1136{
1137 IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
1138 IDeckLinkDisplayMode* displayMode = NULL;
1139
1141
1142 bool com_initialized = false;
1146 if (!deviceName.empty() && deviceName ==
device_id.c_str()) {
1147 break;
1148 }
1149
1150
1151 const unsigned long tid =
1152 strtoul(
device_id.c_str(),
nullptr, 16);
1153 if (get<unsigned>(d) == tid) {
1154 break;
1155 }
1156
1158 if (atoi(
device_id.c_str()) == get<int>(d)) {
1159 break;
1160 }
1161 }
1162
1165 break;
1166 }
1167 }
1168
1169
1172 }
1173
1177 }
1178
1179
1181 if (!deviceName.empty()) {
1183 }
1184
1188 }
1189 }
1190
1191
1193
1194
1196
1199
1202 continue;
1203 }
1206 }
1207 }
1208 const BMDVideoInputConversionMode supported_conversion_mode = s->
device_options.find(bmdDeckLinkConfigVideoInputConversionMode) != s->
device_options.end() ? (BMDVideoInputConversionMode) s->
device_options.at(bmdDeckLinkConfigVideoInputConversionMode).get_int() : (BMDVideoInputConversionMode) bmdNoVideoInputConversion;
1211 }
1212
1213
1214 delegate = make_unique<VideoDelegate>(s, *
this);
1216
1217 BMDDisplayMode detectedDisplayMode = bmdModeUnknown;
1222 }
1223 }
1224
1225
1227 "Could not obtain the video input display mode iterator:",
INIT_ERR());
1228
1230
1231 int mnum = 0;
1232 enum { MODE_SPEC_AUTODETECT = -1, MODE_SPEC_FOURCC = -2, MODE_SPEC_DETECTED = -3 };
1233 int mode_idx = MODE_SPEC_AUTODETECT;
1234
1235
1236 if (s->
mode.length() > 0) {
1237 if (s->
mode.length() <= 2) {
1238 mode_idx = atoi(s->
mode.c_str());
1239 } else {
1240 mode_idx = MODE_SPEC_FOURCC;
1241 }
1242 }
1244 mode_idx = MODE_SPEC_DETECTED;
1245 }
1246
1247 while (displayModeIterator->Next(&displayMode) == S_OK) {
1248 if (mode_idx == MODE_SPEC_DETECTED) {
1249 if (detectedDisplayMode == displayMode->GetDisplayMode()) {
1250 break;
1251 } else {
1252 displayMode->Release();
1253 }
1254 } else if (mode_idx == MODE_SPEC_AUTODETECT) {
1255 if ((s->
stereo && (displayMode->GetFlags() & bmdDisplayModeSupports3D) == 0u) || displayMode->GetFieldDominance() == bmdLowerFieldFirst) {
1256 displayMode->Release();
1257 continue;
1258 }
1261 [&s](const std::pair<codec_t, BMDPixelFormat>& el){ return el.first == s->codec; });
1265 }
1266 BMDPixelFormat pf = it->second;
1269 ? (BMDVideoConnection) s->
device_options.at(bmdDeckLinkConfigVideoInputConnection).get_int() : (BMDVideoConnection) bmdVideoConnectionUnspecified;
1271 if (supported) {
1272 break;
1273 }
1274 } else if (mode_idx != MODE_SPEC_FOURCC) {
1275 if (mode_idx != mnum) {
1276 mnum++;
1277
1278 displayMode->Release();
1279 continue;
1280 }
1281
1282 mnum++;
1283 break;
1284 } else {
1286 break;
1287 }
1288 displayMode->Release();
1289 }
1290 }
1291
1292 if (displayMode) {
1293 BMD_STR displayModeString = NULL;
1294 if (HRESULT result = displayMode->GetName(&displayModeString); result == S_OK) {
1296 << "The desired display mode is supported: "
1298 << "\n";
1300 }
1301 } else {
1302 if (mode_idx == MODE_SPEC_FOURCC) {
1304 "Desired mode \"%s\" is invalid or not "
1305 "supported.\n",
1307 } else if (mode_idx >= 0) {
1308 MSG(ERROR,
"Desired mode index %s is out of bounds.\n", s->
mode.c_str());
1309 } else if (mode_idx == MODE_SPEC_AUTODETECT) {
1310 MSG(ERROR,
"Cannot set initial format for "
1311 "autodetection - perhaps imposible "
1312 "combinations of parameters were set.\n");
1313 } else {
1314 assert("Invalid mode spec." && 0);
1315 }
1317 }
1318
1319 BMDPixelFormat pf;
1321 "Could not set display mode properties",
INIT_ERR());
1322
1324
1325 if (mode_idx == MODE_SPEC_AUTODETECT) {
1326 MSG(INFO,
"Trying to autodetect format.\n");
1331 "Device doesn't support format autodetection, you "
1332 "must set it manually or try \"-t "
1333 "decklink:detect-format[:connection=<in>]\"\n");
1335 }
1337 }
1338
1341 ? (BMDVideoConnection) s->
device_options.at(bmdDeckLinkConfigVideoInputConnection).get_int() : (BMDVideoConnection) bmdVideoConnectionUnspecified;
1343
1344 if (!supported) {
1347 }
1348
1349 if (HRESULT result =
deckLinkInput->EnableVideoInput(displayMode->GetDisplayMode(), pf, s->
enable_flags); result != S_OK) {
1350 switch (result) {
1351 case E_INVALIDARG:
1353 break;
1354 case E_ACCESSDENIED:
1356 "stream currently active (another application using it?).\n");
1357 break;
1358 default:
1360 }
1362 }
1363
1366 } else {
1368 audioConnection) == S_OK) {
1369 const map<BMDAudioConnection, string>
mapping = {
1370 { bmdAudioConnectionEmbedded, "embedded" },
1371 { bmdAudioConnectionAESEBU, "AES/EBU" },
1372 { bmdAudioConnectionAnalog, "analog" },
1373 { bmdAudioConnectionAnalogXLR, "analogXLR" },
1374 { bmdAudioConnectionAnalogRCA, "analogRCA" },
1375 { bmdAudioConnectionMicrophone, "microphone" },
1376 { bmdAudioConnectionHeadphones, "headphones" },
1377 };
1379 } else {
1381
1382 }
1383 if (s->
audio.ch_count == 4 ||
1388 "DeckLink may not be able to grab %d audio "
1389 "channels. "
1390 "1, 2, 8, 16, 32 or 64 may work.\n",
1392 }
1394 bmdAudioSampleRate48kHz,
1396 ? bmdAudioSampleType16bitInteger
1397 : bmdAudioSampleType32bitInteger,
1398 max(s->
audio.ch_count, 2)),
1400 }
1401
1402
1404
1405 displayMode->Release();
1406 displayMode = NULL;
1407
1408 displayModeIterator->Release();
1409 displayModeIterator = NULL;
1410 return true;
1411}
const char * get_codec_name(codec_t codec)
static const struct codec_param mapping[AC_COUNT]
uint32_t bmd_read_fourcc(const char *str)
void release_bmd_api_str(BMD_STR string)
string bmd_hresult_to_string(HRESULT res)
string bmd_get_device_name(IDeckLink *decklink)
bool decklink_set_profile(IDeckLink *deckLink, bmd_option const &req_profile, bool stereo)
std::string get_str_from_bmd_api_str(BMD_STR string)
std::vector< bmd_dev > bmd_get_sorted_devices(bool *com_initialized, bool verbose, bool natural_sort)
#define BMD_CHECK(cmd, name, action)
static std::vector< std::pair< codec_t, BMDPixelFormat > > uv_to_bmd_codec_map
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
bool is_power_of_two(unsigned long long x)
IDeckLinkInput * deckLinkInput
void check_attributes(struct vidcap_decklink_state *s)
unique_ptr< VideoDelegate > delegate
IDeckLinkConfiguration * deckLinkConfiguration
IDeckLinkProfileAttributes * deckLinkAttributes
Struct tile is an area of video_frame.
map< BMDDeckLinkConfigurationID, bmd_option > device_options
BMDVideoInputFlags enable_flags
BMDSupportedVideoModeFlags supported_flags
bool keep_device_defaults
static bool detect_format(struct vidcap_decklink_state *s, BMDDisplayMode *outDisplayMode, struct device_state *device)
static HRESULT set_display_mode_properties(struct vidcap_decklink_state *s, struct tile *tile, IDeckLinkDisplayMode *displayMode, BMDPixelFormat *pf)
#define CALL_AND_CHECK(cmd,...)