From 91374fffeed3d9f41f8482e49ced458032d15c57 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Wed, 3 May 2023 12:46:58 +0200 Subject: [PATCH] DeckLink disp.: handle more opts generically + do not set the opts if keep option was selected --- src/blackmagic_common.cpp | 5 ++++- src/blackmagic_common.hpp | 1 + src/video_capture/decklink.cpp | 3 +++ src/video_display/decklink.cpp | 32 ++++++++++---------------------- 4 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/blackmagic_common.cpp b/src/blackmagic_common.cpp index ae21c2a90..df2857dc3 100644 --- a/src/blackmagic_common.cpp +++ b/src/blackmagic_common.cpp @@ -556,7 +556,7 @@ static string fcc_to_string(uint32_t fourcc) { BMDFCC(bmdVideo3DPackingSidebySideHalf), BMDFCC(bmdVideo3DPackingLinebyLine), BMDFCC(bmdVideo3DPackingTopAndBottom), BMDFCC(bmdVideo3DPackingFramePacking), BMDFCC(bmdVideo3DPackingRightOnly), BMDFCC(bmdVideo3DPackingLeftOnly), BMDFCC(bmdDeckLinkConfigVideoOutputIdleOperation), BMDFCC(bmdIdleVideoOutputLastFrame), - + BMDFCC(bmdDeckLinkConfigOutput1080pAsPsF), }; #undef BMDFCC if (auto it = conf_name_map.find(fourcc); it != conf_name_map.end()) { @@ -633,6 +633,9 @@ int64_t bmd_option::get_int() const { bool bmd_option::is_default() { return m_type == type_tag::t_default; } +bool bmd_option::is_user_set() const { + return m_user_specified; +} /** * @note * Returns true also for empty/NULL val - this allow specifying the flag without explicit value diff --git a/src/blackmagic_common.hpp b/src/blackmagic_common.hpp index 2dcf991e9..6b62cf0f7 100644 --- a/src/blackmagic_common.hpp +++ b/src/blackmagic_common.hpp @@ -90,6 +90,7 @@ public: explicit bmd_option(int64_t val, bool user_spec = true); explicit bmd_option(bool val, bool user_spec = true); bool is_default(); + bool is_user_set() const; void set_keep(); bool keep(); bool get_flag() const; diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index 83e716b6b..26ef57fbe 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -1114,6 +1114,9 @@ bool device_state::init(struct vidcap_decklink_state *s, struct tile *t, BMDAudi BMD_CHECK(deckLinkInput->QueryInterface(IID_IDeckLinkProfileAttributes, (void**)&deckLinkAttributes), "Could not query device attributes", INIT_ERR()); for (const auto &o : s->device_options) { + if (s->keep_device_defaults && !o.second.is_user_set()) { + continue; + } if (!o.second.option_write(deckLinkConfiguration, o.first)) { INIT_ERR(); } diff --git a/src/video_display/decklink.cpp b/src/video_display/decklink.cpp index f1aca5a14..4500de5cd 100644 --- a/src/video_display/decklink.cpp +++ b/src/video_display/decklink.cpp @@ -349,7 +349,9 @@ struct state_decklink { char sdi_dual_channel_level = BMD_OPT_DEFAULT; // 'A' - level A, 'B' - level B bool quad_square_division_split = true; map device_options = { - { bmdDeckLinkConfigVideoOutputIdleOperation, bmd_option{(int64_t) bmdIdleVideoOutputLastFrame, false} } + { bmdDeckLinkConfigVideoOutputIdleOperation, bmd_option{(int64_t) bmdIdleVideoOutputLastFrame, false} }, + { bmdDeckLinkConfigOutput1080pAsPsF, bmd_option{false, false}}, + { bmdDeckLinkConfigFieldFlickerRemoval, bmd_option{false, false}}, ///< required for interlaced video in low-latency }; HDRMetadata requested_hdr_mode{}; @@ -961,8 +963,7 @@ static auto parse_devices(const char *devices_str, vector *cardId) { static bool settings_init(struct state_decklink *s, const char *fmt, vector *cardId, - int *audio_consumer_levels, - bmd_option *use1080psf) { + int *audio_consumer_levels) { if (strlen(fmt) == 0) { return true; } @@ -1051,11 +1052,11 @@ static bool settings_init(struct state_decklink *s, const char *fmt, strlen("conversion=")) == 0) { s->device_options[bmdDeckLinkConfigVideoOutputConversionMode].parse_int(strchr(ptr, '=') + 1); } else if (is_prefix_of(ptr, "Use1080pNotPsF") || is_prefix_of(ptr, "Use1080PsF")) { - if (!use1080psf->parse_flag(strchr(ptr, '=') + 1)) { + if (!s->device_options[bmdDeckLinkConfigOutput1080pAsPsF].parse_flag(strchr(ptr, '=') + 1)) { return false; } if (strncasecmp(ptr, "Use1080pNotPsF", strlen("Use1080pNotPsF")) == 0) { // compat, inverse - use1080psf->set_flag(!use1080psf->get_flag()); + s->device_options[bmdDeckLinkConfigOutput1080pAsPsF].set_flag(s->device_options[bmdDeckLinkConfigOutput1080pAsPsF].get_flag()); } } else if (strcasecmp(ptr, "low-latency") == 0 || strcasecmp(ptr, "no-low-latency") == 0) { s->low_latency = strcasecmp(ptr, "low-latency") == 0; @@ -1103,7 +1104,6 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig // for Decklink Studio which has switchable XLR - analog 3 and 4 or AES/EBU 3,4 and 5,6 BMDAudioOutputAnalogAESSwitch audioConnection = (BMDAudioOutputAnalogAESSwitch) 0; int audio_consumer_levels = -1; - bmd_option use1080psf; if (strcmp(fmt, "help") == 0 || strcmp(fmt, "fullhelp") == 0) { show_help(strcmp(fmt, "fullhelp") == 0); @@ -1117,7 +1117,7 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig auto *s = new state_decklink(); s->audio_drift_fixer.set_root(get_root_module(parent)); - if (!settings_init(s, fmt, &cardId, &audio_consumer_levels, &use1080psf)) { + if (!settings_init(s, fmt, &cardId, &audio_consumer_levels)) { delete s; return NULL; } @@ -1236,30 +1236,18 @@ static void *display_decklink_init(struct module *parent, const char *fmt, unsig } for (const auto &o : s->device_options) { + if (s->keep_device_defaults && !o.second.is_user_set()) { + continue; + } if (!o.second.option_write(deckLinkConfiguration, o.first)) { goto error; } } - if (!s->keep_device_defaults && !use1080psf.keep()) { - if (use1080psf.is_default()) { - LOG(LOG_LEVEL_INFO) << MOD_NAME << "Setting output signal as progressive, see option \"Use1080PsF\" to use PsF or keep default.\n"; - use1080psf.set_flag(BMD_FALSE); - } - result = deckLinkConfiguration->SetFlag(bmdDeckLinkConfigOutput1080pAsPsF, use1080psf.get_flag()); - if (result != S_OK) { - LOG(LOG_LEVEL_ERROR) << MOD_NAME << "Unable to set 1080p P/PsF mode.\n"; - } - } - if (!bmd_option(s->low_latency).option_write(deckLinkConfiguration, bmdDeckLinkConfigLowLatencyVideoOutput)) { goto error; } - if (!s->keep_device_defaults && s->low_latency) { - bmd_option(false).option_write(deckLinkConfiguration, bmdDeckLinkConfigFieldFlickerRemoval); - } - if (s->sdi_dual_channel_level != BMD_OPT_DEFAULT) { if (deckLinkAttributes) { BMD_BOOL supports_level_a;