43#include <condition_variable>
52#include <unordered_map>
57#include "DeckLinkAPIVersion.h"
66#define MOD_NAME "[DeckLink] "
71using std::invalid_argument;
75using std::ostringstream;
82using std::unordered_map;
87 const char *errptr =
nullptr;
89 errptr = hresult_to_str(res);
97 oss <<
" " <<
"(0x" << hex << setfill(
'0') << setw(8) << res <<
")";
107 return strdup(
"(NULL!)");
111 size_t len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(bmd_string), kCFStringEncodingUTF8) + 1;
112 cstr = (
char *) malloc(
len);
113 CFStringGetCString(bmd_string, (
char *) cstr,
len, kCFStringEncodingUTF8);
115 size_t len = SysStringLen(bmd_string) * 4 + 1;
116 cstr = (
char *) malloc(
len);
117 wcstombs((
char *) cstr, bmd_string,
len);
119 cstr = strdup(bmd_string);
128 return CFStringCreateWithCString(kCFAllocatorMalloc, cstr, kCFStringEncodingUTF8);
131 const char *tmp = cstr;
132 size_t required_size = mbsrtowcs(NULL, &tmp, 0, &mbstate) + 1;
133 BMD_STR out = (
wchar_t *) malloc(required_size *
sizeof(
wchar_t));
134 mbsrtowcs(out, &tmp, required_size, &mbstate);
149 SysFreeString(
string);
151 free(
const_cast<char *
>(
string));
158 std::string out = displayModeCString;
159 free(displayModeCString);
173 IDeckLinkIterator *deckLinkIterator =
nullptr;
176 HRESULT result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
177 IID_IDeckLinkIterator, (
void **) &deckLinkIterator);
180 deckLinkIterator =
nullptr;
183 *com_initialized =
false;
184 deckLinkIterator = CreateDeckLinkIteratorInstance();
187 if (!deckLinkIterator && verbose) {
188 log_msg(
LOG_LEVEL_ERROR,
"A DeckLink iterator could not be created. The DeckLink drivers may not be installed or are outdated.\n");
189 log_msg(
LOG_LEVEL_INFO,
"This UltraGrid version was compiled with DeckLink drivers %s. You should have at least this version.\n\n",
190 BLACKMAGIC_DECKLINK_API_VERSION_STRING);
194 return deckLinkIterator;
205 IDeckLinkAPIInformation *APIInformation = NULL;
207 bool com_initialized =
false;
213 result = CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
214 IID_IDeckLinkAPIInformation, (
void **) &APIInformation);
217 APIInformation = CreateDeckLinkAPIInformationInstance();
218 if(APIInformation == NULL) {
224 result = APIInformation->GetInt(BMDDeckLinkAPIVersion, &value);
230 if (BLACKMAGIC_DECKLINK_API_VERSION > value) {
241 if (APIInformation) {
242 APIInformation->Release();
251 BMD_STR current_version = NULL;
252 IDeckLinkAPIInformation *APIInformation = NULL;
256 bool com_initialized =
false;
261 result = CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
262 IID_IDeckLinkAPIInformation, (
void **) &APIInformation);
265 APIInformation = CreateDeckLinkAPIInformationInstance();
266 if(APIInformation == NULL) {
268 fprintf(stderr,
"Cannot get API information! Perhaps drivers not installed.\n");
272 result = APIInformation->GetString(BMDDeckLinkAPIVersion, ¤t_version);
273 if (result != S_OK) {
274 fprintf(stderr,
"Cannot get API version string!\n");
277 fprintf(stderr,
"This UltraGrid version was compiled against DeckLink SDK %s. ", BLACKMAGIC_DECKLINK_API_VERSION_STRING);
279 fprintf(stderr,
"System version is %s.\n", currentVersionCString);
281 free(
const_cast<char *
>(currentVersionCString));
285 if (APIInformation) {
286 APIInformation->Release();
296 { bmdProfileOneSubDeviceFullDuplex, {
"1 sub-device full-duplex",
"8K Pro, Duo 2, Quad 2" } },
297 { bmdProfileOneSubDeviceHalfDuplex, {
"1 sub-device half-duplex",
"8K Pro" } },
298 { bmdProfileTwoSubDevicesFullDuplex, {
"2 sub-devices full-duplex",
"8K Pro" } },
299 { bmdProfileTwoSubDevicesHalfDuplex, {
"2 sub-devices half-duplex",
"Duo 2, Quad 2" } },
300 { bmdProfileFourSubDevicesHalfDuplex, {
"4 sub-devices half-duplex",
"8K Pro" } },
303#define EXIT_IF_FAILED(cmd, name) \
305 HRESULT result = cmd;\
306 if (FAILED(result)) {;\
307 LOG(LOG_LEVEL_ERROR) << MOD_NAME << name << ": " << bmd_hresult_to_string(result) << "\n";\
313#define RELEASE_IF_NOT_NULL(x) if (x != nullptr) { x->Release(); x = nullptr; }
317 IDeckLinkProfileAttributes* profileAttributes =
nullptr;
318 if (HRESULT result = profile->QueryInterface(IID_IDeckLinkProfileAttributes, (
void**)&profileAttributes);
FAILED(result)) {
322 int64_t profileIDInt = 0;
325 profileAttributes->GetInt(BMDDeckLinkProfileID, &profileIDInt);
326 if (SUCCEEDED(res)) {
327 profileAttributes->Release();
332 return (BMDProfileID) profileIDInt;
342 HRESULT
ProfileChanging ( [[maybe_unused]] IDeckLinkProfile* profileToBeActivated, [[maybe_unused]]
BMD_BOOL streamsWillBeForcedToStop)
override {
return S_OK; }
354 return E_NOINTERFACE;
370 LOG(
LOG_LEVEL_INFO) <<
"[DeckLink] Profile " << profileName <<
" already active.\n";
374 LOG(
LOG_LEVEL_INFO) <<
"[DeckLink] Waiting for profile activation... (this may take few seconds)\n";
378 LOG(
LOG_LEVEL_NOTICE) <<
"[DeckLink] Profile " << profileName <<
" activated succesfully.\n";
380 LOG(
LOG_LEVEL_ERROR) <<
"[DeckLink] Profile " << profileName <<
" activation timeouted!\n";
405 printf(
"Available profiles:\n");
411 IDeckLinkProfileManager *manager =
nullptr;
412 IDeckLinkProfileIterator *it =
nullptr;
413 IDeckLinkProfile *profile =
nullptr;
417 if (HRESULT res = deckLink->QueryInterface(IID_IDeckLinkProfileManager, (
void**)&manager)) {
418 const bool error = !(req_profile.
is_default() && res == E_NOINTERFACE);
425 const uint32_t profileID = req_profile.
is_default() ? (int64_t) bmdProfileOneSubDeviceFullDuplex : req_profile.
get_int();
427 EXIT_IF_FAILED(manager->GetProfiles(&it),
"Cannot set duplex - get profiles");
429 while (it->Next(&profile) == S_OK) {
430 IDeckLinkProfileAttributes *attributes;
432 if (profile->QueryInterface(IID_IDeckLinkProfileAttributes,
433 (
void**)&attributes) != S_OK) {
437 if (attributes->GetInt(BMDDeckLinkProfileID, &
id) == S_OK) {
438 if (profileID == bmdDuplexHalf) {
439 if (
id == bmdProfileTwoSubDevicesHalfDuplex ||
id == bmdProfileFourSubDevicesHalfDuplex) {
442 }
else if (profileID ==
id) {
447 BMD_CHECK(manager->SetCallback(p),
"IDeckLinkProfileManager::SetCallback",
goto cleanup);
448 if (profile->SetActive() != S_OK) {
459 attributes->Release();
481 IDeckLinkProfileManager *manager =
nullptr;
483 if (HRESULT result = decklink->QueryInterface(IID_IDeckLinkProfileManager, (
void**)&manager);
FAILED(result)) {
484 if (result != E_NOINTERFACE) {
490 IDeckLinkProfileIterator *it =
nullptr;
491 IDeckLinkProfile *profile =
nullptr;
492 EXIT_IF_FAILED(manager->GetProfiles(&it),
"Cannot get profiles iterator");
493 while (it->Next(&profile) == S_OK) {
495 if ((profile->IsActive(&isActiveProfile) == S_OK) && isActiveProfile) {
511 if (profile_active != bmdProfileOneSubDeviceHalfDuplex &&
512 profile_active != bmdProfileOneSubDeviceFullDuplex) {
513 uint32_t profile_fcc_host = ntohl(profile_active);
523 BMD_STR deviceNameString = NULL;
524 char * deviceNameCString = NULL;
527 if (decklink->GetDisplayName((
BMD_STR *) &deviceNameString) == S_OK) {
529 ret = deviceNameCString;
531 free(deviceNameCString);
542 memset(u.c4,
' ', 4);
543 memcpy(u.c4, str, min(strlen(str),
sizeof u.c4));
544 return htonl(u.fourcc);
551 StringFromCLSID(iid, &guidString);
553 int ret = wcstombs(buffer, guidString,
sizeof buffer);
554 if (ret ==
sizeof buffer) {
555 buffer[
sizeof buffer - 1] =
'\0';
558 ::CoTaskMemFree(guidString);
560 auto flags = output.flags();
561 output << hex << uppercase << setfill(
'0') <<
562 setw(2) <<
static_cast<int>(iid.byte0) << setw(2) <<
static_cast<int>(iid.byte1) <<
563 setw(2) <<
static_cast<int>(iid.byte2) << setw(2) <<
static_cast<int>(iid.byte3) <<
"-" <<
564 setw(2) <<
static_cast<int>(iid.byte4) << setw(2) <<
static_cast<int>(iid.byte5) <<
"-" <<
565 setw(2) <<
static_cast<int>(iid.byte6) << setw(2) <<
static_cast<int>(iid.byte7) <<
"-" <<
566 setw(2) <<
static_cast<int>(iid.byte8) << setw(2) <<
static_cast<int>(iid.byte9) <<
"-" <<
567 setw(2) <<
static_cast<int>(iid.byte10) << setw(2) <<
static_cast<int>(iid.byte11) <<
568 setw(2) <<
static_cast<int>(iid.byte12) << setw(2) <<
static_cast<int>(iid.byte13) <<
569 setw(2) <<
static_cast<int>(iid.byte14) << setw(2) <<
static_cast<int>(iid.byte15);
576#define BMDFCC(x) {x,#x}
577 static const unordered_map<uint32_t, const char *> conf_name_map = {
578 BMDFCC(bmdVideo3DPackingSidebySideHalf),
BMDFCC(bmdVideo3DPackingLinebyLine),
BMDFCC(bmdVideo3DPackingTopAndBottom),
BMDFCC(bmdVideo3DPackingFramePacking),
BMDFCC(bmdVideo3DPackingRightOnly),
BMDFCC(bmdVideo3DPackingLeftOnly),
579 BMDFCC(bmdDeckLinkCapturePassthroughModeDisabled),
580 BMDFCC(bmdDeckLinkCapturePassthroughModeCleanSwitch),
581 BMDFCC(bmdDeckLinkConfig444SDIVideoOutput),
582 BMDFCC(bmdDeckLinkConfigAnalogAudioConsumerLevels),
583 BMDFCC(bmdDeckLinkConfigCapture1080pAsPsF),
584 BMDFCC(bmdDeckLinkConfigCapturePassThroughMode),
585 BMDFCC(bmdDeckLinkConfigFieldFlickerRemoval),
586 BMDFCC(bmdDeckLinkConfigLowLatencyVideoOutput),
587 BMDFCC(bmdDeckLinkConfigHDMI3DPackingFormat),
588 BMDFCC(bmdDeckLinkConfigOutput1080pAsPsF),
589 BMDFCC(bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit),
590 BMDFCC(bmdDeckLinkConfigSDIOutputLinkConfiguration),
591 BMDFCC(bmdDeckLinkConfigSMPTELevelAOutput),
592 BMDFCC(bmdDeckLinkConfigVideoInputConnection),
593 BMDFCC(bmdDeckLinkConfigVideoInputConversionMode),
594 BMDFCC(bmdDeckLinkConfigVideoOutputConversionMode),
595 BMDFCC(bmdDeckLinkConfigVideoOutputIdleOperation),
596 BMDFCC(bmdIdleVideoOutputBlack),
597 BMDFCC(bmdIdleVideoOutputLastFrame),
598 BMDFCC(bmdLinkConfigurationSingleLink),
BMDFCC(bmdLinkConfigurationDualLink),
BMDFCC(bmdLinkConfigurationQuadLink),
601 if (
auto it = conf_name_map.find(fourcc); it != conf_name_map.end()) {
608 fcc.i = htonl(fourcc);
609 return string(
"'") + fcc.c +
"'";
623 output <<
"(default)";
629 output << (b.
get_flag() ?
"true" :
"false");
635 auto flags = output.flags();
636 output << b.
get_int() <<
" (0x" << hex
644 auto flags = output.flags();
645 output << fixed << b.
m_val.
f;
698 "Option is not set to a string but get_string() called! Current "
723#pragma clang diagnostic push
724#pragma clang diagnostic ignored "-Wnull-pointer-arithmetic"
726 if (
val ==
nullptr ||
val ==
static_cast<char *
>(
nullptr) + 1
727 || strlen(
val) == 0 || strcasecmp(
val,
"true") == 0 || strcasecmp(
val,
"on") == 0 || strcasecmp(
val,
"yes") == 0) {
732#pragma clang diagnostic pop
734 if (strcasecmp(
val,
"false") == 0 || strcasecmp(
val,
"off") == 0 || strcasecmp(
val,
"no") == 0) {
739 if (strcasecmp(
val,
"keep") == 0) {
744 if (strcmp(
val,
"help") == 0) {
750 if ((
val[0] ==
'"' &&
val[strlen(
val) - 1] ==
'"') || (
val[0] ==
'\'' &&
val[strlen(
val) - 1] ==
'\'')) {
751 string raw_val(
val + 1);
752 raw_val.erase(raw_val.length() - 1, 1);
762 bool is_number =
true;
763 bool decimal_point =
false;
764 for (
size_t i = 0;
i < strlen(
val); ++
i) {
770 decimal_point =
true;
773 is_number = is_number && isxdigit(
val[
i]);
774 if (
i == 0 && (
val[
i] ==
'-' ||
val[
i] ==
'+')) {
786 if (strlen(
val) <= 4) {
794bool bmd_option::device_write(IDeckLinkConfiguration *deckLinkConfiguration, BMDDeckLinkConfigurationID opt,
string const &log_prefix)
const {
795 HRESULT res = E_FAIL;
798 res = deckLinkConfiguration->SetFlag(opt,
get_flag());
801 res = deckLinkConfiguration->SetInt(opt,
get_int());
804 res = deckLinkConfiguration->SetFloat(opt,
m_val.f);
808 res = deckLinkConfiguration->SetString(opt,
s);
816 ostringstream value_oss;
826 LOG(lvl) << log_prefix <<
"Unable to set key "
837 auto lut = (
const unsigned int * __restrict) udata;
838 auto *in = (
const unsigned char *) i;
839 auto *out = (
unsigned char *) o;
840 const unsigned char *in_end = in +
len;
841 while (in < in_end) {
842 unsigned r = in[0] << 2U | in[1] >> 6U;
843 unsigned g = (in[1] & 0x3FU) << 4U | in[2] >> 4U;
844 unsigned b = (in[2] & 0xFU) << 6U | in[3] >> 2U;
849 out[1] = (r & 0x3U) << 6U | (g >> 4U);
850 out[2] = (g & 0xFU) << 4U | (b >> 6U);
851 out[3] = (b & 0x3FU) << 2U;
858 for (
int i = 0; i < 1024; ++i) {
860 val = 4 + (
val - 64) * 1015 / 896;
871 static unsigned int lut[1024];
872 if (lut[1023] == 0) {
881 for (
int i = 0; i < 1024; ++i) {
883 val = 64 + (
val - 4) * 896 / 1015;
894 static unsigned int lut[1024];
895 if (lut[1023] == 0) {
904 switch(audioConnection) {
905 case bmdAudioOutputSwitchAESEBU:
907 case bmdAudioOutputSwitchAnalog:
917 vector<pair<uint32_t, const char *>> map {
918 { bmdDisplayModeColorspaceRec601,
"Rec601" },
919 { bmdDisplayModeColorspaceRec709,
"Rec709" },
920 { bmdDisplayModeColorspaceRec2020,
"Rec2020" },
921 { bmdDisplayModeSupports3D,
"3D" },
924 for (
auto &f : map ) {
925 if (
flags & f.first) {
926 oss << (!
first ?
", " :
"") << f.second;
933 if (
flags >= bmdDisplayModeColorspaceRec2020 << 1) {
934 oss <<
", (unknown flags)";
942 const uint32_t fcc = htonl(p.first);
943 color_printf(
"%s" TBOLD(
"%.4s")
" - %s (%s)\n", line_prefix, (
const char *) &fcc, p.second.first, p.second.second);
949 static const map<BMDVideoConnection, string> m = {
950 { bmdVideoConnectionSDI,
"SDI" },
951 { bmdVideoConnectionHDMI,
"HDMI"},
952 { bmdVideoConnectionOpticalSDI,
"OpticalSDI"},
953 { bmdVideoConnectionComponent,
"Component"},
954 { bmdVideoConnectionComposite,
"Composite"},
955 { bmdVideoConnectionSVideo,
"SVideo"}
963 static constexpr BMDVideoInputConversionMode value =
964 bmdNoVideoInputConversion;
967 static constexpr BMDVideoOutputConversionMode value =
968 bmdNoVideoOutputConversion;
981 IDeckLinkDisplayModeIterator *displayModeIterator =
nullptr;
982 IDeckLinkDisplayMode *deckLinkDisplayMode =
nullptr;
985 deckLink->GetDisplayModeIterator(&displayModeIterator))) {
986 MSG(ERROR,
"Fatal: cannot create display mode iterator.\n");
990 while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) {
992 const HRESULT res = deckLink->DoesSupportVideoMode(
993 bmdVideoConnectionUnspecified,
994 deckLinkDisplayMode->GetDisplayMode(), pf,
996 nullptr, &supported);
997 deckLinkDisplayMode->Release();
999 MSG(WARNING,
"DoesSupportVideoMode: %s\n",
1004 displayModeIterator->Release();
1008 displayModeIterator->Release();
1022 MSG(WARNING,
"audio_level option is deprecated, use "
1023 "\"aacl[=true|false]\" instead\n");
1024 if (strcasecmp(opt,
"false") == 0 || strcasecmp(opt,
"off") == 0 ||
1025 strcasecmp(opt,
"line") == 0) {
1028 if (strcasecmp(opt,
"true") == 0 || strcasecmp(opt,
"on") == 0 ||
1029 strcasecmp(opt,
"mic") == 0) {
1032 throw invalid_argument(
string(
"invalid BMD audio level ") + opt);
1037 const char *query_prop_fcc)
1039 if (strcmp(query_prop_fcc,
"help") == 0) {
1040 col{} <<
"Query usage:\n"
1041 <<
SBOLD(
"\tq[uery]=<fcc>")
1042 <<
" - gets DeckLink attribute value\n";
1046 char fcc[
sizeof(BMDDeckLinkAttributeID)] = {
' ',
' ',
' ',
1048 BMDDeckLinkAttributeID
key;
1050 memcpy(fcc, query_prop_fcc,
min(strlen(query_prop_fcc),
sizeof fcc));
1051 key = (BMDDeckLinkAttributeID) htonl(
key);
1057 HRESULT result = deckLinkAttributes->GetFlag(
key, &bool_val);
1058 if (result == S_OK) {
1059 oss << (bool_val ?
"true" :
"false");
1061 if (result == E_INVALIDARG) {
1062 result = deckLinkAttributes->GetInt(
key, &int_val);
1063 if (result == S_OK) {
1064 oss << int_val <<
" (0x" << hex << int_val <<
")";
1067 if (result == E_INVALIDARG) {
1068 result = deckLinkAttributes->GetFloat(
key, &float_val);
1069 if (result == S_OK) {
1073 if (result == E_INVALIDARG) {
1074 result = deckLinkAttributes->GetString(
key, &string_val);
1075 if (result == S_OK) {
1081 if (result != S_OK) {
1083 <<
MOD_NAME <<
"Cannot get " << query_prop_fcc <<
": "
1087 col() <<
"\t" << hex <<
"Value of " <<
SBOLD(query_prop_fcc)
1088 <<
" attribute for this device is " <<
SBOLD(oss.str()) <<
"\n";
1108 IDeckLinkIterator *deckLinkIterator =
1110 if (deckLinkIterator ==
nullptr) {
1114 IDeckLink *deckLink =
nullptr;
1115 std::vector<bmd_dev> out;
1117 while (deckLinkIterator->Next(&deckLink) == S_OK) {
1118 IDeckLinkProfileAttributes *deckLinkAttributes =
nullptr;
1119 HRESULT result = E_FAIL;
1121 deckLink->QueryInterface(IID_IDeckLinkProfileAttributes,
1122 (
void **) &deckLinkAttributes);
1123 assert(result == S_OK);
1126 deckLinkAttributes->GetInt(BMDDeckLinkTopologicalID, &
id);
1127 if (result != S_OK) {
1128 id = UINT_MAX - idx;
1130 assert(
id >= 0 &&
id <= UINT_MAX);
1131 deckLinkAttributes->Release();
1133 auto release = [](IDeckLink *d) { d->Release(); };
1134 auto &it = out.emplace_back(
1135 std::unique_ptr<IDeckLink,
void (*)(IDeckLink *)>{
1136 deckLink, release },
1138 std::get<unsigned>(it) = id;
1139 std::get<int>(it) = idx++;
1141 deckLinkIterator->Release();
1142 if (!natural_sort) {
1144 return std::get<unsigned>(a) < std::get<unsigned>(b);
1149 for (
auto &d : out) {
1150 std::get<char>(d) = new_idx++;
1156 " Do not do conversion from/to limited range on in/out for R10k on BMD devs.\n");
1158 " Use the old BMD device sorting.\n");
const char unsigned int flags
#define STDMETHODCALLTYPE
static const map< BMDProfileID, pair< const char *, const char * > > kDeviceProfiles
bool bmd_parse_audio_levels(const char *opt) noexcept(false)
TOREMOVE (implicit "aacl" option is preferred)
static BMDProfileID GetDeckLinkProfileID(IDeckLinkProfile *profile)
BMD_STR get_bmd_api_str_from_cstr(const char *cstr)
template bool decklink_supports_codec< IDeckLinkOutput >(IDeckLinkOutput *deckLink, BMDPixelFormat pf)
static void fill_limited_to_full_lut(unsigned int *lut)
static void apply_r10k_lut(void *i, void *o, size_t len, void *udata)
bool blackmagic_api_version_check()
string bmd_get_flags_str(BMDDisplayModeFlags flags)
const map< BMDVideoConnection, string > & get_connection_string_map()
uint32_t bmd_read_fourcc(const char *str)
void print_bmd_device_profiles(const char *line_prefix)
static BMDProfileID decklink_get_active_profile_id(IDeckLink *decklink)
static string fcc_to_string(uint32_t fourcc)
std::ostream & operator<<(std::ostream &output, REFIID iid)
IDeckLinkIterator * create_decklink_iterator(bool *com_initialized, bool verbose)
void release_bmd_api_str(BMD_STR string)
void print_bmd_attribute(IDeckLinkProfileAttributes *deckLinkAttributes, const char *query_prop_fcc)
string bmd_hresult_to_string(HRESULT res)
string bmd_get_device_name(IDeckLink *decklink)
string bmd_get_audio_connection_name(BMDAudioOutputAnalogAESSwitch audioConnection)
void decklink_uninitialize(bool *com_initialized)
#define EXIT_IF_FAILED(cmd, name)
bool decklink_set_profile(IDeckLink *deckLink, bmd_option const &req_profile, bool stereo)
std::string get_str_from_bmd_api_str(BMD_STR string)
void r10k_full_to_limited(const char *in, char *out, size_t len)
bool bmd_check_stereo_profile(IDeckLink *deckLink)
template bool decklink_supports_codec< IDeckLinkInput >(IDeckLinkInput *deckLink, BMDPixelFormat pf)
#define RELEASE_IF_NOT_NULL(x)
std::vector< bmd_dev > bmd_get_sorted_devices(bool *com_initialized, bool verbose, bool natural_sort)
static void fill_full_to_limited_lut(unsigned int *lut)
bool decklink_supports_codec(T *deckLink, BMDPixelFormat pf)
void print_decklink_version()
char * get_cstr_from_bmd_api_str(BMD_STR bmd_string)
void r10k_limited_to_full(const char *in, char *out, size_t len)
BMD_STR get_bmd_api_str_from_cstr(const char *cstr)
const std::map< BMDVideoConnection, std::string > & get_connection_string_map()
#define BMD_CHECK(cmd, name, action)
std::string bmd_hresult_to_string(HRESULT res)
void release_bmd_api_str(BMD_STR string)
std::tuple< std::unique_ptr< IDeckLink, void(*)(IDeckLink *)>, unsigned, int, char > bmd_dev
uint32_t bmd_read_fourcc(const char *)
HRESULT ProfileActivated(IDeckLinkProfile *activatedProfile) override
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) override
IDeckLinkProfile * m_requestedProfile
std::condition_variable m_profileActivatedCondition
HRESULT ProfileChanging(IDeckLinkProfile *profileToBeActivated, BMD_BOOL streamsWillBeForcedToStop) override
bool WaitForProfileActivation(void)
ULONG STDMETHODCALLTYPE Release() override
virtual ~ProfileCallback()
bool m_requestedProfileActivated
ULONG STDMETHODCALLTYPE AddRef() override
std::mutex m_profileActivatedMutex
ProfileCallback(IDeckLinkProfile *requestedProfile)
int color_printf(const char *format,...)
static __device__ vec2 clamp(const vec2 &v, float min_val, float max_val)
void log_msg(int level, const char *format,...)
#define DEBUG_TIMER_START(name)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_INFO
normal reporting
#define DEBUG_TIMER_STOP(name)
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_WARNING
less severe errors
#define ADD_TO_PARAM(param, doc)
const char * get_string() const
void set_string(const char *val_)
enum bmd_option::type_tag m_type
bool m_user_specified
ignore errors if set to false
void set_int(int64_t val_)
bool device_write(IDeckLinkConfiguration *deckLinkConfiguration, BMDDeckLinkConfigurationID opt, std::string const &log_prefix="[DeckLink] ") const
union bmd_option::@11 m_val
void set_float(double val_)
bool com_initialize(bool *com_initialized, const char *err_prefix)
void com_uninitialize(bool *com_initialized)
#define HRESULT_GET_ERROR_COMMON(res, errptr)
void respawn_parallel(void *in, void *out, size_t nmemb, size_t size, respawn_parallel_callback_t c, void *udata)