Files
video-shader-toys/apps/RenderCadenceCompositor/video/DeckLinkInput.h
Aiden fd4b70ec9c
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 3m4s
CI / Windows Release Package (push) Has been skipped
Input GPU decoding
2026-05-12 20:26:03 +10:00

97 lines
3.0 KiB
C++

#pragma once
#include "../frames/InputFrameMailbox.h"
#include "DeckLinkAPI_h.h"
#include "DeckLinkDisplayMode.h"
#include <atlbase.h>
#include <atomic>
#include <chrono>
#include <cstdint>
#include <string>
#include <vector>
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<ULONG> 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<IDeckLinkInput> mInput;
CComPtr<DeckLinkInputCallback> mCallback;
std::atomic<bool> mRunning{ false };
std::atomic<uint64_t> mCapturedFrames{ 0 };
std::atomic<uint64_t> mNoInputSourceFrames{ 0 };
std::atomic<uint64_t> mUnsupportedFrames{ 0 };
std::atomic<uint64_t> mSubmitMisses{ 0 };
std::atomic<double> mConvertMilliseconds{ 0.0 };
std::atomic<double> mSubmitMilliseconds{ 0.0 };
std::atomic<bool> mLoggedFirstFrame{ false };
std::atomic<bool> mLoggedNoInputSource{ false };
std::atomic<bool> mLoggedUnsupportedFrame{ false };
std::atomic<bool> mLoggedSubmitMiss{ false };
};
}