deckLink官方回复
一、获取DeckLink设备
(1)、同步获取
IDeckLinkIterator *deckLinkIterator = nullptr;
if (FAILED(CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
IID_IDeckLinkIterator, (void**)deckLinkIterator)))
{
fprintf(stderr, "A DeckLink iterator could not be created. The DeckLink drivers
may not be installed.\n");
return;
}
IDeckLink *deckLink = nullptr;
while(deckLinkIterator->next(&deckLink) == S_OK)
{
// save
}
(2)、异步获取
实现IDeckLinkDeviceNotificationCallback,调用callBack
class BMDDeviceDiscovery : public IDeckLinkDeviceNotificationCallback
{
using Callback = std::function<void(CComPtr<IDeckLink>&)>;
public:
BMDDeviceDiscovery();
virtual ~BMDDeviceDiscovery() = default;
void onDeviceArrival(const Callback& callback) { m_deckLinkArrivedCallback = callback; }
void onDeviceRemoval(const Callback& callback) { m_deckLinkRemovedCallback = callback; }
bool enable();
void disable();
// IDeckLinkDeviceArrivalNotificationCallback interface
HRESULT STDMETHODCALLTYPE DeckLinkDeviceArrived(IDeckLink* deckLinkDevice) override;
HRESULT STDMETHODCALLTYPE DeckLinkDeviceRemoved(IDeckLink* deckLinkDevice) override;
// IUnknown needs only a dummy implementation
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;
private:
CComPtr<IDeckLinkDiscovery> m_deckLinkDiscovery;
Callback m_deckLinkArrivedCallback;
Callback m_deckLinkRemovedCallback;
std::atomic<ULONG> m_refCount;
};
/* -LICENSE-START-
** Copyright (c) 2020 Blackmagic Design
**
** Permission is hereby granted, free of charge, to any person or organization
** obtaining a copy of the software and accompanying documentation covered by
** this license (the "Software") to use, reproduce, display, distribute,
** execute, and transmit the Software, and to prepare derivative works of the
** Software, and to permit third-parties to whom the Software is furnished to
** do so, all subject to the following:
**
** The copyright notices in the Software and this entire statement, including
** the above license grant, this restriction and the following disclaimer,
** must be included in all copies of the Software, in whole or in part, and
** all derivative works of the Software, unless such copies or derivative
** works are solely in the form of machine-executable object code generated by
** a source language processor.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
** DEALINGS IN THE SOFTWARE.
** -LICENSE-END-
*/
#include <stdexcept>
#include "BMDDeviceDiscovery.h"
BMDDeviceDiscovery::BMDDeviceDiscovery() :
m_deckLinkDiscovery(nullptr),
m_refCount(1)
{
if (CoCreateInstance(CLSID_CDeckLinkDiscovery, NULL, CLSCTX_ALL, IID_IDeckLinkDiscovery, (void**)&m_deckLinkDiscovery) != S_OK)
throw std::runtime_error("Unable to create IDeckLinkDiscovery interface object");
}
bool BMDDeviceDiscovery::enable()
{
HRESULT result = E_FAIL;
// Install device arrival notifications
if (m_deckLinkDiscovery)
result = m_deckLinkDiscovery->InstallDeviceNotifications(this);
return result == S_OK;
}
void BMDDeviceDiscovery::disable()
{
// Uninstall device arrival notifications
if (m_deckLinkDiscovery)
m_deckLinkDiscovery->UninstallDeviceNotifications();
}
HRESULT BMDDeviceDiscovery::DeckLinkDeviceArrived(/* in */ IDeckLink* deckLink)
{
if (m_deckLinkArrivedCallback)
{
CComPtr<IDeckLink> deckLinkDevice = deckLink;
m_deckLinkArrivedCallback(deckLinkDevice);
}
return S_OK;
}
HRESULT BMDDeviceDiscovery::DeckLinkDeviceRemoved(/* in */ IDeckLink* deckLink)
{
if (m_deckLinkRemovedCallback)
{
CComPtr<IDeckLink> deckLinkDevice = deckLink;
m_deckLinkRemovedCallback(deckLinkDevice);
}
return S_OK;
}
HRESULT BMDDeviceDiscovery::QueryInterface(REFIID iid, LPVOID *ppv)
{
HRESULT result = E_NOINTERFACE;
if (ppv == NULL)
return E_INVALIDARG;
// Initialise the return result
*ppv = NULL;
// Obtain the IUnknown interface and compare it the provided REFIID
if (iid == IID_IUnknown)
{
*ppv = this;
AddRef();
result = S_OK;
}
else if (iid == IID_IDeckLinkDeviceNotificationCallback)
{
*ppv = static_cast<IDeckLinkDeviceNotificationCallback*>(this);
AddRef();
result = S_OK;
}
return result;
}
ULONG BMDDeviceDiscovery::AddRef(void)
{
return ++m_refCount;
}
ULONG BMDDeviceDiscovery::Release(void)
{
ULONG newRefValue = --m_refCount;
if (newRefValue == 0)
delete this;
return newRefValue;
}
二、获取IDeckLinkInput 并调用flag bmdVideoInputEnableFormatDetection(注:这条必不可少,不然获取不到信号)
IDeckLinkInput *pInput = nullptr;
if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&pInput) == S_FALSE)
{
return;
}
// 必须要
if (pInput->EnableVideoInput(bmdModeNTSC, bmdFormat8BitYUV, bmdVideoInputEnableFormatDetection) != S_OK)
{
return;
}
三、获取IDeckLinkStatus,并读取相应的属性
IDeckLinkStatus *deckLinkStatus = nullptr;
if (deckLink->QueryInterface(IID_IDeckLinkStatus, (void**)&deckLinkStatus) != S_OK || deckLinkStatus == nullptr)
{
return;
}
BOOL bLock;
if (deckLinkStatus->GetFlag(bmdDeckLinkStatusVideoInputSignalLocked, &bLock) != S_OK)
{
return;
}
int64_t inputFormat;
if (deckLinkStatus->GetInt(bmdDeckLinkStatusDetectedVideoInputFormatFlags, &inputFormat) != S_OK)
{
return;
}
// 输入类型
int64_t statusInt;
if (deckLinkStatus->GetInt(bmdDeckLinkStatusDetectedVideoInputMode, &statusInt) != S_OK)
{
return;
}
if (statusInt == bmdModeUnknown)
{
return;
}