#pragma once #include "DeckLinkAPI.h" #include using namespace std; #include #include #include #include #define MAX_DECKLINK 16 #define SD_FRAME_WIDTH 720 #define SD_FRAME_HEIGHT 576 #define HD_FRAME_WIDTH 1920 #define HD_FRAME_HEIGHT 1080 // 视频委托对象 class CDeckLinkInputDelegate : public IDeckLinkInputCallback { public: CDeckLinkInputDelegate(void* pOwner); virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv); virtual ULONG STDMETHODCALLTYPE AddRef(void); virtual ULONG STDMETHODCALLTYPE Release(void); virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents notificationEvents, IDeckLinkDisplayMode* newDisplayMode, BMDDetectedVideoInputFormatFlags detectedSignalFlags); virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame* pArrivedFrame, IDeckLinkAudioInputPacket*); private: int m_RefCount; void* m_pOwner; }; // 视频输入对象 class CVideoInput { public: CVideoInput(const char* lpszCardName, void* pOwner); virtual ~CVideoInput(); public: // 对象初始化 bool Init(int nChannel, CDeckLinkInputDelegate* pDelegate, BMDDisplayMode dmDisplayMode); // 启动视频输入 bool Start(); // 停止视频输入 bool Stop(); private: QString m_strCardName; // 视频输入卡名称 void* m_pOwner; // 拥有者 BMDDisplayMode m_dmDisplayMode; // 显示模式 IDeckLinkInput* m_pInputCard; // 输入卡对象 bool m_bOpen; }; // 视频输出对象 class CVideoOutput { public: CVideoOutput(const char* lpszCardName, void* pOwner); virtual ~CVideoOutput(); public: // 对象初始化 bool Init(int nChannel, BMDDisplayMode dmDisplayMode, int nFrameWidth, int nFrameHeight); // 启动视频输入 bool Start(); // 停止视频输入 bool Stop(); // 输出视频数据 bool OutputData(byte* pFrameData); private: QString m_strCardName; // 视频输出卡名称 void* m_pOwner; // 拥有者 BMDDisplayMode m_dmDisplayMode; // 显示模式 IDeckLinkOutput* m_pOutputCard; // 输出卡对象 IDeckLinkMutableVideoFrame* m_pVideoFrame; // 视频帧对象 int m_nFrameWidth; int m_nFrameHeight; bool m_bOpen; }; typedef void (*pCallBack_DataCapture)(BYTE* pData, int nDataSize, void* pOwner); // 视频管理器 class CDeckLinkManager { public: CDeckLinkManager(); virtual ~CDeckLinkManager(void); public: // 查找系统中已安装的DeckLink卡,返回找到的卡的数量。 static int SearchDeckLinkCard(); // 初始化视频管理器 // 参数说明: // lpszCardName:视频输入卡标识,不能为NULL。 // nChannel:通道号。 // shVideoType:用于指出支持的视频类型,标清或高清。 // pCB_DataCapture:数据采集回调函数 // pOwner:对象拥有者 // 返回值:true表示初始化成功,false表示初始化失败。 // 使用说明:strOutputCard、hMainVideoWnd 、hSecondVideoWnd 这三个(视频流输出对象)参数 // 不能同时为NULL。三个视频流输出对象在创建时缺省被激活,其中视频输出和主视频显示对象 // 缺省叠加信息,副视频显示对象缺省不叠加信息。该函数应在对象实例化后第一个被调用,并 // 且仅被调用一次。 bool InitVideoInput(const char* lpszCardName, int nChannel, int nFrameWidth, int nFrameHeight, BMDDisplayMode eDisplayMode, pCallBack_DataCapture pCB_DataCapture, void* pOwner); // 初始化视频管理器 // 参数说明: // lpszCardName:视频输入卡标识,不能为NULL。 // nChannel:通道号。 // shVideoType:用于指出支持的视频类型,标清或高清。 // pOwner:对象拥有者 // 返回值:true表示初始化成功,false表示初始化失败。 // 使用说明:strOutputCard、hMainVideoWnd 、hSecondVideoWnd 这三个(视频流输出对象)参数 // 不能同时为NULL。三个视频流输出对象在创建时缺省被激活,其中视频输出和主视频显示对象 // 缺省叠加信息,副视频显示对象缺省不叠加信息。该函数应在对象实例化后第一个被调用,并 // 且仅被调用一次。 bool InitVideoOutput(const char* lpszCardName, int nChannel, int nFrameWidth, int nFrameHeight, BMDDisplayMode eDisplayMode); // 开始视频流 bool StartStreams(); // 停止视频流 bool StopStreams(); // 写数据到采集卡 bool OutputData(byte* pFrameData); private: // 采集到达的视频帧 void CaptureVideoFrame(IDeckLinkVideoInputFrame* pArrivedFrame); public: static int m_nDeckLinkCount; // 找到的卡的数量 static IDeckLink *m_pDeckLink[MAX_DECKLINK]; // DeckLink卡对象的数组 // 拥有者 static std::map m_mapDeckLinkCards; private: friend HRESULT STDMETHODCALLTYPE CDeckLinkInputDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*); private: // VideoInput CVideoInput* m_pInput; // 视频输入对象 CDeckLinkInputDelegate* m_pDelegate; // 视频委托对象 pCallBack_DataCapture m_pCB_DataCapture; // 视频采集回调函数 // VideoOutput CVideoOutput* m_pOutput; // bool m_bRunning; // 视频流是否在运行 long m_nFrameWidth; // 视频帧宽度 long m_nFrameHeight; // 视频帧高度 long m_nFrameSize; // 视频帧大小(字节数) long m_nTimeScale; // 时间刻度 BMDDisplayMode m_eDisplayMode; // 显示模式 int m_nChannel; // 通道号 BYTE* m_pFrameData; void* m_pOwner; bool m_bVideoInput; // true,VideoInput;false,VideoOutput };