/* * 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/. */ #include "ArSessionPlayback.hpp" #include "ArFramePlayback.hpp" #include "Base/Logger.hpp" #include namespace OpenVulkano::AR::Playback { ArSessionPlayback::ArSessionPlayback(const std::string& recordingPath, bool autoAdvance) : ArSession(ArSessionMetadata(recordingPath)), recordingPath(recordingPath), autoAdvance(autoAdvance), playbackReader(recordingPath) { capabilities = ArSessionCapabilities(metadata.type, ArSessionType::PLAYBACK, false, metadata.depthFormat != ArDepthFormat::UNAVAILABLE); constants = { Math::Matrix4f(1), metadata.confidenceRange }; m_playbackReaderThread = std::thread([this](){ReadWorker();}); } ArSessionPlayback::~ArSessionPlayback() { Stop(); if (m_playbackReaderThread.joinable()) m_playbackReaderThread.join(); } void ArSessionPlayback::Start() { running = true; m_frameConsumed = true; } void ArSessionPlayback::Stop() { running = false; OnStopped(); } void ArSessionPlayback::Pause() { running = false; } std::shared_ptr ArSessionPlayback::GetFrame() { while(IsRunning() && m_frameConsumed) { std::this_thread::yield(); } auto frame = m_nextFrame; m_nextFrame = nullptr; m_frameConsumed = true; return frame; } ArType ArSessionPlayback::GetArType() { return capabilities.GetArType(); } void ArSessionPlayback::ReadWorker() { while (playbackReader.HasNext() && IsRunning()) { while (!m_frameConsumed) { std::this_thread::yield(); } try { std::shared_ptr frame = std::make_shared(shared_from_this(), playbackReader); lastTimestamp = frame->GetTimestamp(); m_nextFrame = frame; m_frameConsumed = false; //TODO try to keep original frame timing // Trigger events OnNewFrameAvailable(); OnNewFrame(frame); OnNewCameraTransformation(frame->GetCameraTransformation()); if (OnNewCameraViewMatrix.HasHandlers()) { auto view = frame->GetCameraViewForCurrentDeviceOrientation(); OnNewCameraViewMatrix(view); } } catch (const std::exception& e) { Logger::AR->error("Failed to read AR frame: {}", e.what()); } } Stop(); OnSessionInterruptionChange(true); } }