/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Math/ByteSize.hpp" #include #include #include #include #include #include #include #include namespace openVulkanoCpp { class IEventHandler; class MultiPartArchiveWriter; } namespace openVulkanoCpp::AR { class ArSession; class ArFrame; enum class RecordingMode { /** * Frames will only be saved when manually requested through ArFrame::Save() */ MANUAL, /** * Frames will only be saved when the frame is manually requested through ArSession::GetFrame() */ FRAME_REQUEST, /** * Every new frame will be stored automatically */ NEW_FRAME }; struct RecordingSettings { RecordingMode recordingMode = RecordingMode::MANUAL; std::filesystem::path path; size_t archiveSize = 2_GiB; bool downsampleColor = false; bool highResFramesInSeparateArchive = true; bool asyncRecording = false; }; class ArRecorder final { struct AsyncProcessor final { ArRecorder* recorder; std::thread processingThread; std::queue> frameQueue, highResFrameQueue; std::mutex queueMutex; std::condition_variable newDataAvailable; std::atomic_bool requestExit{}; explicit AsyncProcessor(ArRecorder* recorder); ~AsyncProcessor(); void Queue(const std::shared_ptr& frame, bool highRes); void Handler(); }; ArSession* m_session; std::unique_ptr m_colorWriter, m_depthWriter, m_confidenceWriter, m_metadataWriter, m_highResWriter; RecordingSettings m_settings; bool m_recording = false, m_persistent = false; IEventHandler* m_newFrameHandler = nullptr; AsyncProcessor m_asyncProcessor; void Write(ArFrame* frame, bool highRes = false); void WriteMetadata(ArFrame* frame, MultiPartArchiveWriter* metaWriter); void WriteColorImage(ArFrame* arFrame, MultiPartArchiveWriter* colorWriter, bool highRes) const; void WriteDepthImage(ArFrame *arFrame, MultiPartArchiveWriter* depthWriter, MultiPartArchiveWriter* confWriter); public: ArRecorder(ArSession* session); ~ArRecorder(); void Save(const std::shared_ptr& frame); void SaveHighResolution(const std::shared_ptr& frame); /** * Starts the recording of the owning AR session */ void Start(); /** * Stops the recording of the owning AR session */ void Stop(); /** * Sets the directory into which the AR recording should be stored. * The path needs to be set to make the recording persistent. * If path is changed after starting the recording, the already running recording will be moved to the new path. * @param path The path to be used to store the recording */ void SetRecordingPath(const std::string& path); /** * Gets the current recording path * @return Current recording dir */ [[nodiscard]] const std::filesystem::path& GetRecordingPath() const { return m_settings.path; } /** * Checks if a path to be used for the recording has been set. * If no path has been set the recording will be stored in a temporary location and will be deleted once the recording is stopped. * @return True if a path has been set and the recording will persist after stopping the recording. */ [[nodiscard]] bool IsPersistent() const { return m_persistent; } /** * Checks if the recording of the AR session is running * @return True if recording is started */ [[nodiscard]] bool IsRecording() const { return m_recording; } /** * Sets the used recording mode * @param mode The mode that should be used to record the current session */ void SetRecordingMode(RecordingMode mode); /** * Checks the currently used recording mode for the AR session * @return The currently used recording mode */ [[nodiscard]] RecordingMode GetRecordingMode() const { return m_settings.recordingMode; } /** * If enabled color images will be reduced to 1/4 of the original resolution (both axes will have half the resolution). * This option can be used to reduce the used storage space and storage bandwidth during recording. * * @param downsample true = downsample images; false = no downsampling */ void SetDownsampleColorImages(bool downsample = true) { m_settings.downsampleColor = downsample; } /** * Checks if color image downsampling is enabled. * @return true = downsample images; false = no downsampling */ bool GetDownsampleColorImages() const { return m_settings.downsampleColor; } /** * If enabled the requested high resolution images will be stored in a separate archive ("highres.tar") instead of the normal ar recording archives. * @param separateArchive true = using the separate archive file; false = using the normal archive files */ void SetHighResFramesInSeparateArchive(bool separateArchive = true) { m_settings.highResFramesInSeparateArchive = separateArchive; } /** * Checks if a separate archive is used for the high res frames. * @return true = using the separate archive file; false = using the normal archive files */ bool GetHighResFramesInSeparateArchive() const { return m_settings.highResFramesInSeparateArchive; } void SetArchivePartMaxFileSize(size_t maxPartSize = 2_GiB) { m_settings.archiveSize = maxPartSize; } size_t GetArchivePartMaxFileSize() const { return m_settings.archiveSize; } const RecordingSettings& GetRecordingSettings() const { return m_settings; } }; }