Use async save for SaveToFile and add option to include all ar metadata

This commit is contained in:
Georg Hagen
2025-05-19 15:53:04 +02:00
parent 369528c170
commit 31bd94f939
4 changed files with 63 additions and 16 deletions

View File

@@ -25,9 +25,9 @@ namespace OpenVulkano::AR
m_session->GetRecorder().Save(shared_from_this());
}
void ArFrame::SaveToFile(const std::filesystem::path& path, bool downsample)
void ArFrame::SaveToFile(const std::filesystem::path& path, bool downsample, bool includeAux)
{
m_session->GetRecorder().SaveToFile(shared_from_this(), path, downsample);
m_session->GetRecorder().SaveToFile(shared_from_this(), path, downsample, includeAux);
}
const Scene::Texture* ArFrame::GetImageTexture()

View File

@@ -182,7 +182,7 @@ namespace OpenVulkano::AR
void Save();
void SaveToFile(const std::filesystem::path& path, bool downsample = false);
void SaveToFile(const std::filesystem::path& path, bool downsample = false, bool includeAux = true);
void SetSaved() { m_saved = true; }

View File

@@ -60,7 +60,7 @@ namespace OpenVulkano::AR
else m_asyncProcessor.Close();
}
void ArRecorder::WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const
void ArRecorder::WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const
{
//BlockProfiler profile("Save AR Frame - Image");
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
@@ -141,10 +141,10 @@ namespace OpenVulkano::AR
#endif
}
void ArRecorder::WriteDepthImage(ArFrame* arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter)
void ArRecorder::WriteDepthImage(ArFrame* arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter)
{
//BlockProfiler profile("Save AR Frame - Depth");
if (!m_depthWriter || !m_confidenceWriter) return;
if (!depthWriter || !confWriter) return;
auto depthImg = arFrame->GetDepthImage();
std::vector<std::pair<const void*, size_t>> buffers(2);
{ // TODO handle alternative depth formats!!!!
@@ -175,7 +175,7 @@ namespace OpenVulkano::AR
}
}
void ArRecorder::WriteMetadata(ArFrame* frame, MultiPartArchiveWriter* metaWriter)
void ArRecorder::WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter)
{
//BlockProfiler profileMeta("Save AR Frame - Meta");
std::string metaContent = frame->GetFrameMetadata().ToYaml();
@@ -287,9 +287,23 @@ namespace OpenVulkano::AR
else Write(frame.get(), true);
}
void ArRecorder::SaveToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample)
void ArRecorder::SaveToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool includeAux)
{
if (m_settings.asyncRecording) m_asyncProcessor.Queue(frame, path, downsample, includeAux);
else WriteToFile(frame, path, downsample, includeAux);
}
void ArRecorder::WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool includeAux)
{
WriteColorImage(frame.get(), nullptr, &path, !downsample);
if (includeAux)
{
auto fName = path.string();
fName.replace(fName.size() - 3, 3, "aux");
ArchiveWriter writer(fName);
WriteMetadata(frame.get(), &writer);
WriteDepthImage(frame.get(), &writer, &writer);
}
}
void ArRecorder::WriteMetadataFile()
@@ -335,6 +349,16 @@ namespace OpenVulkano::AR
newDataAvailable.notify_all();
}
void ArRecorder::AsyncProcessor::Queue(const Ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool aux)
{
if (requestExit) return;
{
std::unique_lock lock(queueMutex);
toFile.emplace(frame, path, downsample, aux);
}
newDataAvailable.notify_all();
}
void ArRecorder::AsyncProcessor::Handler()
{
Utils::SetThreadName("ArRecorder");
@@ -342,7 +366,16 @@ namespace OpenVulkano::AR
std::unique_lock lock(queueMutex);
do
{
newDataAvailable.wait(lock, [this]{ return !frameQueue.empty() || !highResFrameQueue.empty() || requestExit; });
if (Empty()) newDataAvailable.wait(lock, [this]{ return !Empty() || requestExit; });
while(!toFile.empty())
{
auto request = std::move(toFile.front());
toFile.pop();
if (!request.frame) continue;
lock.unlock();
recorder->WriteToFile(request.frame, request.path, request.downsample, request.addAux);
lock.lock();
}
while(!highResFrameQueue.empty())
{
auto frame = std::move(highResFrameQueue.front());
@@ -353,12 +386,13 @@ namespace OpenVulkano::AR
lock.lock();
}
if (requestExit) break;
while(!frameQueue.empty())
if(!frameQueue.empty())
{
if (frameQueue.size() > 3)
{
Logger::AR->warn("Falling behind saving frames, skipping ...");
recorder->m_skippedFrames++;
frameQueue.pop();
//while(frameQueue.size() > 3) frameQueue.pop();
}
auto frame = std::move(frameQueue.front());

View File

@@ -9,6 +9,7 @@
#include "Math/ByteSize.hpp"
#include "Base/Event.hpp"
#include "Base/Timer.hpp"
#include "Base/Wrapper.hpp"
#include <atomic>
#include <condition_variable>
#include <filesystem>
@@ -21,6 +22,7 @@
namespace OpenVulkano
{
class IEventHandler;
class IArchiveWriter;
class MultiPartArchiveWriter;
}
@@ -58,11 +60,19 @@ namespace OpenVulkano::AR
class ArRecorder final
{
struct SaveToFileRequest final
{
Ptr<ArFrame> frame;
std::filesystem::path path;
bool downsample, addAux;
};
struct AsyncProcessor final
{
ArRecorder* recorder;
std::thread processingThread;
std::queue<std::shared_ptr<ArFrame>> frameQueue, highResFrameQueue;
std::queue<Ptr<ArFrame>> frameQueue, highResFrameQueue;
std::queue<SaveToFileRequest> toFile;
std::mutex queueMutex;
std::condition_variable newDataAvailable;
std::atomic_bool requestExit{};
@@ -70,8 +80,10 @@ namespace OpenVulkano::AR
explicit AsyncProcessor(ArRecorder* recorder);
~AsyncProcessor();
void Close();
void Queue(const std::shared_ptr<ArFrame>& frame, bool highRes);
void Queue(const Ptr<ArFrame>& frame, bool highRes);
void Queue(const Ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool aux);
void Handler();
bool Empty() { return frameQueue.empty() && highResFrameQueue.empty() && toFile.empty(); }
};
ArSession* m_session;
@@ -87,9 +99,10 @@ namespace OpenVulkano::AR
AsyncProcessor m_asyncProcessor;
void Write(ArFrame* frame, bool highRes = false);
void WriteMetadata(ArFrame* frame, MultiPartArchiveWriter* metaWriter);
void WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
void WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter);
void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter);
void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
void WriteDepthImage(ArFrame *arFrame, IArchiveWriter* depthWriter, IArchiveWriter* confWriter);
void WriteToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample, bool saveAux);
void SplitWriters();
void WriteMetadataFile();
@@ -103,7 +116,7 @@ namespace OpenVulkano::AR
void SaveHighResolution(const std::shared_ptr<ArFrame>& frame);
void SaveToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample = false);
void SaveToFile(const std::shared_ptr<ArFrame>& frame, const std::filesystem::path& path, bool downsample = false, bool saveAux = true);
/**
* Starts the recording of the owning AR session