yolobs-studio/plugins/decklink/decklink-device.cpp

274 lines
6.1 KiB
C++
Raw Normal View History

2019-07-27 12:47:10 +00:00
#include <sstream>
2016-02-23 23:16:51 +00:00
#include "decklink-device.hpp"
#include <util/threading.h>
2019-09-22 21:19:10 +00:00
DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_) {}
2016-02-23 23:16:51 +00:00
DeckLinkDevice::~DeckLinkDevice(void)
{
2019-07-27 12:47:10 +00:00
for (DeckLinkDeviceMode *mode : inputModes)
delete mode;
for (DeckLinkDeviceMode *mode : outputModes)
2016-02-23 23:16:51 +00:00
delete mode;
}
ULONG DeckLinkDevice::AddRef()
{
return os_atomic_inc_long(&refCount);
}
ULONG DeckLinkDevice::Release()
{
long ret = os_atomic_dec_long(&refCount);
if (ret == 0)
delete this;
return ret;
}
bool DeckLinkDevice::Init()
{
2018-02-19 19:54:37 +00:00
ComPtr<IDeckLinkAttributes> attributes;
const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes,
2019-09-22 21:19:10 +00:00
(void **)&attributes);
2018-02-19 19:54:37 +00:00
if (result == S_OK) {
decklink_bool_t detectable = false;
if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection,
2019-09-22 21:19:10 +00:00
&detectable) == S_OK &&
!!detectable) {
DeckLinkDeviceMode *mode =
new DeckLinkDeviceMode("Auto", MODE_ID_AUTO);
2019-07-27 12:47:10 +00:00
inputModes.push_back(mode);
inputModeIdMap[MODE_ID_AUTO] = mode;
2018-02-19 19:54:37 +00:00
}
}
2019-07-27 12:47:10 +00:00
// Find input modes
2016-02-23 23:16:51 +00:00
ComPtr<IDeckLinkInput> input;
2019-09-22 21:19:10 +00:00
if (device->QueryInterface(IID_IDeckLinkInput, (void **)&input) ==
S_OK) {
2019-07-27 12:47:10 +00:00
IDeckLinkDisplayModeIterator *modeIterator;
if (input->GetDisplayModeIterator(&modeIterator) == S_OK) {
IDeckLinkDisplayMode *displayMode;
long long modeId = 1;
while (modeIterator->Next(&displayMode) == S_OK) {
if (displayMode == nullptr)
continue;
2016-02-23 23:16:51 +00:00
2019-07-27 12:47:10 +00:00
DeckLinkDeviceMode *mode =
2019-09-22 21:19:10 +00:00
new DeckLinkDeviceMode(displayMode,
modeId);
2019-07-27 12:47:10 +00:00
inputModes.push_back(mode);
inputModeIdMap[modeId] = mode;
displayMode->Release();
++modeId;
}
modeIterator->Release();
2016-02-23 23:16:51 +00:00
}
2019-07-27 12:47:10 +00:00
}
// Get supported video connections
attributes->GetInt(BMDDeckLinkVideoInputConnections,
2019-09-22 21:19:10 +00:00
&supportedVideoInputConnections);
2019-07-27 12:47:10 +00:00
attributes->GetInt(BMDDeckLinkVideoOutputConnections,
2019-09-22 21:19:10 +00:00
&supportedVideoOutputConnections);
2019-07-27 12:47:10 +00:00
// Get supported audio connections
attributes->GetInt(BMDDeckLinkAudioInputConnections,
2019-09-22 21:19:10 +00:00
&supportedAudioInputConnections);
2019-07-27 12:47:10 +00:00
attributes->GetInt(BMDDeckLinkAudioOutputConnections,
2019-09-22 21:19:10 +00:00
&supportedAudioOutputConnections);
2016-02-23 23:16:51 +00:00
2019-07-27 12:47:10 +00:00
// find output modes
ComPtr<IDeckLinkOutput> output;
2019-09-22 21:19:10 +00:00
if (device->QueryInterface(IID_IDeckLinkOutput, (void **)&output) ==
S_OK) {
2019-07-27 12:47:10 +00:00
IDeckLinkDisplayModeIterator *modeIterator;
if (output->GetDisplayModeIterator(&modeIterator) == S_OK) {
IDeckLinkDisplayMode *displayMode;
long long modeId = 1;
while (modeIterator->Next(&displayMode) == S_OK) {
if (displayMode == nullptr)
continue;
DeckLinkDeviceMode *mode =
2019-09-22 21:19:10 +00:00
new DeckLinkDeviceMode(displayMode,
modeId);
2019-07-27 12:47:10 +00:00
outputModes.push_back(mode);
outputModeIdMap[modeId] = mode;
displayMode->Release();
++modeId;
}
modeIterator->Release();
}
2016-02-23 23:16:51 +00:00
}
2019-07-27 12:47:10 +00:00
// get keyer support
attributes->GetFlag(BMDDeckLinkSupportsExternalKeying,
2019-09-22 21:19:10 +00:00
&supportsExternalKeyer);
2019-07-27 12:47:10 +00:00
attributes->GetFlag(BMDDeckLinkSupportsInternalKeying,
2019-09-22 21:19:10 +00:00
&supportsInternalKeyer);
2019-07-27 12:47:10 +00:00
// Sub Device Counts
attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex);
attributes->GetInt(BMDDeckLinkNumberOfSubDevices, &numSubDevices);
2016-02-23 23:16:51 +00:00
decklink_string_t decklinkModelName;
decklink_string_t decklinkDisplayName;
if (device->GetModelName(&decklinkModelName) != S_OK)
return false;
DeckLinkStringToStdString(decklinkModelName, name);
if (device->GetDisplayName(&decklinkDisplayName) != S_OK)
return false;
DeckLinkStringToStdString(decklinkDisplayName, displayName);
hash = displayName;
if (result != S_OK)
return true;
2017-06-29 19:01:10 +00:00
int64_t channels;
/* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */
if (name == "Intensity Shuttle Thunderbolt")
maxChannel = 8;
2019-09-22 21:19:10 +00:00
else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels,
&channels) == S_OK)
2017-06-29 19:01:10 +00:00
maxChannel = (int32_t)channels;
else
maxChannel = 2;
2016-05-24 19:53:01 +00:00
/* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967
* BMDDeckLinkTopologicalID for older devices
* BMDDeckLinkPersistentID for newer ones */
2016-02-23 23:16:51 +00:00
int64_t value;
2019-09-22 21:19:10 +00:00
if (attributes->GetInt(BMDDeckLinkPersistentID, &value) != S_OK &&
2016-05-24 19:53:01 +00:00
attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK)
2016-02-23 23:16:51 +00:00
return true;
std::ostringstream os;
os << value << "_" << name;
hash = os.str();
return true;
}
bool DeckLinkDevice::GetInput(IDeckLinkInput **input)
{
2019-09-22 21:19:10 +00:00
if (device->QueryInterface(IID_IDeckLinkInput, (void **)input) != S_OK)
2016-02-23 23:16:51 +00:00
return false;
return true;
}
2019-07-27 12:47:10 +00:00
bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output)
2016-02-23 23:16:51 +00:00
{
2019-09-22 21:19:10 +00:00
if (device->QueryInterface(IID_IDeckLinkOutput, (void **)output) !=
S_OK)
2019-07-27 12:47:10 +00:00
return false;
return true;
}
bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer)
{
2019-09-22 21:19:10 +00:00
if (device->QueryInterface(IID_IDeckLinkKeyer,
(void **)deckLinkKeyer) != S_OK) {
fprintf(stderr,
"Could not obtain the IDeckLinkKeyer interface\n");
2019-07-27 12:47:10 +00:00
return false;
}
return true;
}
void DeckLinkDevice::SetKeyerMode(int newKeyerMode)
{
keyerMode = newKeyerMode;
}
int DeckLinkDevice::GetKeyerMode(void)
{
return keyerMode;
}
DeckLinkDeviceMode *DeckLinkDevice::FindInputMode(long long id)
{
return inputModeIdMap[id];
}
DeckLinkDeviceMode *DeckLinkDevice::FindOutputMode(long long id)
{
return outputModeIdMap[id];
2016-02-23 23:16:51 +00:00
}
2019-09-22 21:19:10 +00:00
const std::string &DeckLinkDevice::GetDisplayName(void)
2016-02-23 23:16:51 +00:00
{
return displayName;
}
2019-09-22 21:19:10 +00:00
const std::string &DeckLinkDevice::GetHash(void) const
2016-02-23 23:16:51 +00:00
{
return hash;
}
2019-09-22 21:19:10 +00:00
const std::vector<DeckLinkDeviceMode *> &
DeckLinkDevice::GetInputModes(void) const
2019-07-27 12:47:10 +00:00
{
return inputModes;
}
2019-09-22 21:19:10 +00:00
const std::vector<DeckLinkDeviceMode *> &
DeckLinkDevice::GetOutputModes(void) const
2019-07-27 12:47:10 +00:00
{
return outputModes;
}
int64_t DeckLinkDevice::GetVideoInputConnections()
{
return supportedVideoInputConnections;
}
int64_t DeckLinkDevice::GetAudioInputConnections()
{
return supportedAudioInputConnections;
}
bool DeckLinkDevice::GetSupportsExternalKeyer(void) const
{
return supportsExternalKeyer;
}
bool DeckLinkDevice::GetSupportsInternalKeyer(void) const
{
return supportsInternalKeyer;
}
int64_t DeckLinkDevice::GetSubDeviceCount()
{
return numSubDevices;
}
int64_t DeckLinkDevice::GetSubDeviceIndex()
2016-02-23 23:16:51 +00:00
{
2019-07-27 12:47:10 +00:00
return subDeviceIndex;
2016-02-23 23:16:51 +00:00
}
2019-09-22 21:19:10 +00:00
const std::string &DeckLinkDevice::GetName(void) const
2016-02-23 23:16:51 +00:00
{
return name;
}
2017-06-29 19:01:10 +00:00
int32_t DeckLinkDevice::GetMaxChannel(void) const
{
return maxChannel;
}