#pragma once #include "VideoIOFormat.h" #include #include #include #include #include #include enum class InputFrameSlotState { Free, Ready, Reading }; struct InputFrameMailboxConfig { unsigned width = 0; unsigned height = 0; VideoIOPixelFormat pixelFormat = VideoIOPixelFormat::Bgra8; unsigned rowBytes = 0; std::size_t capacity = 0; }; struct InputFrame { const void* bytes = nullptr; long rowBytes = 0; unsigned width = 0; unsigned height = 0; VideoIOPixelFormat pixelFormat = VideoIOPixelFormat::Bgra8; std::size_t index = 0; uint64_t generation = 0; uint64_t frameIndex = 0; }; struct InputFrameMailboxMetrics { std::size_t capacity = 0; std::size_t freeCount = 0; std::size_t readyCount = 0; std::size_t readingCount = 0; uint64_t submittedFrames = 0; uint64_t consumedFrames = 0; uint64_t droppedReadyFrames = 0; uint64_t submitMisses = 0; uint64_t consumeMisses = 0; uint64_t latestFrameIndex = 0; bool hasSubmittedFrame = false; double latestFrameAgeMilliseconds = 0.0; }; class InputFrameMailbox { public: InputFrameMailbox() = default; explicit InputFrameMailbox(const InputFrameMailboxConfig& config); void Configure(const InputFrameMailboxConfig& config); InputFrameMailboxConfig Config() const; bool SubmitFrame(const void* bytes, unsigned rowBytes, uint64_t frameIndex); bool TryAcquireLatest(InputFrame& frame); bool Release(const InputFrame& frame); void Clear(); InputFrameMailboxMetrics Metrics() const; private: struct Slot { std::vector bytes; InputFrameSlotState state = InputFrameSlotState::Free; uint64_t frameIndex = 0; uint64_t generation = 0; }; bool IsValidLocked(const InputFrame& frame) const; void FillFrameLocked(std::size_t index, InputFrame& frame) const; bool DropOldestReadyLocked(); std::size_t FrameByteCount() const; mutable std::mutex mMutex; InputFrameMailboxConfig mConfig; std::vector mSlots; std::deque mReadyIndices; InputFrameMailboxMetrics mCounters; std::chrono::steady_clock::time_point mLatestSubmitTime; };