Add async frame recording
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "IO/Files/Pnm.hpp"
|
||||
#include "IO/AppFolders.hpp"
|
||||
#include "Base/BlockProfiler.hpp"
|
||||
#include "Base/Logger.hpp"
|
||||
#include "Image/YuvUtils.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
@@ -42,7 +43,7 @@ namespace openVulkanoCpp::AR
|
||||
}
|
||||
|
||||
ArRecorder::ArRecorder(ArSession* session)
|
||||
: m_session(session)
|
||||
: m_session(session), m_asyncProcessor(this)
|
||||
{
|
||||
m_settings.path = GeneratePath(AppFolders::GetAppDataHomeDir(), "ar_recording");
|
||||
session->OnNewFrameHighResolution += EventHandler(this, &ArRecorder::SaveHighResolution);
|
||||
@@ -216,7 +217,7 @@ namespace openVulkanoCpp::AR
|
||||
if (!m_recording) return;
|
||||
if (m_settings.asyncRecording)
|
||||
{
|
||||
|
||||
m_asyncProcessor.Queue(frame, false);
|
||||
}
|
||||
else Write(frame.get());
|
||||
}
|
||||
@@ -226,8 +227,68 @@ namespace openVulkanoCpp::AR
|
||||
if (!m_recording) return;
|
||||
if (m_settings.asyncRecording)
|
||||
{
|
||||
|
||||
m_asyncProcessor.Queue(frame, true);
|
||||
}
|
||||
else Write(frame.get(), true);
|
||||
}
|
||||
|
||||
//region AsyncProcessor
|
||||
ArRecorder::AsyncProcessor::AsyncProcessor(ArRecorder* recorder)
|
||||
: recorder(recorder), processingThread(&ArRecorder::AsyncProcessor::Handler, this)
|
||||
{}
|
||||
|
||||
ArRecorder::AsyncProcessor::~AsyncProcessor()
|
||||
{
|
||||
requestExit = true;
|
||||
queueMutex.lock();
|
||||
newDataAvailable.notify_one();
|
||||
if (processingThread.joinable()) processingThread.join();
|
||||
}
|
||||
|
||||
void ArRecorder::AsyncProcessor::Queue(const std::shared_ptr<ArFrame>& frame, bool highRes)
|
||||
{
|
||||
if (requestExit) return; // no need to queue up on shutdown
|
||||
{
|
||||
std::unique_lock lock(queueMutex);
|
||||
if (highRes) highResFrameQueue.push(frame);
|
||||
else frameQueue.push(frame);
|
||||
}
|
||||
newDataAvailable.notify_all();
|
||||
}
|
||||
|
||||
void ArRecorder::AsyncProcessor::Handler()
|
||||
{
|
||||
Utils::SetThreadName("ArRecorder");
|
||||
std::unique_lock lock(queueMutex);
|
||||
do
|
||||
{
|
||||
newDataAvailable.wait(lock, [this]{ return !frameQueue.empty() || !highResFrameQueue.empty() || requestExit; });
|
||||
while(!highResFrameQueue.empty())
|
||||
{
|
||||
auto frame = std::move(highResFrameQueue.front());
|
||||
highResFrameQueue.pop();
|
||||
if (frame->IsSaved()) continue;
|
||||
lock.unlock();
|
||||
recorder->Write(frame.get(), true);
|
||||
lock.lock();
|
||||
}
|
||||
if (requestExit) break;
|
||||
while(!frameQueue.empty())
|
||||
{
|
||||
if (frameQueue.size() > 3)
|
||||
{
|
||||
Logger::AR->warn("Falling behind saving frames, skipping ...");
|
||||
//while(frameQueue.size() > 3) frameQueue.pop();
|
||||
}
|
||||
auto frame = std::move(frameQueue.front());
|
||||
frameQueue.pop();
|
||||
if (frame->IsSaved()) continue;
|
||||
lock.unlock();
|
||||
recorder->Write(frame.get(), false);
|
||||
lock.lock();
|
||||
}
|
||||
}
|
||||
while (!requestExit);
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user