97 lines
3.0 KiB
C++
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 };
|
|
};
|
|
}
|