UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
blackmagic_common.hpp File Reference
#include "DeckLinkAPI.h"
#include <cctype>
#include <cstdbool>
#include <cstdint>
#include <map>
#include <memory>
#include <tuple>
#include <vector>
#include <string>
#include <type_traits>
#include <utility>
#include "utils/macros.h"
#include "video.h"
Include dependency graph for blackmagic_common.hpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  bmd_option
 

Macros

#define BMD_BOOL   bool
 
#define BMD_CHECK(cmd, name, action)
 
#define BMD_FALSE   false
 
#define BMD_NAT_SORT   "bmd-sort-natural"
 
#define BMD_STR   const char *
 
#define BMD_TRUE   true
 
#define R10K_FULL_OPT   "bmd-r10k-full-range"
 

Typedefs

using bmd_dev
 

Enumerations

enum  { BMD_MAX_AUD_CH = 64 }
 

Functions

bool blackmagic_api_version_check ()
 
bool bmd_check_stereo_profile (IDeckLink *deckLink)
 
std::string bmd_get_audio_connection_name (BMDAudioOutputAnalogAESSwitch audioConnection)
 
std::string bmd_get_device_name (IDeckLink *decklink)
 
std::string bmd_get_flags_str (BMDDisplayModeFlags flags)
 
std::vector< bmd_dev > bmd_get_sorted_devices (bool *com_initialized, bool verbose=true, bool natural_sort=false)
 
std::string bmd_hresult_to_string (HRESULT res)
 
bool bmd_parse_audio_levels (const char *opt) noexcept(false)
 TOREMOVE (implicit "aacl" option is preferred)
 
uint32_t bmd_read_fourcc (const char *)
 
IDeckLinkIterator * create_decklink_iterator (bool *com_initialized, bool verbose=true)
 
bool decklink_set_profile (IDeckLink *deckLink, bmd_option const &req_profile, bool stereo)
 
template<typename T >
bool decklink_supports_codec (T *deckLink, BMDPixelFormat pf)
 
template bool decklink_supports_codec< IDeckLinkInput > (IDeckLinkInput *deckLink, BMDPixelFormat pf)
 
template bool decklink_supports_codec< IDeckLinkOutput > (IDeckLinkOutput *deckLink, BMDPixelFormat pf)
 
void decklink_uninitialize (bool *com_initialized)
 
BMD_STR get_bmd_api_str_from_cstr (const char *cstr)
 
const std::map< BMDVideoConnection, std::string > & get_connection_string_map ()
 
char * get_cstr_from_bmd_api_str (BMD_STR string)
 
std::string get_str_from_bmd_api_str (BMD_STR string)
 
std::ostream & operator<< (std::ostream &output, const bmd_option &b)
 
std::ostream & operator<< (std::ostream &output, REFIID iid)
 
void print_bmd_attribute (IDeckLinkProfileAttributes *deckLinkAttributes, const char *query_prop_fcc)
 
void print_bmd_device_profiles (const char *line_prefix)
 
void print_decklink_version (void)
 
void r10k_full_to_limited (const char *in, char *out, size_t len)
 
void r10k_limited_to_full (const char *in, char *out, size_t len)
 
void release_bmd_api_str (BMD_STR string)
 

Variables

static std::vector< std::pair< codec_t, BMDPixelFormat > > uv_to_bmd_codec_map
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file blackmagic_common.hpp.

Macro Definition Documentation

◆ BMD_BOOL

◆ BMD_CHECK

#define BMD_CHECK ( cmd,
name,
action )
Value:
do {\
HRESULT result = cmd;\
if (FAILED(result)) {;\
LOG(LOG_LEVEL_ERROR) << MOD_NAME << name << ": " << bmd_hresult_to_string(result) << "\n";\
action;\
}\
} while (0)
#define MOD_NAME
Definition audio.cpp:110
std::string bmd_hresult_to_string(HRESULT res)
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
const char * name
Definition settings.cpp:193
@ FAILED

Definition at line 157 of file blackmagic_common.hpp.

157#define BMD_CHECK(cmd, name, action) \
158 do {\
159 HRESULT result = cmd;\
160 if (FAILED(result)) {;\
161 LOG(LOG_LEVEL_ERROR) << MOD_NAME << name << ": " << bmd_hresult_to_string(result) << "\n";\
162 action;\
163 }\
164 } while (0)

Referenced by decklink_set_profile(), and device_state::init().

◆ BMD_FALSE

◆ BMD_NAT_SORT

#define BMD_NAT_SORT   "bmd-sort-natural"

Definition at line 168 of file blackmagic_common.hpp.

Referenced by decklink_help(), and show_help().

◆ BMD_STR

◆ BMD_TRUE

#define BMD_TRUE   true

Definition at line 82 of file blackmagic_common.hpp.

Referenced by display_decklink_init(), and display_decklink_reconfigure().

◆ R10K_FULL_OPT

#define R10K_FULL_OPT   "bmd-r10k-full-range"

Typedef Documentation

◆ bmd_dev

using bmd_dev
Initial value:
std::tuple<std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>,
unsigned, int, char>

parameters:

  • first - IDeckLinkInstance
  • unsigned - topological ID
  • int - natural idx (the old, order as given by IDeckLinkIterator)
  • char - new index ('a', 'b', 'c'...); sorted by topological ID

Definition at line 189 of file blackmagic_common.hpp.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
BMD_MAX_AUD_CH 

Definition at line 86 of file blackmagic_common.hpp.

86 {
87 BMD_MAX_AUD_CH = 64,
88};
@ BMD_MAX_AUD_CH

Function Documentation

◆ blackmagic_api_version_check()

bool blackmagic_api_version_check ( )

Definition at line 202 of file blackmagic_common.cpp.

203{
204 bool ret = false;
205 IDeckLinkAPIInformation *APIInformation = NULL;
206 HRESULT result;
207 bool com_initialized = false;
208
209 if (!com_initialize(&com_initialized, "[BMD] ")) {
210 goto cleanup;
211 }
212#ifdef _WIN32
213 result = CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
214 IID_IDeckLinkAPIInformation, (void **) &APIInformation);
215 if(FAILED(result)) {
216#else
217 APIInformation = CreateDeckLinkAPIInformationInstance();
218 if(APIInformation == NULL) {
219#endif
220 log_msg(LOG_LEVEL_ERROR, "Cannot get API information! Perhaps drivers not installed.\n");
221 goto cleanup;
222 }
223 int64_t value;
224 result = APIInformation->GetInt(BMDDeckLinkAPIVersion, &value);
225 if(result != S_OK) {
226 log_msg(LOG_LEVEL_ERROR, "Cannot get API version!\n");
227 goto cleanup;
228 }
229
230 if (BLACKMAGIC_DECKLINK_API_VERSION > value) { // this is safe comparision, for internal structure please see SDK documentation
231 log_msg(LOG_LEVEL_ERROR, "The DeckLink drivers may not be installed or are outdated.\n");
232 log_msg(LOG_LEVEL_ERROR, "You should have at least the version UltraGrid has been linked with.\n");
233 log_msg(LOG_LEVEL_ERROR, "Vendor download page is http://www.blackmagic-design.com/support\n");
235 ret = false;
236 } else {
237 ret = true;
238 }
239
240cleanup:
241 if (APIInformation) {
242 APIInformation->Release();
243 }
244 decklink_uninitialize(&com_initialized);
245
246 return ret;
247}
void decklink_uninitialize(bool *com_initialized)
void print_decklink_version()
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
static void cleanup()
Definition sdp.c:195
bool com_initialize(bool *com_initialized, const char *err_prefix)
Definition windows.c:65

References cleanup(), com_initialize(), decklink_uninitialize(), FAILED, LOG_LEVEL_ERROR, log_msg(), and print_decklink_version().

Referenced by display_decklink_init(), and vidcap_decklink_init().

Here is the call graph for this function:

◆ bmd_check_stereo_profile()

bool bmd_check_stereo_profile ( IDeckLink * deckLink)

Definition at line 509 of file blackmagic_common.cpp.

509 {
510 if (BMDProfileID profile_active = decklink_get_active_profile_id(deckLink)) {
511 if (profile_active != bmdProfileOneSubDeviceHalfDuplex &&
512 profile_active != bmdProfileOneSubDeviceFullDuplex) {
513 uint32_t profile_fcc_host = ntohl(profile_active);
514 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Active profile '%.4s' may not be compatible with stereo mode.\n", (char *) &profile_fcc_host);
515 log_msg(LOG_LEVEL_INFO, MOD_NAME "Use 'profile=' parameter to set 1-subdevice mode in either '1dhd' (half) or '1dfd' (full) duplex.\n");
516 }
517 return false;
518 }
519 return true;
520}
static BMDProfileID decklink_get_active_profile_id(IDeckLink *decklink)
#define MOD_NAME
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62

References decklink_get_active_profile_id(), LOG_LEVEL_ERROR, LOG_LEVEL_INFO, log_msg(), and MOD_NAME.

Referenced by device_state::check_attributes(), and display_decklink_reconfigure().

Here is the call graph for this function:

◆ bmd_get_audio_connection_name()

std::string bmd_get_audio_connection_name ( BMDAudioOutputAnalogAESSwitch audioConnection)

Definition at line 903 of file blackmagic_common.cpp.

903 {
904 switch(audioConnection) {
905 case bmdAudioOutputSwitchAESEBU:
906 return "AES/EBU";
907 case bmdAudioOutputSwitchAnalog:
908 return "analog";
909 default:
910 return "default";
911 }
912}

◆ bmd_get_device_name()

std::string bmd_get_device_name ( IDeckLink * decklink)

Definition at line 522 of file blackmagic_common.cpp.

522 {
523 BMD_STR deviceNameString = NULL;
524 char * deviceNameCString = NULL;
525 string ret;
526
527 if (decklink->GetDisplayName((BMD_STR *) &deviceNameString) == S_OK) {
528 deviceNameCString = get_cstr_from_bmd_api_str(deviceNameString);
529 ret = deviceNameCString;
530 release_bmd_api_str(deviceNameString);
531 free(deviceNameCString);
532 }
533
534 return ret;
535}
void release_bmd_api_str(BMD_STR string)
char * get_cstr_from_bmd_api_str(BMD_STR bmd_string)
#define BMD_STR

References BMD_STR, get_cstr_from_bmd_api_str(), and release_bmd_api_str().

Referenced by decklink_help(), display_decklink_init(), display_decklink_probe(), device_state::init(), show_help(), and vidcap_decklink_probe().

Here is the call graph for this function:

◆ bmd_get_flags_str()

std::string bmd_get_flags_str ( BMDDisplayModeFlags flags)

Definition at line 914 of file blackmagic_common.cpp.

914 {
915 bool first = true;
916 ostringstream oss;
917 vector<pair<uint32_t, const char *>> map {
918 { bmdDisplayModeColorspaceRec601, "Rec601" },
919 { bmdDisplayModeColorspaceRec709, "Rec709" },
920 { bmdDisplayModeColorspaceRec2020, "Rec2020" },
921 { bmdDisplayModeSupports3D, "3D" },
922 };
923
924 for (auto &f : map ) {
925 if (flags & f.first) {
926 oss << (!first ? ", " : "") << f.second;
927 first = false;
928 }
929 }
930 if (flags == 0) {
931 oss << "(none)";
932 }
933 if (flags >= bmdDisplayModeColorspaceRec2020 << 1) {
934 oss << ", (unknown flags)";
935 }
936 return oss.str();
937}
const char unsigned int flags
codec_t first
Definition sdl2.c:423

References first, and flags.

Referenced by get_input_modes(), and print_output_modes().

◆ bmd_get_sorted_devices()

std::vector< bmd_dev > bmd_get_sorted_devices ( bool * com_initialized,
bool verbose,
bool natural_sort )
Returns
list of DeckLink devices sorted (indexed) by topological ID If no topological ID is reported, use UINT_MAX (and lower vals)
Parameters
verbose- print errors
natural_sort- use the (old) natural sort as given by the iterator
Note
Each call of this function should be followed by com_uninitialize() when done with DeckLink. No BMD stuff originating from this function call (IDeckLinks) can be used after that and new call must be made.
The returned IDeckLink instances are managed with the unique_ptr, so take care about the returned object lifetime (particularly not to be destroyed after decklink_uninitialize()).

Definition at line 1106 of file blackmagic_common.cpp.

1107{
1108 IDeckLinkIterator *deckLinkIterator =
1109 create_decklink_iterator(com_initialized, verbose);
1110 if (deckLinkIterator == nullptr) {
1111 return {};
1112 }
1113
1114 IDeckLink *deckLink = nullptr;
1115 std::vector<bmd_dev> out;
1116 int idx = 0;
1117 while (deckLinkIterator->Next(&deckLink) == S_OK) {
1118 IDeckLinkProfileAttributes *deckLinkAttributes = nullptr;
1119 HRESULT result = E_FAIL;
1120 result =
1121 deckLink->QueryInterface(IID_IDeckLinkProfileAttributes,
1122 (void **) &deckLinkAttributes);
1123 assert(result == S_OK);
1124 int64_t id = 0;
1125 result =
1126 deckLinkAttributes->GetInt(BMDDeckLinkTopologicalID, &id);
1127 if (result != S_OK) {
1128 id = UINT_MAX - idx;
1129 }
1130 assert(id >= 0 && id <= UINT_MAX);
1131 deckLinkAttributes->Release();
1132
1133 auto release = [](IDeckLink *d) { d->Release(); };
1134 auto &it = out.emplace_back(
1135 std::unique_ptr<IDeckLink, void (*)(IDeckLink *)>{
1136 deckLink, release },
1137 0, 0, 0);
1138 std::get<unsigned>(it) = id;
1139 std::get<int>(it) = idx++;
1140 }
1141 deckLinkIterator->Release();
1142 if (!natural_sort) {
1143 std::sort(out.begin(), out.end(), [](bmd_dev &a, bmd_dev &b) {
1144 return std::get<unsigned>(a) < std::get<unsigned>(b);
1145 });
1146 }
1147 // assign new indices
1148 char new_idx = 'a';
1149 for (auto &d : out) {
1150 std::get<char>(d) = new_idx++;
1151 }
1152 return out;
1153}
IDeckLinkIterator * create_decklink_iterator(bool *com_initialized, bool verbose)
std::tuple< std::unique_ptr< IDeckLink, void(*)(IDeckLink *)>, unsigned, int, char > bmd_dev

References create_decklink_iterator().

Referenced by decklink_help(), display_decklink_init(), display_decklink_probe(), device_state::init(), show_help(), and vidcap_decklink_probe().

Here is the call graph for this function:

◆ bmd_hresult_to_string()

std::string bmd_hresult_to_string ( HRESULT res)

Definition at line 85 of file blackmagic_common.cpp.

86{
87 const char *errptr = nullptr;
88#ifdef _WIN32
89 errptr = hresult_to_str(res);
90#else
91 HRESULT_GET_ERROR_COMMON(res, errptr)
92#endif
93 ostringstream oss;
94 if (errptr) {
95 oss << errptr;
96 }
97 oss << " " << "(0x" << hex << setfill('0') << setw(8) << res << ")";
98 return oss.str();
99}
#define HRESULT_GET_ERROR_COMMON(res, errptr)
Definition windows.h:60

References HRESULT_GET_ERROR_COMMON.

Referenced by decklink_get_active_profile_id(), decklink_set_profile(), decklink_supports_codec(), bmd_option::device_write(), display_decklink_init(), display_decklink_reconfigure(), get_input_modes(), GetDeckLinkProfileID(), device_state::init(), print_bmd_attribute(), set_audio_props(), set_display_mode_properties(), vidcap_decklink_done(), and VideoDelegate::VideoInputFormatChanged().

◆ bmd_parse_audio_levels()

bool bmd_parse_audio_levels ( const char * opt)

TOREMOVE (implicit "aacl" option is preferred)

Definition at line 1020 of file blackmagic_common.cpp.

1021{
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) {
1026 return false;
1027 }
1028 if (strcasecmp(opt, "true") == 0 || strcasecmp(opt, "on") == 0 ||
1029 strcasecmp(opt, "mic") == 0) {
1030 return true;
1031 }
1032 throw invalid_argument(string("invalid BMD audio level ") + opt);
1033}
#define MSG(l, fmt,...)
Definition debug.h:96

References MSG.

Referenced by parse_option(), and settings_init().

◆ bmd_read_fourcc()

uint32_t bmd_read_fourcc ( const char * str)

Definition at line 537 of file blackmagic_common.cpp.

537 {
538 union {
539 uint32_t fourcc;
540 char c4[4];
541 } u;
542 memset(u.c4, ' ', 4);
543 memcpy(u.c4, str, min(strlen(str), sizeof u.c4));
544 return htonl(u.fourcc);
545}

Referenced by device_state::init(), bmd_option::parse(), parse_option(), and settings_init().

◆ create_decklink_iterator()

IDeckLinkIterator * create_decklink_iterator ( bool * com_initialized,
bool verbose )
Parameters
[out]com_initializedpointer to be passed to decklnk_uninitialize (keeps information if COM needs to be unintialized)
Note
Each successful call (returning non-null pointer) of this function should be followed by com_uninitialize() when done with DeckLink (not when releasing IDeckLinkIterator!), typically on application shutdown.

Definition at line 171 of file blackmagic_common.cpp.

172{
173 IDeckLinkIterator *deckLinkIterator = nullptr;
174#ifdef _WIN32
175 com_initialize(com_initialized, "[BMD] ");
176 HRESULT result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL,
177 IID_IDeckLinkIterator, (void **) &deckLinkIterator);
178 if (FAILED(result)) {
179 decklink_uninitialize(com_initialized);
180 deckLinkIterator = nullptr;
181 }
182#else
183 *com_initialized = false;
184 deckLinkIterator = CreateDeckLinkIteratorInstance();
185#endif
186
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);
191
192 }
193
194 return deckLinkIterator;
195}

References com_initialize(), decklink_uninitialize(), FAILED, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, and log_msg().

Referenced by bmd_get_sorted_devices().

Here is the call graph for this function:

◆ decklink_set_profile()

bool decklink_set_profile ( IDeckLink * deckLink,
bmd_option const & req_profile,
bool stereo )
Parameters
avalue from BMDProfileID or bmdDuplexHalf (maximize number of IOs)

Definition at line 399 of file blackmagic_common.cpp.

399 {
400 if (req_profile.is_default() && !stereo) {
401 return true;
402 }
403
404 if (req_profile.is_help()) {
405 printf("Available profiles:\n");
407 return false;
408 }
409
410 bool ret = true;
411 IDeckLinkProfileManager *manager = nullptr;
412 IDeckLinkProfileIterator *it = nullptr;
413 IDeckLinkProfile *profile = nullptr;
414 bool found = false;
415 ProfileCallback *p = nullptr;
416
417 if (HRESULT res = deckLink->QueryInterface(IID_IDeckLinkProfileManager, (void**)&manager)) {
418 const bool error = !(req_profile.is_default() && res == E_NOINTERFACE);
419 LOG(error ? LOG_LEVEL_ERROR : LOG_LEVEL_VERBOSE) << MOD_NAME << "Cannot set duplex - query profile manager: " << bmd_hresult_to_string(res) << "\n";
420 return error;
421 }
422
423 // set '1dfd' for stereo if profile is not set explicitly
424 assert(!req_profile.is_default() || stereo);
425 const uint32_t profileID = req_profile.is_default() ? (int64_t) bmdProfileOneSubDeviceFullDuplex : req_profile.get_int();
426
427 EXIT_IF_FAILED(manager->GetProfiles(&it), "Cannot set duplex - get profiles");
428
429 while (it->Next(&profile) == S_OK) {
430 IDeckLinkProfileAttributes *attributes;
431 int64_t id;
432 if (profile->QueryInterface(IID_IDeckLinkProfileAttributes,
433 (void**)&attributes) != S_OK) {
434 LOG(LOG_LEVEL_WARNING) << "[DeckLink] Cannot get profile attributes!\n";
435 continue;
436 }
437 if (attributes->GetInt(BMDDeckLinkProfileID, &id) == S_OK) {
438 if (profileID == bmdDuplexHalf) {
439 if (id == bmdProfileTwoSubDevicesHalfDuplex || id == bmdProfileFourSubDevicesHalfDuplex) {
440 found = true;
441 }
442 } else if (profileID == id) {
443 found = true;
444 }
445 if (found) {
446 p = new ProfileCallback(profile);
447 BMD_CHECK(manager->SetCallback(p), "IDeckLinkProfileManager::SetCallback", goto cleanup);
448 if (profile->SetActive() != S_OK) {
449 LOG(LOG_LEVEL_ERROR) << "[DeckLink] Cannot set profile!\n";
450 ret = false;
451 }
452 if (!p->WaitForProfileActivation()) {
453 ret = false;
454 }
455 }
456 } else {
457 LOG(LOG_LEVEL_WARNING) << "[DeckLink] Cannot get profile ID!\n";
458 }
459 attributes->Release();
460 profile->Release();
461 if (found) {
462 break;
463 }
464 }
465
466 if (!found && ret) { // no err but not found
467 LOG(LOG_LEVEL_WARNING) << "[DeckLink] did not find suitable duplex profile!\n";
468 ret = false;
469 }
470
471cleanup:
474 RELEASE_IF_NOT_NULL(manager);
475 return ret;
476}
void print_bmd_device_profiles(const char *line_prefix)
string bmd_hresult_to_string(HRESULT res)
#define EXIT_IF_FAILED(cmd, name)
#define RELEASE_IF_NOT_NULL(x)
#define BMD_CHECK(cmd, name, action)
bool WaitForProfileActivation(void)
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
#define LOG(level)
Definition debug.h:313
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60

References BMD_CHECK, bmd_hresult_to_string(), cleanup(), EXIT_IF_FAILED, bmd_option::get_int(), bmd_option::is_default(), bmd_option::is_help(), LOG, LOG_LEVEL_ERROR, LOG_LEVEL_VERBOSE, LOG_LEVEL_WARNING, MOD_NAME, print_bmd_device_profiles(), RELEASE_IF_NOT_NULL, and ProfileCallback::WaitForProfileActivation().

Referenced by display_decklink_init(), display_decklink_reconfigure(), and device_state::init().

Here is the call graph for this function:

◆ decklink_supports_codec()

template<typename T >
bool decklink_supports_codec ( T * deckLink,
BMDPixelFormat pf )

This function returns true if any display mode and any output supports the codec. The codec, however, may not be supported with actual video mode.

Todo
For UltraStudio Pro DoesSupportVideoMode returns E_FAIL on not supported pixel formats instead of setting supported to false.

Definition at line 979 of file blackmagic_common.cpp.

980{
981 IDeckLinkDisplayModeIterator *displayModeIterator = nullptr;
982 IDeckLinkDisplayMode *deckLinkDisplayMode = nullptr;
983
984 if (FAILED(
985 deckLink->GetDisplayModeIterator(&displayModeIterator))) {
986 MSG(ERROR, "Fatal: cannot create display mode iterator.\n");
987 return false;
988 }
989
990 while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) {
991 BMD_BOOL supported = false;
992 const HRESULT res = deckLink->DoesSupportVideoMode(
993 bmdVideoConnectionUnspecified,
994 deckLinkDisplayMode->GetDisplayMode(), pf,
995 bmd_no_conv<T>::value, bmdSupportedVideoModeDefault,
996 nullptr, &supported);
997 deckLinkDisplayMode->Release();
998 if (res != S_OK) {
999 MSG(WARNING, "DoesSupportVideoMode: %s\n",
1000 bmd_hresult_to_string(res).c_str());
1001 continue;
1002 }
1003 if (supported) {
1004 displayModeIterator->Release();
1005 return true;
1006 }
1007 }
1008 displayModeIterator->Release();
1009
1010 return false;
1011}
#define BMD_BOOL

References BMD_BOOL, bmd_hresult_to_string(), FAILED, and MSG.

Referenced by display_decklink_get_property(), print_output_modes(), and vidcap_decklink_print_card_info().

Here is the call graph for this function:

◆ decklink_supports_codec< IDeckLinkInput >()

template bool decklink_supports_codec< IDeckLinkInput > ( IDeckLinkInput * deckLink,
BMDPixelFormat pf )
extern

◆ decklink_supports_codec< IDeckLinkOutput >()

template bool decklink_supports_codec< IDeckLinkOutput > ( IDeckLinkOutput * deckLink,
BMDPixelFormat pf )
extern

◆ decklink_uninitialize()

void decklink_uninitialize ( bool * com_initialized)
Parameters
com_initialized- pointer passed to create_decklink_iterator

Definition at line 197 of file blackmagic_common.cpp.

198{
199 com_uninitialize(com_initialized);
200}
void com_uninitialize(bool *com_initialized)
Definition windows.c:94

References com_uninitialize().

Referenced by blackmagic_api_version_check(), create_decklink_iterator(), decklink_help(), display_decklink_done(), display_decklink_probe(), show_help(), and vidcap_decklink_probe().

Here is the call graph for this function:

◆ get_bmd_api_str_from_cstr()

BMD_STR get_bmd_api_str_from_cstr ( const char * cstr)

Definition at line 125 of file blackmagic_common.cpp.

126{
127#ifdef __APPLE__
128 return CFStringCreateWithCString(kCFAllocatorMalloc, cstr, kCFStringEncodingUTF8);
129#elif defined _WIN32
130 mbstate_t mbstate{};
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);
135 return out;
136#else
137 return strdup(cstr);
138#endif
139}

References BMD_STR.

Referenced by bmd_option::device_write().

◆ get_connection_string_map()

const std::map< BMDVideoConnection, std::string > & get_connection_string_map ( )

Definition at line 948 of file blackmagic_common.cpp.

948 {
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"}
956 };
957 return m;
958}

Referenced by bmd_option::device_write(), parse_option(), vidcap_decklink_print_card_info(), and vidcap_decklink_probe().

◆ get_cstr_from_bmd_api_str()

char * get_cstr_from_bmd_api_str ( BMD_STR bmd_string)

returned c-sring needs to be freed when not used

Definition at line 104 of file blackmagic_common.cpp.

105{
106 if (!bmd_string) {
107 return strdup("(NULL!)");
108 }
109 char *cstr;
110#ifdef __APPLE__
111 size_t len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(bmd_string), kCFStringEncodingUTF8) + 1;
112 cstr = (char *) malloc(len);
113 CFStringGetCString(bmd_string, (char *) cstr, len, kCFStringEncodingUTF8);
114#elif defined _WIN32
115 size_t len = SysStringLen(bmd_string) * 4 + 1;
116 cstr = (char *) malloc(len);
117 wcstombs((char *) cstr, bmd_string, len);
118#else // Linux
119 cstr = strdup(bmd_string);
120#endif
121
122 return cstr;
123}
int void size_t * len

References len.

Referenced by bmd_get_device_name(), get_str_from_bmd_api_str(), and print_decklink_version().

◆ get_str_from_bmd_api_str()

std::string get_str_from_bmd_api_str ( BMD_STR string)

Definition at line 155 of file blackmagic_common.cpp.

156{
157 char *displayModeCString = get_cstr_from_bmd_api_str(string);
158 std::string out = displayModeCString;
159 free(displayModeCString);
160 return out;
161}

References get_cstr_from_bmd_api_str().

Referenced by get_input_modes(), get_mode(), device_state::init(), print_bmd_attribute(), print_output_modes(), and set_display_mode_properties().

Here is the call graph for this function:

◆ operator<<() [1/2]

std::ostream & operator<< ( std::ostream & output,
const bmd_option & b )

Definition at line 100 of file blackmagic_common.cpp.

620 {
621 switch (b.m_type) {
623 output << "(default)";
624 break;
626 output << "(keep)";
627 break;
629 output << (b.get_flag() ? "true" : "false");
630 break;
632 if (IS_FCC(b.get_int())) {
633 output << fcc_to_string(b.get_int());
634 } else if (b.get_int() >= 0) {
635 auto flags = output.flags();
636 output << b.get_int() << " (0x" << hex
637 << b.get_int() << ")";
638 output.flags(flags);
639 } else {
640 output << b.get_int();
641 }
642 break;
644 auto flags = output.flags();
645 output << fixed << b.m_val.f;
646 output.flags(flags);
647 break;
648 }
650 output << b.m_val.s;
651 break;
652 }
653 return output;
654}
static string fcc_to_string(uint32_t fourcc)
#define IS_FCC(val)
Definition macros.h:116
int64_t get_int() const
enum bmd_option::type_tag m_type
bool get_flag() const
union bmd_option::@11 m_val

◆ operator<<() [2/2]

std::ostream & operator<< ( std::ostream & output,
REFIID iid )

Definition at line 547 of file blackmagic_common.cpp.

548{
549#ifdef _WIN32
550 OLECHAR* guidString;
551 StringFromCLSID(iid, &guidString);
552 char buffer[128];
553 int ret = wcstombs(buffer, guidString, sizeof buffer);
554 if (ret == sizeof buffer) {
555 buffer[sizeof buffer - 1] = '\0';
556 }
557 output << buffer;
558 ::CoTaskMemFree(guidString);
559#else
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);
570 output.flags(flags);
571#endif
572 return output;
573}

References flags.

◆ print_bmd_attribute()

void print_bmd_attribute ( IDeckLinkProfileAttributes * deckLinkAttributes,
const char * query_prop_fcc )

Definition at line 1036 of file blackmagic_common.cpp.

1038{
1039 if (strcmp(query_prop_fcc, "help") == 0) {
1040 col{} << "Query usage:\n"
1041 << SBOLD("\tq[uery]=<fcc>")
1042 << " - gets DeckLink attribute value\n";
1043 return;
1044 }
1045 union {
1046 char fcc[sizeof(BMDDeckLinkAttributeID)] = { ' ', ' ', ' ',
1047 ' ' };
1048 BMDDeckLinkAttributeID key;
1049 };
1050 memcpy(fcc, query_prop_fcc, min(strlen(query_prop_fcc), sizeof fcc));
1051 key = (BMDDeckLinkAttributeID) htonl(key);
1052 BMD_BOOL bool_val{};
1053 int64_t int_val{};
1054 double float_val{};
1055 BMD_STR string_val{};
1056 ostringstream oss;
1057 HRESULT result = deckLinkAttributes->GetFlag(key, &bool_val);
1058 if (result == S_OK) {
1059 oss << (bool_val ? "true" : "false");
1060 }
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 << ")";
1065 }
1066 }
1067 if (result == E_INVALIDARG) {
1068 result = deckLinkAttributes->GetFloat(key, &float_val);
1069 if (result == S_OK) {
1070 oss << float_val;
1071 }
1072 }
1073 if (result == E_INVALIDARG) {
1074 result = deckLinkAttributes->GetString(key, &string_val);
1075 if (result == S_OK) {
1076 string str = get_str_from_bmd_api_str(string_val);
1077 release_bmd_api_str(string_val);
1078 oss << str;
1079 }
1080 }
1081 if (result != S_OK) {
1083 << MOD_NAME << "Cannot get " << query_prop_fcc << ": "
1084 << bmd_hresult_to_string(result) << "\n";
1085 return;
1086 }
1087 col() << "\t" << hex << "Value of " << SBOLD(query_prop_fcc)
1088 << " attribute for this device is " << SBOLD(oss.str()) << "\n";
1089}
std::string get_str_from_bmd_api_str(BMD_STR string)
#define SBOLD(x)
Definition color_out.h:80
#define min(a, b)
Definition rtp.c:99
const char * key
Definition cineform.cpp:125

References BMD_BOOL, bmd_hresult_to_string(), BMD_STR, get_str_from_bmd_api_str(), key, LOG, LOG_LEVEL_ERROR, min, MOD_NAME, release_bmd_api_str(), and SBOLD.

Referenced by print_output_modes(), and vidcap_decklink_print_card_info().

Here is the call graph for this function:

◆ print_bmd_device_profiles()

void print_bmd_device_profiles ( const char * line_prefix)

Definition at line 939 of file blackmagic_common.cpp.

940{
941 for (const auto &p : kDeviceProfiles) {
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);
944 }
945 color_printf("%s" TBOLD("keep") " - keep device setting\n", line_prefix);
946}
static const map< BMDProfileID, pair< const char *, const char * > > kDeviceProfiles
int color_printf(const char *format,...)
#define TBOLD(x)
Definition color_out.h:70

References color_printf(), kDeviceProfiles, and TBOLD.

Referenced by decklink_help(), decklink_set_profile(), and show_help().

Here is the call graph for this function:

◆ print_decklink_version()

void print_decklink_version ( void )

Definition at line 249 of file blackmagic_common.cpp.

250{
251 BMD_STR current_version = NULL;
252 IDeckLinkAPIInformation *APIInformation = NULL;
253 HRESULT result;
254
255#ifdef _WIN32
256 bool com_initialized = false;
257 if (!com_initialize(&com_initialized, "[BMD] ")) {
258 goto cleanup;
259 }
260
261 result = CoCreateInstance(CLSID_CDeckLinkAPIInformation, NULL, CLSCTX_ALL,
262 IID_IDeckLinkAPIInformation, (void **) &APIInformation);
263 if(FAILED(result)) {
264#else
265 APIInformation = CreateDeckLinkAPIInformationInstance();
266 if(APIInformation == NULL) {
267#endif
268 fprintf(stderr, "Cannot get API information! Perhaps drivers not installed.\n");
269 goto cleanup;
270 }
271
272 result = APIInformation->GetString(BMDDeckLinkAPIVersion, &current_version);
273 if (result != S_OK) {
274 fprintf(stderr, "Cannot get API version string!\n");
275 goto cleanup;
276 } else {
277 fprintf(stderr, "This UltraGrid version was compiled against DeckLink SDK %s. ", BLACKMAGIC_DECKLINK_API_VERSION_STRING);
278 const char *currentVersionCString = get_cstr_from_bmd_api_str(current_version);
279 fprintf(stderr, "System version is %s.\n", currentVersionCString);
280 release_bmd_api_str(current_version);
281 free(const_cast<char *>(currentVersionCString));
282 }
283
284cleanup:
285 if (APIInformation) {
286 APIInformation->Release();
287 }
288#ifdef _WIN32
289 com_uninitialize(&com_initialized);
290#endif
291}

References BMD_STR, cleanup(), com_initialize(), com_uninitialize(), FAILED, get_cstr_from_bmd_api_str(), and release_bmd_api_str().

Referenced by blackmagic_api_version_check(), decklink_help(), and show_help().

Here is the call graph for this function:

◆ r10k_full_to_limited()

void r10k_full_to_limited ( const char * in,
char * out,
size_t len )

converts from full range (4-1019) to 64-960

in and out pointers can point to the same address

Definition at line 892 of file blackmagic_common.cpp.

893{
894 static unsigned int lut[1024];
895 if (lut[1023] == 0) {
897 }
899 respawn_parallel(const_cast<char *>(in), out, len / 4, 4, apply_r10k_lut, lut);
901}
static void apply_r10k_lut(void *i, void *o, size_t len, void *udata)
static void fill_full_to_limited_lut(unsigned int *lut)
void r10k_limited_to_full(const char *in, char *out, size_t len)
#define DEBUG_TIMER_START(name)
Definition debug.h:324
#define DEBUG_TIMER_STOP(name)
Definition debug.h:325
void respawn_parallel(void *in, void *out, size_t nmemb, size_t size, respawn_parallel_callback_t c, void *udata)
Definition worker.cpp:332

References apply_r10k_lut(), DEBUG_TIMER_START, DEBUG_TIMER_STOP, fill_full_to_limited_lut(), len, r10k_limited_to_full(), and respawn_parallel().

Referenced by display_decklink_putf().

Here is the call graph for this function:

◆ r10k_limited_to_full()

void r10k_limited_to_full ( const char * in,
char * out,
size_t len )

converts from range 64-960 to 4-1019

in and out pointers can point to the same address

Definition at line 869 of file blackmagic_common.cpp.

870{
871 static unsigned int lut[1024];
872 if (lut[1023] == 0) {
874 }
876 respawn_parallel(const_cast<char *>(in), out, len / 4, 4, apply_r10k_lut, lut);
878}
static void fill_limited_to_full_lut(unsigned int *lut)

References apply_r10k_lut(), DEBUG_TIMER_START, DEBUG_TIMER_STOP, fill_limited_to_full_lut(), len, r10k_limited_to_full(), and respawn_parallel().

Referenced by postprocess_frame(), r10k_full_to_limited(), and r10k_limited_to_full().

Here is the call graph for this function:

◆ release_bmd_api_str()

void release_bmd_api_str ( BMD_STR string)

Definition at line 141 of file blackmagic_common.cpp.

142{
143 if (!string) {
144 return;
145 }
146#ifdef __APPLE__
147 CFRelease(string);
148#elif defined _WIN32
149 SysFreeString(string);
150#else
151 free(const_cast<char *>(string));
152#endif
153}

Referenced by bmd_get_device_name(), bmd_option::device_write(), get_input_modes(), get_mode(), device_state::init(), print_bmd_attribute(), print_decklink_version(), print_output_modes(), and set_display_mode_properties().

Variable Documentation

◆ uv_to_bmd_codec_map

std::vector<std::pair<codec_t, BMDPixelFormat> > uv_to_bmd_codec_map
static
Initial value:
= {
{ R12L, bmdFormat12BitRGBLE },
{ R10k, bmdFormat10BitRGBX },
{ v210, bmdFormat10BitYUV },
{ RGBA, bmdFormat8BitBGRA },
{ UYVY, bmdFormat8BitYUV },
}
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75

Definition at line 68 of file blackmagic_common.hpp.

68 {
69 { R12L, bmdFormat12BitRGBLE },
70 { R10k, bmdFormat10BitRGBX },
71 { v210, bmdFormat10BitYUV },
72 { RGBA, bmdFormat8BitBGRA },
73 { UYVY, bmdFormat8BitYUV },
74};

Referenced by decklink_help(), display_decklink_get_property(), display_decklink_reconfigure(), device_state::init(), print_output_modes(), set_display_mode_properties(), show_help(), and vidcap_decklink_print_card_info().