#pragma once #include "../frames/InputFrameMailbox.h" #include "DeckLinkAPI_h.h" #include "DeckLinkDisplayMode.h" #include #include #include #include #include #include namespace RenderCadenceCompositor { struct DeckLinkInputConfig { VideoFormat videoFormat; }; struct DeckLinkInputMetrics { uint64_t capturedFrames = 0; uint64_t noInputSourceFrames = 0; uint64_t unsupportedFrames = 0; uint64_t submitMisses = 0; double convertMilliseconds = 0.0; double submitMilliseconds = 0.0; const char* captureFormat = "none"; }; class DeckLinkInput; class DeckLinkInputCallback final : public IDeckLinkInputCallback { public: explicit DeckLinkInputCallback(DeckLinkInput& owner); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID* ppv) override; ULONG STDMETHODCALLTYPE AddRef() override; ULONG STDMETHODCALLTYPE Release() override; HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioPacket) override; HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode* newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags) override; private: DeckLinkInput& mOwner; std::atomic mRefCount{ 1 }; }; class DeckLinkInput { public: DeckLinkInput(InputFrameMailbox& mailbox); DeckLinkInput(const DeckLinkInput&) = delete; DeckLinkInput& operator=(const DeckLinkInput&) = delete; ~DeckLinkInput(); bool Initialize(const DeckLinkInputConfig& config, std::string& error); bool Start(std::string& error); void Stop(); void ReleaseResources(); bool IsInitialized() const { return mInput != nullptr; } bool IsRunning() const { return mRunning.load(std::memory_order_acquire); } VideoIOPixelFormat CapturePixelFormat() const; DeckLinkInputMetrics Metrics() const; void HandleFrameArrived(IDeckLinkVideoInputFrame* inputFrame); void HandleFormatChanged(); private: bool DiscoverInput(const DeckLinkInputConfig& config, std::string& error); bool SupportsInputFormat(IDeckLinkInput* input, BMDDisplayMode displayMode, BMDPixelFormat pixelFormat) const; bool SubmitBgra8Frame(IDeckLinkVideoInputFrame* inputFrame, const void* bytes); bool SubmitUyvy8Frame(IDeckLinkVideoInputFrame* inputFrame, const void* bytes); const char* CaptureFormatName() const; InputFrameMailbox& mMailbox; DeckLinkInputConfig mConfig; BMDPixelFormat mCapturePixelFormat = bmdFormat8BitBGRA; CComPtr mInput; CComPtr mCallback; std::atomic mRunning{ false }; std::atomic mCapturedFrames{ 0 }; std::atomic mNoInputSourceFrames{ 0 }; std::atomic mUnsupportedFrames{ 0 }; std::atomic mSubmitMisses{ 0 }; std::atomic mConvertMilliseconds{ 0.0 }; std::atomic mSubmitMilliseconds{ 0.0 }; std::atomic mLoggedFirstFrame{ false }; std::atomic mLoggedNoInputSource{ false }; std::atomic mLoggedUnsupportedFrame{ false }; std::atomic mLoggedSubmitMiss{ false }; }; }