#pragma once #include "VideoIOTypes.h" #include #include #include #include #include enum class OutputFrameSlotState { Free, Rendering, Completed, Scheduled }; struct SystemOutputFramePoolConfig { unsigned width = 0; unsigned height = 0; VideoIOPixelFormat pixelFormat = VideoIOPixelFormat::Bgra8; unsigned rowBytes = 0; std::size_t capacity = 0; }; struct OutputFrameSlot { VideoIOOutputFrame frame; std::size_t index = 0; uint64_t generation = 0; }; struct SystemOutputFramePoolMetrics { std::size_t capacity = 0; std::size_t freeCount = 0; std::size_t renderingCount = 0; std::size_t completedCount = 0; std::size_t scheduledCount = 0; std::size_t acquiredCount = 0; std::size_t readyCount = 0; std::size_t consumedCount = 0; uint64_t acquireMissCount = 0; uint64_t readyUnderrunCount = 0; }; class SystemOutputFramePool { public: SystemOutputFramePool() = default; explicit SystemOutputFramePool(const SystemOutputFramePoolConfig& config); void Configure(const SystemOutputFramePoolConfig& config); SystemOutputFramePoolConfig Config() const; bool AcquireFreeSlot(OutputFrameSlot& slot); bool AcquireRenderingSlot(OutputFrameSlot& slot); bool PublishReadySlot(const OutputFrameSlot& slot); bool PublishCompletedSlot(const OutputFrameSlot& slot); bool ConsumeReadySlot(OutputFrameSlot& slot); bool ConsumeCompletedSlot(OutputFrameSlot& slot); bool MarkScheduled(const OutputFrameSlot& slot); bool MarkScheduledByBuffer(void* bytes); bool ReleaseSlot(const OutputFrameSlot& slot); bool ReleaseScheduledSlot(const OutputFrameSlot& slot); bool ReleaseSlotByBuffer(void* bytes); void Clear(); SystemOutputFramePoolMetrics GetMetrics() const; private: struct StoredSlot { std::vector bytes; OutputFrameSlotState state = OutputFrameSlotState::Free; uint64_t generation = 1; }; bool IsValidSlotLocked(const OutputFrameSlot& slot) const; bool TransitionSlotLocked(const OutputFrameSlot& slot, OutputFrameSlotState expectedState, OutputFrameSlotState nextState); void FillOutputSlotLocked(std::size_t index, OutputFrameSlot& slot); void RemoveReadyIndexLocked(std::size_t index); bool ReleaseSlotByIndexLocked(std::size_t index); std::size_t FrameByteCount() const; mutable std::mutex mMutex; SystemOutputFramePoolConfig mConfig; std::vector mSlots; std::deque mReadySlots; uint64_t mAcquireMissCount = 0; uint64_t mReadyUnderrunCount = 0; };