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());
|
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()
|
const Scene::Texture* ArFrame::GetImageTexture()
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
void Save();
|
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; }
|
void SetSaved() { m_saved = true; }
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace OpenVulkano::AR
|
|||||||
else m_asyncProcessor.Close();
|
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");
|
//BlockProfiler profile("Save AR Frame - Image");
|
||||||
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
|
std::string fileName = GetFileName(arFrame->GetFrameId(), "jpg");
|
||||||
@@ -141,10 +141,10 @@ namespace OpenVulkano::AR
|
|||||||
#endif
|
#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");
|
//BlockProfiler profile("Save AR Frame - Depth");
|
||||||
if (!m_depthWriter || !m_confidenceWriter) return;
|
if (!depthWriter || !confWriter) return;
|
||||||
auto depthImg = arFrame->GetDepthImage();
|
auto depthImg = arFrame->GetDepthImage();
|
||||||
std::vector<std::pair<const void*, size_t>> buffers(2);
|
std::vector<std::pair<const void*, size_t>> buffers(2);
|
||||||
{ // TODO handle alternative depth formats!!!!
|
{ // 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");
|
//BlockProfiler profileMeta("Save AR Frame - Meta");
|
||||||
std::string metaContent = frame->GetFrameMetadata().ToYaml();
|
std::string metaContent = frame->GetFrameMetadata().ToYaml();
|
||||||
@@ -287,9 +287,23 @@ namespace OpenVulkano::AR
|
|||||||
else Write(frame.get(), true);
|
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);
|
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()
|
void ArRecorder::WriteMetadataFile()
|
||||||
@@ -334,6 +348,16 @@ namespace OpenVulkano::AR
|
|||||||
}
|
}
|
||||||
newDataAvailable.notify_all();
|
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()
|
void ArRecorder::AsyncProcessor::Handler()
|
||||||
{
|
{
|
||||||
@@ -342,7 +366,16 @@ namespace OpenVulkano::AR
|
|||||||
std::unique_lock lock(queueMutex);
|
std::unique_lock lock(queueMutex);
|
||||||
do
|
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())
|
while(!highResFrameQueue.empty())
|
||||||
{
|
{
|
||||||
auto frame = std::move(highResFrameQueue.front());
|
auto frame = std::move(highResFrameQueue.front());
|
||||||
@@ -353,12 +386,13 @@ namespace OpenVulkano::AR
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
if (requestExit) break;
|
if (requestExit) break;
|
||||||
while(!frameQueue.empty())
|
if(!frameQueue.empty())
|
||||||
{
|
{
|
||||||
if (frameQueue.size() > 3)
|
if (frameQueue.size() > 3)
|
||||||
{
|
{
|
||||||
Logger::AR->warn("Falling behind saving frames, skipping ...");
|
Logger::AR->warn("Falling behind saving frames, skipping ...");
|
||||||
recorder->m_skippedFrames++;
|
recorder->m_skippedFrames++;
|
||||||
|
frameQueue.pop();
|
||||||
//while(frameQueue.size() > 3) frameQueue.pop();
|
//while(frameQueue.size() > 3) frameQueue.pop();
|
||||||
}
|
}
|
||||||
auto frame = std::move(frameQueue.front());
|
auto frame = std::move(frameQueue.front());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Math/ByteSize.hpp"
|
#include "Math/ByteSize.hpp"
|
||||||
#include "Base/Event.hpp"
|
#include "Base/Event.hpp"
|
||||||
#include "Base/Timer.hpp"
|
#include "Base/Timer.hpp"
|
||||||
|
#include "Base/Wrapper.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
namespace OpenVulkano
|
namespace OpenVulkano
|
||||||
{
|
{
|
||||||
class IEventHandler;
|
class IEventHandler;
|
||||||
|
class IArchiveWriter;
|
||||||
class MultiPartArchiveWriter;
|
class MultiPartArchiveWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,11 +60,19 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
class ArRecorder final
|
class ArRecorder final
|
||||||
{
|
{
|
||||||
|
struct SaveToFileRequest final
|
||||||
|
{
|
||||||
|
Ptr<ArFrame> frame;
|
||||||
|
std::filesystem::path path;
|
||||||
|
bool downsample, addAux;
|
||||||
|
};
|
||||||
|
|
||||||
struct AsyncProcessor final
|
struct AsyncProcessor final
|
||||||
{
|
{
|
||||||
ArRecorder* recorder;
|
ArRecorder* recorder;
|
||||||
std::thread processingThread;
|
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::mutex queueMutex;
|
||||||
std::condition_variable newDataAvailable;
|
std::condition_variable newDataAvailable;
|
||||||
std::atomic_bool requestExit{};
|
std::atomic_bool requestExit{};
|
||||||
@@ -70,8 +80,10 @@ namespace OpenVulkano::AR
|
|||||||
explicit AsyncProcessor(ArRecorder* recorder);
|
explicit AsyncProcessor(ArRecorder* recorder);
|
||||||
~AsyncProcessor();
|
~AsyncProcessor();
|
||||||
void Close();
|
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();
|
void Handler();
|
||||||
|
bool Empty() { return frameQueue.empty() && highResFrameQueue.empty() && toFile.empty(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
ArSession* m_session;
|
ArSession* m_session;
|
||||||
@@ -87,9 +99,10 @@ namespace OpenVulkano::AR
|
|||||||
AsyncProcessor m_asyncProcessor;
|
AsyncProcessor m_asyncProcessor;
|
||||||
|
|
||||||
void Write(ArFrame* frame, bool highRes = false);
|
void Write(ArFrame* frame, bool highRes = false);
|
||||||
void WriteMetadata(ArFrame* frame, MultiPartArchiveWriter* metaWriter);
|
void WriteMetadata(ArFrame* frame, IArchiveWriter* metaWriter);
|
||||||
void WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
|
void WriteColorImage(ArFrame* arFrame, IArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
|
||||||
void WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter);
|
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 SplitWriters();
|
||||||
void WriteMetadataFile();
|
void WriteMetadataFile();
|
||||||
@@ -103,7 +116,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
void SaveHighResolution(const std::shared_ptr<ArFrame>& frame);
|
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
|
* Starts the recording of the owning AR session
|
||||||
|
|||||||
Reference in New Issue
Block a user