94 lines
3.4 KiB
C++
94 lines
3.4 KiB
C++
#pragma once
|
|
|
|
#include "AppState.h"
|
|
#include "D3DProcessor.h"
|
|
|
|
#include "DeckLinkApi.h"
|
|
#include <wrl/client.h>
|
|
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <string>
|
|
|
|
class DeckLinkPipeline;
|
|
|
|
class DeckLinkInputCallback final : public IDeckLinkInputCallback
|
|
{
|
|
public:
|
|
explicit DeckLinkInputCallback(DeckLinkPipeline& pipeline);
|
|
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID* ppv) override;
|
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
|
ULONG STDMETHODCALLTYPE Release() override;
|
|
HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode* mode, BMDDetectedVideoInputFormatFlags flags) override;
|
|
HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioPacket) override;
|
|
|
|
private:
|
|
std::atomic<ULONG> m_refCount = 1;
|
|
DeckLinkPipeline& m_pipeline;
|
|
};
|
|
|
|
class DeckLinkOutputCallback final : public IDeckLinkVideoOutputCallback
|
|
{
|
|
public:
|
|
explicit DeckLinkOutputCallback(DeckLinkPipeline& pipeline);
|
|
|
|
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID* ppv) override;
|
|
ULONG STDMETHODCALLTYPE AddRef() override;
|
|
ULONG STDMETHODCALLTYPE Release() override;
|
|
HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted(IDeckLinkVideoFrame* completedFrame, BMDOutputFrameCompletionResult result) override;
|
|
HRESULT STDMETHODCALLTYPE ScheduledPlaybackHasStopped() override;
|
|
|
|
private:
|
|
std::atomic<ULONG> m_refCount = 1;
|
|
DeckLinkPipeline& m_pipeline;
|
|
};
|
|
|
|
class DeckLinkPipeline
|
|
{
|
|
public:
|
|
DeckLinkPipeline(AppState& appState, D3DProcessor& processor);
|
|
~DeckLinkPipeline();
|
|
|
|
bool initialize(std::string& error);
|
|
bool start(std::string& error);
|
|
void stop();
|
|
void onFormatChanged(IDeckLinkDisplayMode* mode, BMDDetectedVideoInputFormatFlags flags);
|
|
void onFrameArrived(IDeckLinkVideoInputFrame* videoFrame);
|
|
void onOutputFrameCompleted(BMDOutputFrameCompletionResult result);
|
|
|
|
private:
|
|
friend class DeckLinkInputCallback;
|
|
friend class DeckLinkOutputCallback;
|
|
|
|
bool selectDevice(std::string& error);
|
|
bool findStartupMode(Microsoft::WRL::ComPtr<IDeckLinkDisplayMode>& selectedMode, std::string& error);
|
|
bool configureForMode(IDeckLinkDisplayMode* mode, BMDPixelFormat inputFormat, std::string& error);
|
|
bool chooseOutputFormat(BMDDisplayMode displayMode, BMDPixelFormat& outputFormat);
|
|
void updateStatusLocked();
|
|
std::string deckLinkName(IDeckLink* deckLink) const;
|
|
std::string displayModeName(IDeckLinkDisplayMode* mode) const;
|
|
|
|
AppState& m_appState;
|
|
D3DProcessor& m_processor;
|
|
mutable std::recursive_mutex m_mutex;
|
|
|
|
Microsoft::WRL::ComPtr<IDeckLink> m_deckLink;
|
|
Microsoft::WRL::ComPtr<IDeckLinkInput> m_input;
|
|
Microsoft::WRL::ComPtr<IDeckLinkOutput> m_output;
|
|
Microsoft::WRL::ComPtr<IDeckLinkConfiguration> m_configuration;
|
|
Microsoft::WRL::ComPtr<IDeckLinkVideoConversion> m_converter;
|
|
Microsoft::WRL::ComPtr<IDeckLinkDisplayMode> m_activeMode;
|
|
Microsoft::WRL::ComPtr<DeckLinkInputCallback> m_inputCallback;
|
|
Microsoft::WRL::ComPtr<DeckLinkOutputCallback> m_outputCallback;
|
|
|
|
PipelineStatus m_status;
|
|
BMDPixelFormat m_inputFormat = bmdFormat8BitYUV;
|
|
BMDPixelFormat m_outputFormat = bmdFormat8BitARGB;
|
|
BMDTimeValue m_frameDuration = 1001;
|
|
BMDTimeScale m_frameTimescale = 30000;
|
|
uint64_t m_totalScheduled = 0;
|
|
bool m_initialized = false;
|
|
bool m_streamStarted = false;
|
|
};
|