Write duration and frame count to metadata file
This commit is contained in:
@@ -38,9 +38,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
std::string GetFileName(size_t frameId, std::string_view fileExtension)
|
std::string GetFileName(size_t frameId, std::string_view fileExtension)
|
||||||
{
|
{
|
||||||
std::stringstream fnStream;
|
return fmt::format("{:07d}.{}", frameId, fileExtension);
|
||||||
fnStream << std::setw(7) << std::setfill('0') << frameId << '.' << fileExtension;
|
|
||||||
return fnStream.str();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +50,10 @@ namespace OpenVulkano::AR
|
|||||||
session->OnNewFrameHighResolution += EventHandler(this, &ArRecorder::SaveHighResolution);
|
session->OnNewFrameHighResolution += EventHandler(this, &ArRecorder::SaveHighResolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArRecorder::~ArRecorder() = default;
|
ArRecorder::~ArRecorder()
|
||||||
|
{
|
||||||
|
if (!m_settings.asyncRecording) WriteMetadataFile();
|
||||||
|
}
|
||||||
|
|
||||||
void ArRecorder::WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const
|
void ArRecorder::WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const
|
||||||
{
|
{
|
||||||
@@ -165,6 +166,7 @@ namespace OpenVulkano::AR
|
|||||||
WriteDepthImage(frame,
|
WriteDepthImage(frame,
|
||||||
useHighResWriter ? m_highResWriter.get() : m_depthWriter.get(),
|
useHighResWriter ? m_highResWriter.get() : m_depthWriter.get(),
|
||||||
useHighResWriter ? m_highResWriter.get() : m_confidenceWriter.get());
|
useHighResWriter ? m_highResWriter.get() : m_confidenceWriter.get());
|
||||||
|
m_frameCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArRecorder::Start()
|
void ArRecorder::Start()
|
||||||
@@ -178,23 +180,29 @@ namespace OpenVulkano::AR
|
|||||||
m_metadataWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path.string(), "meta_{:05d}.tar.gz", ArchiveConfig::TAR_GZ, m_settings.archiveSize * 10, true);
|
m_metadataWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path.string(), "meta_{:05d}.tar.gz", ArchiveConfig::TAR_GZ, m_settings.archiveSize * 10, true);
|
||||||
m_highResWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path.string(), "highres_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true);
|
m_highResWriter = std::make_unique<MultiPartArchiveWriter>(m_settings.path.string(), "highres_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true);
|
||||||
|
|
||||||
std::ofstream platformInfoStream(m_settings.path / ArSessionMetadata::RECORDING_METADATA_FILENAME);
|
WriteMetadataFile();
|
||||||
platformInfoStream << m_session->GetSessionMetadata().ToYaml();
|
|
||||||
platformInfoStream.close();
|
|
||||||
}
|
}
|
||||||
m_recording = true;
|
m_recording = true;
|
||||||
OnRecordingStateChanged(this, m_recording);
|
OnRecordingStateChanged(this, m_recording);
|
||||||
|
m_timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArRecorder::SplitWriters()
|
||||||
|
{
|
||||||
|
for(MultiPartArchiveWriter* writer : { m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get(), m_highResWriter.get() })
|
||||||
|
{
|
||||||
|
writer->Split();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArRecorder::Stop()
|
void ArRecorder::Stop()
|
||||||
{
|
{
|
||||||
if (!m_recording) return;
|
if (!m_recording) return;
|
||||||
m_recording = false;
|
m_recording = false;
|
||||||
for(MultiPartArchiveWriter* writer : { m_colorWriter.get(), m_depthWriter.get(), m_confidenceWriter.get(), m_metadataWriter.get(), m_highResWriter.get() })
|
|
||||||
{
|
|
||||||
writer->Split();
|
|
||||||
}
|
|
||||||
OnRecordingStateChanged(this, m_recording);
|
OnRecordingStateChanged(this, m_recording);
|
||||||
|
if (!m_settings.asyncRecording) SplitWriters();
|
||||||
|
m_timer.Tick();
|
||||||
|
m_timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArRecorder::SetRecordingPath(const std::filesystem::path& path)
|
void ArRecorder::SetRecordingPath(const std::filesystem::path& path)
|
||||||
@@ -256,6 +264,17 @@ namespace OpenVulkano::AR
|
|||||||
WriteColorImage(frame.get(), nullptr, &path, !downsample);
|
WriteColorImage(frame.get(), nullptr, &path, !downsample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ArRecorder::WriteMetadataFile()
|
||||||
|
{
|
||||||
|
m_timer.Tick();
|
||||||
|
m_session->GetSessionMetadata().recFrameCount = m_frameCount;
|
||||||
|
m_session->GetSessionMetadata().recSkippedFrames = m_skippedFrames;
|
||||||
|
m_session->GetSessionMetadata().recDuration = static_cast<int32_t>(m_timer.GetTotalSeconds());
|
||||||
|
std::ofstream platformInfoStream(m_settings.path / ArSessionMetadata::RECORDING_METADATA_FILENAME);
|
||||||
|
platformInfoStream << m_session->GetSessionMetadata().ToYaml();
|
||||||
|
platformInfoStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
//region AsyncProcessor
|
//region AsyncProcessor
|
||||||
ArRecorder::AsyncProcessor::AsyncProcessor(ArRecorder* recorder)
|
ArRecorder::AsyncProcessor::AsyncProcessor(ArRecorder* recorder)
|
||||||
: recorder(recorder), processingThread(&ArRecorder::AsyncProcessor::Handler, this)
|
: recorder(recorder), processingThread(&ArRecorder::AsyncProcessor::Handler, this)
|
||||||
@@ -270,7 +289,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
void ArRecorder::AsyncProcessor::Queue(const std::shared_ptr<ArFrame>& frame, bool highRes)
|
void ArRecorder::AsyncProcessor::Queue(const std::shared_ptr<ArFrame>& frame, bool highRes)
|
||||||
{
|
{
|
||||||
if (requestExit) return; // no need to queue up on shutdown
|
if (requestExit || !recorder->m_recording) return; // no need to queue up on shutdown
|
||||||
{
|
{
|
||||||
std::unique_lock lock(queueMutex);
|
std::unique_lock lock(queueMutex);
|
||||||
if (highRes) highResFrameQueue.push(frame);
|
if (highRes) highResFrameQueue.push(frame);
|
||||||
@@ -302,6 +321,7 @@ namespace OpenVulkano::AR
|
|||||||
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++;
|
||||||
//while(frameQueue.size() > 3) frameQueue.pop();
|
//while(frameQueue.size() > 3) frameQueue.pop();
|
||||||
}
|
}
|
||||||
auto frame = std::move(frameQueue.front());
|
auto frame = std::move(frameQueue.front());
|
||||||
@@ -311,8 +331,10 @@ namespace OpenVulkano::AR
|
|||||||
recorder->Write(frame.get(), false);
|
recorder->Write(frame.get(), false);
|
||||||
lock.lock();
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
if (!recorder->m_recording) recorder->SplitWriters();
|
||||||
}
|
}
|
||||||
while (!requestExit);
|
while (!requestExit);
|
||||||
|
recorder->WriteMetadataFile();
|
||||||
}
|
}
|
||||||
//endregion
|
//endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "Math/ByteSize.hpp"
|
#include "Math/ByteSize.hpp"
|
||||||
#include "Base/Event.hpp"
|
#include "Base/Event.hpp"
|
||||||
|
#include "Base/Timer.hpp"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
@@ -75,7 +76,10 @@ namespace OpenVulkano::AR
|
|||||||
ArSession* m_session;
|
ArSession* m_session;
|
||||||
std::unique_ptr<MultiPartArchiveWriter> m_colorWriter, m_depthWriter, m_confidenceWriter, m_metadataWriter, m_highResWriter;
|
std::unique_ptr<MultiPartArchiveWriter> m_colorWriter, m_depthWriter, m_confidenceWriter, m_metadataWriter, m_highResWriter;
|
||||||
RecordingSettings m_settings;
|
RecordingSettings m_settings;
|
||||||
|
uint64_t m_frameCount = 0;
|
||||||
|
uint32_t m_skippedFrames = 0;
|
||||||
bool m_recording = false, m_persistent = false;
|
bool m_recording = false, m_persistent = false;
|
||||||
|
Timer m_timer;
|
||||||
|
|
||||||
IEventHandler* m_newFrameHandler = nullptr;
|
IEventHandler* m_newFrameHandler = nullptr;
|
||||||
|
|
||||||
@@ -86,6 +90,9 @@ namespace OpenVulkano::AR
|
|||||||
void WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
|
void WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, const std::filesystem::path* path, bool highRes) const;
|
||||||
void WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter);
|
void WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter);
|
||||||
|
|
||||||
|
void SplitWriters();
|
||||||
|
void WriteMetadataFile();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ArRecorder(ArSession* session);
|
ArRecorder(ArSession* session);
|
||||||
|
|
||||||
|
|||||||
@@ -238,6 +238,8 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
[[nodiscard]] const ArSessionMetadata& GetSessionMetadata() const { return metadata; }
|
[[nodiscard]] const ArSessionMetadata& GetSessionMetadata() const { return metadata; }
|
||||||
|
|
||||||
|
[[nodiscard]] ArSessionMetadata& GetSessionMetadata() { return metadata; }
|
||||||
|
|
||||||
void SetShouldAttemptRelocalization(bool attemptReloc) { shouldAttemptRelocalization = attemptReloc; }
|
void SetShouldAttemptRelocalization(bool attemptReloc) { shouldAttemptRelocalization = attemptReloc; }
|
||||||
|
|
||||||
Event<> OnNewFrameAvailable;
|
Event<> OnNewFrameAvailable;
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ namespace OpenVulkano::AR
|
|||||||
|
|
||||||
std::string ArSessionMetadata::FinishedRecordingInfoToYaml() const
|
std::string ArSessionMetadata::FinishedRecordingInfoToYaml() const
|
||||||
{
|
{
|
||||||
if (recFrameCount < 1 || recDuration < 1 || recSkippedFrames < 1) return "";
|
if (recFrameCount < 1 && recDuration < 1 && recSkippedFrames < 1) return "";
|
||||||
return fmt::format(R"(Recording:
|
return fmt::format(R"(Recording:
|
||||||
Duration: {}
|
Duration: {}
|
||||||
FrameCount: {}
|
FrameCount: {}
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ namespace OpenVulkano::AR::ArKit
|
|||||||
[m_arSession release];
|
[m_arSession release];
|
||||||
[m_arConfig release];
|
[m_arConfig release];
|
||||||
[m_arKitDelegate release];
|
[m_arKitDelegate release];
|
||||||
|
Logger::AR->info("Released AR session");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArSessionArKitInternal::SetRenderer(IRenderer* renderer)
|
void ArSessionArKitInternal::SetRenderer(IRenderer* renderer)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ namespace OpenVulkano::AR::Playback
|
|||||||
metadata.recDuration, metadata.recFrameCount, metadata.recSkippedFrames);
|
metadata.recDuration, metadata.recFrameCount, metadata.recSkippedFrames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger::AR->info("Starting AR Playback '{}'{}", metadata.type.GetHumanReadableName(), recordingPath, playbackInfo);
|
Logger::AR->info("Starting {} playback '{}'{}", metadata.type.GetHumanReadableName(), recordingPath, playbackInfo);
|
||||||
std::this_thread::sleep_for(128ms); // Delay startup of playback
|
std::this_thread::sleep_for(128ms); // Delay startup of playback
|
||||||
while (playbackReader.HasNext() && IsRunning())
|
while (playbackReader.HasNext() && IsRunning())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user