#include "RenderOutputQueue.h" RenderOutputQueue::RenderOutputQueue(const VideoPlayoutPolicy& policy) : mPolicy(NormalizeVideoPlayoutPolicy(policy)) { } void RenderOutputQueue::Configure(const VideoPlayoutPolicy& policy) { std::lock_guard lock(mMutex); mPolicy = NormalizeVideoPlayoutPolicy(policy); while (mReadyFrames.size() > CapacityLocked()) { ReleaseFrame(mReadyFrames.front()); mReadyFrames.pop_front(); ++mDroppedCount; } } bool RenderOutputQueue::Push(RenderOutputFrame frame) { std::lock_guard lock(mMutex); if (mReadyFrames.size() >= CapacityLocked()) { ReleaseFrame(mReadyFrames.front()); mReadyFrames.pop_front(); ++mDroppedCount; } mReadyFrames.push_back(frame); ++mPushedCount; return true; } bool RenderOutputQueue::TryPop(RenderOutputFrame& frame) { std::lock_guard lock(mMutex); if (mReadyFrames.empty()) { ++mUnderrunCount; return false; } frame = mReadyFrames.front(); mReadyFrames.pop_front(); ++mPoppedCount; return true; } bool RenderOutputQueue::DropOldestFrame() { std::lock_guard lock(mMutex); if (mReadyFrames.empty()) return false; ReleaseFrame(mReadyFrames.front()); mReadyFrames.pop_front(); ++mDroppedCount; return true; } void RenderOutputQueue::Clear() { std::lock_guard lock(mMutex); for (RenderOutputFrame& frame : mReadyFrames) ReleaseFrame(frame); mReadyFrames.clear(); } RenderOutputQueueMetrics RenderOutputQueue::GetMetrics() const { std::lock_guard lock(mMutex); RenderOutputQueueMetrics metrics; metrics.depth = mReadyFrames.size(); metrics.capacity = CapacityLocked(); metrics.pushedCount = mPushedCount; metrics.poppedCount = mPoppedCount; metrics.droppedCount = mDroppedCount; metrics.underrunCount = mUnderrunCount; return metrics; } std::size_t RenderOutputQueue::CapacityLocked() const { return static_cast(mPolicy.maxReadyFrames); } void RenderOutputQueue::ReleaseFrame(RenderOutputFrame& frame) { if (frame.releaseFrame) frame.releaseFrame(frame.frame); frame.releaseFrame = {}; }