Use async save for SaveToFile and add option to include all ar metadata
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user