diff --git a/src/blackmagic_common.h b/src/blackmagic_common.h index 530fcb01c..88159b9ca 100644 --- a/src/blackmagic_common.h +++ b/src/blackmagic_common.h @@ -107,10 +107,11 @@ int invert_bmd_flag(int val); std::ostream &operator<<(std::ostream &output, REFIID iid); +/// @param type - Int of Flag /// @param fatal - exit if failed to set (usually set to true for explicit settings, false implicit) -#define BMD_CONFIG_SET_INT(key, val, fatal) do {\ +#define BMD_CONFIG_SET(type, key, val, fatal) do {\ if (val != (decltype(val)) BMD_OPT_DEFAULT && val != (decltype(val)) BMD_OPT_KEEP) {\ - HRESULT result = deckLinkConfiguration->SetInt(key, val);\ + HRESULT result = deckLinkConfiguration->Set##type(key, val);\ if (result != S_OK) {\ LOG(fatal ? LOG_LEVEL_ERROR : LOG_LEVEL_WARNING) << MOD_NAME << "Unable to set " #key ": " << bmd_hresult_to_string(result) << "\n";\ if (fatal) { \ diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index 0a5dfab3f..e80d3b56d 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -178,6 +178,7 @@ struct vidcap_decklink_state { uint32_t profile{}; // BMD_OPT_DEFAULT, BMD_OPT_KEEP, bmdDuplexHalf or one of BMDProfileID uint32_t link = 0; /// @deprecated TOREMOVE? It sets output link configuration, not input thus it should not be used here. bool nosig_send = false; ///< send video even when no signal detected + bool keep_device_defaults = false; }; static HRESULT set_display_mode_properties(struct vidcap_decklink_state *s, struct tile *tile, IDeckLinkDisplayMode* displayMode, /* out */ BMDPixelFormat *pf); @@ -528,6 +529,9 @@ decklink_help(bool full) cout << style::bold << "sync_timecode" << style::reset << "\n"; cout << "\tTry to synchronize inputs based on timecode (for multiple inputs, eg. tiled 4K)\n"; cout << "\n"; + cout << style::bold << "keep-settings" << style::reset << "\n\tdo not apply any DeckLink settings by UG than required (keep user-selected defaults)\n"; + cout << "\n"; + } else { cout << "(other options available, use \"fullhelp\" to see complete list of options)\n\n"; } @@ -698,6 +702,8 @@ static bool parse_option(struct vidcap_decklink_state *s, const char *opt) s->link = bmdLinkConfigurationQuadLink; } else if (strcasecmp(opt, "nosig-send") == 0) { s->nosig_send = true; + } else if (strstr(opt, "keep-settings") == opt) { + s->keep_device_defaults = true; } else { log_msg(LOG_LEVEL_WARNING, "[DeckLink] Warning, unrecognized trailing options in init string: %s\n", opt); return false; @@ -1089,12 +1095,13 @@ vidcap_decklink_init(struct vidcap_params *params, void **state) } if (s->link == bmdLinkConfigurationQuadLink) { - if (s->profile == BMD_OPT_DEFAULT) { - LOG(LOG_LEVEL_WARNING) << MOD_NAME "Quad-link detected - setting 1-subdevice-1/2-duplex profile automatically, use 'profile=keep' to override.\n"; - s->profile = bmdProfileOneSubDeviceHalfDuplex; - } else if (s->profile != BMD_OPT_KEEP && s->profile != bmdProfileOneSubDeviceHalfDuplex) { - LOG(LOG_LEVEL_WARNING) << MOD_NAME "Setting quad-link and profile other than 1-subdevice-1/2-duplex may not be supported!\n"; - } + if (!s->keep_device_defaults && s->profile == BMD_OPT_DEFAULT) { + LOG(LOG_LEVEL_WARNING) << MOD_NAME "Quad-link detected - setting 1-subdevice-1/2-duplex profile automatically, use 'profile=keep' to override.\n"; + s->profile = bmdProfileOneSubDeviceHalfDuplex; + } + if (s->profile > 0 && s->profile != bmdProfileOneSubDeviceHalfDuplex) { + LOG(LOG_LEVEL_WARNING) << MOD_NAME "Setting quad-link and profile other than 1-subdevice-1/2-duplex may not be supported!\n"; + } } switch (get_bits_per_component(s->codec)) { @@ -1174,7 +1181,7 @@ vidcap_decklink_init(struct vidcap_params *params, void **state) LOG(LOG_LEVEL_INFO) << "Using device " << deviceName << "\n"; } - if (s->profile != BMD_OPT_DEFAULT && s->profile != BMD_OPT_KEEP) { + if (!s->keep_device_defaults && s->profile != BMD_OPT_DEFAULT && s->profile != BMD_OPT_KEEP) { decklink_set_duplex(s->state[i].deckLink, s->profile); } @@ -1190,10 +1197,10 @@ vidcap_decklink_init(struct vidcap_params *params, void **state) EXIT_IF_FAILED(deckLinkInput->QueryInterface(IID_IDeckLinkProfileAttributes, (void**)&deckLinkAttributes), "Could not query device attributes"); s->state[i].deckLinkAttributes = deckLinkAttributes; - BMD_CONFIG_SET_INT(bmdDeckLinkConfigVideoInputConnection, s->connection, true); - BMD_CONFIG_SET_INT(bmdDeckLinkConfigVideoInputConversionMode, s->conversion_mode, true); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigVideoInputConnection, s->connection, true); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigVideoInputConversionMode, s->conversion_mode, true); BMDVideoInputConversionMode supported_conversion_mode = s->conversion_mode ? s->conversion_mode : (BMDVideoInputConversionMode) bmdNoVideoInputConversion; - BMD_CONFIG_SET_INT(bmdDeckLinkConfigCapturePassThroughMode, s->passthrough, false); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigCapturePassThroughMode, s->passthrough, false); if (s->link != 0) { LOG(LOG_LEVEL_WARNING) << MOD_NAME << "Setting output link configuration on capture is deprecated and will be removed in future, let us know if this is needed!\n"; diff --git a/src/video_display/decklink.cpp b/src/video_display/decklink.cpp index cd7698df1..6e0eec033 100644 --- a/src/video_display/decklink.cpp +++ b/src/video_display/decklink.cpp @@ -356,6 +356,7 @@ struct state_decklink { bool low_latency = true; mutex reconfiguration_lock; ///< for audio and video reconf to be mutually exclusive + bool keep_device_defaults = false; }; static void show_help(bool full); @@ -411,6 +412,7 @@ static void show_help(bool full) << style::bold << "2dhd" << style::reset << " or " << style::bold << "4dhd" << style::reset << ". See SDK manual for details. Use " << style::bold << "keep" << style::reset << " to disable automatic selection.\n"; + cout << style::bold << "\tkeep-settings" << style::reset << "\tdo not apply any DeckLink settings by UG than required (keep user-selected defaults)\n"; } cout << "Recognized pixel formats:"; @@ -788,7 +790,7 @@ display_decklink_reconfigure_video(void *state, struct video_desc desc) uint32_t link = s->link_req; - if (s->link_req == BMD_OPT_DEFAULT) { + if (!s->keep_device_defaults && s->link_req == BMD_OPT_DEFAULT) { if (desc.width != 7680) { link = bmdLinkConfigurationSingleLink; LOG(LOG_LEVEL_NOTICE) << MOD_NAME "Setting single link by default.\n"; @@ -799,7 +801,7 @@ display_decklink_reconfigure_video(void *state, struct video_desc desc) } CALL_AND_CHECK(s->state.at(i).deckLinkConfiguration->SetInt(bmdDeckLinkConfigSDIOutputLinkConfiguration, link), "Unable set output SDI link mode"); - if (s->profile_req == BMD_OPT_DEFAULT && link == bmdLinkConfigurationQuadLink) { + if (!s->keep_device_defaults && s->profile_req == BMD_OPT_DEFAULT && link == bmdLinkConfigurationQuadLink) { LOG(LOG_LEVEL_WARNING) << MOD_NAME "Quad-link detected - setting 1-subdevice-1/2-duplex profile automatically, use 'profile=keep' to override.\n"; decklink_set_duplex(s->state.at(i).deckLink, bmdProfileOneSubDeviceHalfDuplex); } else if (link == bmdLinkConfigurationQuadLink && (s->profile_req != BMD_OPT_KEEP && s->profile_req == bmdProfileOneSubDeviceHalfDuplex)) { @@ -1041,6 +1043,8 @@ static bool settings_init(struct state_decklink *s, const char *fmt, return false; } } + } else if (strstr(ptr, "keep-settings") == ptr) { + s->keep_device_defaults = true; } else { log_msg(LOG_LEVEL_ERROR, MOD_NAME "Warning: unknown options in config string.\n"); return false; @@ -1061,7 +1065,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig IDeckLinkConfiguration* deckLinkConfiguration = NULL; // for Decklink Studio which has switchable XLR - analog 3 and 4 or AES/EBU 3,4 and 5,6 BMDAudioOutputAnalogAESSwitch audioConnection = (BMDAudioOutputAnalogAESSwitch) 0; - BMDVideo3DPackingFormat HDMI3DPacking = (BMDVideo3DPackingFormat) 0; + BMDVideo3DPackingFormat HDMI3DPacking = (BMDVideo3DPackingFormat) BMD_OPT_DEFAULT; int audio_consumer_levels = -1; int use1080psf = BMD_OPT_DEFAULT; @@ -1199,9 +1203,9 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig goto error; } - BMD_CONFIG_SET_INT(bmdDeckLinkConfigVideoOutputConversionMode, s->conversion_mode, true); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigVideoOutputConversionMode, s->conversion_mode, true); - if (use1080psf != BMD_OPT_KEEP) { + if (!s->keep_device_defaults && use1080psf != BMD_OPT_KEEP) { if (use1080psf == BMD_OPT_DEFAULT) { LOG(LOG_LEVEL_WARNING) << MOD_NAME << "Setting output signal as progressive, see option \"Use1080PsF\" to use PsF or keep default.\n"; } @@ -1212,22 +1216,14 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig } } - result = deckLinkConfiguration->SetFlag(bmdDeckLinkConfigLowLatencyVideoOutput, s->low_latency); - if (result != S_OK) { - log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to set to low-latency mode.\n"); - goto error; + BMD_CONFIG_SET(Flag, bmdDeckLinkConfigLowLatencyVideoOutput, s->low_latency, true); + + if (!s->keep_device_defaults && s->low_latency) { + BMD_CONFIG_SET(Flag, bmdDeckLinkConfigFieldFlickerRemoval, false, false); } - if (s->low_latency) { - result = deckLinkConfiguration->SetFlag(bmdDeckLinkConfigFieldFlickerRemoval, false); - if (result != S_OK) { - log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unable to set field flicker removal.\n"); - goto error; - } - } - - BMD_CONFIG_SET_INT(bmdDeckLinkConfigHDMI3DPackingFormat, HDMI3DPacking, true); - BMD_CONFIG_SET_INT(bmdDeckLinkConfigVideoOutputIdleOperation, bmdIdleVideoOutputLastFrame, false); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigHDMI3DPackingFormat, HDMI3DPacking, true); + BMD_CONFIG_SET(Int, bmdDeckLinkConfigVideoOutputIdleOperation, bmdIdleVideoOutputLastFrame, false); if (s->sdi_dual_channel_level != BMD_OPT_DEFAULT) { if (deckLinkAttributes) {