diff --git a/openVulkanoCpp/AR/ArRecorder.cpp b/openVulkanoCpp/AR/ArRecorder.cpp index f0fe6b8..1b84b1d 100644 --- a/openVulkanoCpp/AR/ArRecorder.cpp +++ b/openVulkanoCpp/AR/ArRecorder.cpp @@ -38,9 +38,7 @@ namespace OpenVulkano::AR std::string GetFileName(size_t frameId, std::string_view fileExtension) { - std::stringstream fnStream; - fnStream << std::setw(7) << std::setfill('0') << frameId << '.' << fileExtension; - return fnStream.str(); + return fmt::format("{:07d}.{}", frameId, fileExtension); } } @@ -52,7 +50,10 @@ namespace OpenVulkano::AR 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 { @@ -165,6 +166,7 @@ namespace OpenVulkano::AR WriteDepthImage(frame, useHighResWriter ? m_highResWriter.get() : m_depthWriter.get(), useHighResWriter ? m_highResWriter.get() : m_confidenceWriter.get()); + m_frameCount++; } void ArRecorder::Start() @@ -178,23 +180,29 @@ namespace OpenVulkano::AR m_metadataWriter = std::make_unique(m_settings.path.string(), "meta_{:05d}.tar.gz", ArchiveConfig::TAR_GZ, m_settings.archiveSize * 10, true); m_highResWriter = std::make_unique(m_settings.path.string(), "highres_{:05d}.tar", ArchiveConfig::TAR, m_settings.archiveSize, true); - std::ofstream platformInfoStream(m_settings.path / ArSessionMetadata::RECORDING_METADATA_FILENAME); - platformInfoStream << m_session->GetSessionMetadata().ToYaml(); - platformInfoStream.close(); + WriteMetadataFile(); } m_recording = true; 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() { if (!m_recording) return; 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); + if (!m_settings.asyncRecording) SplitWriters(); + m_timer.Tick(); + m_timer.Start(); } void ArRecorder::SetRecordingPath(const std::filesystem::path& path) @@ -256,6 +264,17 @@ namespace OpenVulkano::AR 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(m_timer.GetTotalSeconds()); + std::ofstream platformInfoStream(m_settings.path / ArSessionMetadata::RECORDING_METADATA_FILENAME); + platformInfoStream << m_session->GetSessionMetadata().ToYaml(); + platformInfoStream.close(); + } + //region AsyncProcessor ArRecorder::AsyncProcessor::AsyncProcessor(ArRecorder* recorder) : recorder(recorder), processingThread(&ArRecorder::AsyncProcessor::Handler, this) @@ -270,7 +289,7 @@ namespace OpenVulkano::AR void ArRecorder::AsyncProcessor::Queue(const std::shared_ptr& 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); if (highRes) highResFrameQueue.push(frame); @@ -302,6 +321,7 @@ namespace OpenVulkano::AR if (frameQueue.size() > 3) { Logger::AR->warn("Falling behind saving frames, skipping ..."); + recorder->m_skippedFrames++; //while(frameQueue.size() > 3) frameQueue.pop(); } auto frame = std::move(frameQueue.front()); @@ -311,8 +331,10 @@ namespace OpenVulkano::AR recorder->Write(frame.get(), false); lock.lock(); } + if (!recorder->m_recording) recorder->SplitWriters(); } while (!requestExit); + recorder->WriteMetadataFile(); } //endregion } diff --git a/openVulkanoCpp/AR/ArRecorder.hpp b/openVulkanoCpp/AR/ArRecorder.hpp index 72723c8..0ab772c 100644 --- a/openVulkanoCpp/AR/ArRecorder.hpp +++ b/openVulkanoCpp/AR/ArRecorder.hpp @@ -8,6 +8,7 @@ #include "Math/ByteSize.hpp" #include "Base/Event.hpp" +#include "Base/Timer.hpp" #include #include #include @@ -75,7 +76,10 @@ namespace OpenVulkano::AR ArSession* m_session; std::unique_ptr m_colorWriter, m_depthWriter, m_confidenceWriter, m_metadataWriter, m_highResWriter; RecordingSettings m_settings; + uint64_t m_frameCount = 0; + uint32_t m_skippedFrames = 0; bool m_recording = false, m_persistent = false; + Timer m_timer; 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 WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter); + void SplitWriters(); + void WriteMetadataFile(); + public: ArRecorder(ArSession* session); diff --git a/openVulkanoCpp/AR/ArSession.hpp b/openVulkanoCpp/AR/ArSession.hpp index 74f4a23..cb215ff 100644 --- a/openVulkanoCpp/AR/ArSession.hpp +++ b/openVulkanoCpp/AR/ArSession.hpp @@ -238,6 +238,8 @@ namespace OpenVulkano::AR [[nodiscard]] const ArSessionMetadata& GetSessionMetadata() const { return metadata; } + [[nodiscard]] ArSessionMetadata& GetSessionMetadata() { return metadata; } + void SetShouldAttemptRelocalization(bool attemptReloc) { shouldAttemptRelocalization = attemptReloc; } Event<> OnNewFrameAvailable; diff --git a/openVulkanoCpp/AR/ArSessionMetadata.cpp b/openVulkanoCpp/AR/ArSessionMetadata.cpp index 5ccac67..19673ca 100644 --- a/openVulkanoCpp/AR/ArSessionMetadata.cpp +++ b/openVulkanoCpp/AR/ArSessionMetadata.cpp @@ -125,7 +125,7 @@ namespace OpenVulkano::AR 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: Duration: {} FrameCount: {} diff --git a/openVulkanoCpp/AR/Provider/ArKit/ArSessionArKitInternal.mm b/openVulkanoCpp/AR/Provider/ArKit/ArSessionArKitInternal.mm index 08f5a10..c255852 100644 --- a/openVulkanoCpp/AR/Provider/ArKit/ArSessionArKitInternal.mm +++ b/openVulkanoCpp/AR/Provider/ArKit/ArSessionArKitInternal.mm @@ -107,6 +107,7 @@ namespace OpenVulkano::AR::ArKit [m_arSession release]; [m_arConfig release]; [m_arKitDelegate release]; + Logger::AR->info("Released AR session"); } void ArSessionArKitInternal::SetRenderer(IRenderer* renderer) diff --git a/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp b/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp index 7a109fb..a28937c 100644 --- a/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp +++ b/openVulkanoCpp/AR/Provider/Playback/ArSessionPlayback.cpp @@ -74,7 +74,7 @@ namespace OpenVulkano::AR::Playback 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 while (playbackReader.HasNext() && IsRunning()) {