From fd1d808d664a2d7759da8816ef2c3c3c42e89680 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Tue, 10 Oct 2023 14:48:02 +0200 Subject: [PATCH] print supported pixfmts also for DeckLink capture --- src/blackmagic_common.cpp | 58 ++++++++++++++++++++++++++++++++++ src/blackmagic_common.hpp | 9 ++++++ src/video_capture/decklink.cpp | 16 ++++++++++ src/video_display/decklink.cpp | 38 ++-------------------- 4 files changed, 85 insertions(+), 36 deletions(-) diff --git a/src/blackmagic_common.cpp b/src/blackmagic_common.cpp index 580c23a65..7949011c1 100644 --- a/src/blackmagic_common.cpp +++ b/src/blackmagic_common.cpp @@ -909,6 +909,64 @@ const map &get_connection_string_map() { return m; } +template struct bmd_no_conv { +}; +template <> struct bmd_no_conv { + static constexpr BMDVideoInputConversionMode value = + bmdNoVideoInputConversion; +}; +template <> struct bmd_no_conv { + static constexpr BMDVideoOutputConversionMode value = + bmdNoVideoOutputConversion; +}; +/** + * 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. + */ +template +bool +decklink_supports_codec(T *deckLink, BMDPixelFormat pf) +{ + IDeckLinkDisplayModeIterator *displayModeIterator = nullptr; + IDeckLinkDisplayMode *deckLinkDisplayMode = nullptr; + + if (FAILED( + deckLink->GetDisplayModeIterator(&displayModeIterator))) { + MSG(ERROR, "Fatal: cannot create display mode iterator.\n"); + return false; + } + + while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { + BMD_BOOL supported = false; + const HRESULT res = deckLink->DoesSupportVideoMode( + bmdVideoConnectionUnspecified, + deckLinkDisplayMode->GetDisplayMode(), pf, + bmd_no_conv::value, bmdSupportedVideoModeDefault, + nullptr, &supported); + deckLinkDisplayMode->Release(); + if (res != S_OK) { + MSG(WARNING, "DoesSupportVideoMode: %s\n", + bmd_hresult_to_string(res).c_str()); + continue; + } + if (supported) { + displayModeIterator->Release(); + return true; + } + } + displayModeIterator->Release(); + + return false; +} +template bool +decklink_supports_codec(IDeckLinkOutput *deckLink, + BMDPixelFormat pf); +template bool decklink_supports_codec(IDeckLinkInput *deckLink, + BMDPixelFormat pf); + ADD_TO_PARAM(R10K_FULL_OPT, "* " R10K_FULL_OPT "\n" " Do not do conversion from/to limited range on in/out for R10k on BMD devs.\n"); diff --git a/src/blackmagic_common.hpp b/src/blackmagic_common.hpp index efa60ba4e..cbf3c94ec 100644 --- a/src/blackmagic_common.hpp +++ b/src/blackmagic_common.hpp @@ -160,5 +160,14 @@ std::ostream &operator<<(std::ostream &output, REFIID iid); #define R10K_FULL_OPT "bmd-r10k-full-range" +template +bool decklink_supports_codec(T *deckLink, BMDPixelFormat pf); +extern template bool +decklink_supports_codec(IDeckLinkOutput *deckLink, + BMDPixelFormat pf); +extern template bool +decklink_supports_codec(IDeckLinkInput *deckLink, + BMDPixelFormat pf); + #endif // defined BLACKMAGIC_COMMON_HPP diff --git a/src/video_capture/decklink.cpp b/src/video_capture/decklink.cpp index 344d920d5..a9442d697 100644 --- a/src/video_capture/decklink.cpp +++ b/src/video_capture/decklink.cpp @@ -484,6 +484,22 @@ vidcap_decklink_print_card_info(IDeckLink *deckLink, const char *query_prop_fcc) cout << "Could not query device attributes.\n\n"; return; } + + IDeckLinkInput *deckLinkInput = nullptr; + color_printf("\n\tsupported pixel formats:" TERM_BOLD); + if ((deckLink->QueryInterface(IID_IDeckLinkInput, + (void **) &deckLinkInput)) == S_OK) { + for (auto &c : uv_to_bmd_codec_map) { + if (decklink_supports_codec(deckLinkInput, c.second)) { + printf(" %s", get_codec_name(c.first)); + } + } + RELEASE_IF_NOT_NULL(deckLinkInput); + } else { + color_printf(TRED("(error)")); + } + color_printf(TERM_RESET "\n"); + int64_t connections = 0; if (deckLinkAttributes->GetInt(BMDDeckLinkVideoInputConnections, &connections) != S_OK) { LOG(LOG_LEVEL_ERROR) << MOD_NAME "Could not get connections.\n"; diff --git a/src/video_display/decklink.cpp b/src/video_display/decklink.cpp index ea5ad829c..85d1f281b 100644 --- a/src/video_display/decklink.cpp +++ b/src/video_display/decklink.cpp @@ -1511,40 +1511,6 @@ static void display_decklink_done(void *state) delete s; } -/** - * 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. - */ -static bool decklink_display_supports_codec(IDeckLinkOutput *deckLinkOutput, BMDPixelFormat pf) { - IDeckLinkDisplayModeIterator *displayModeIterator; - IDeckLinkDisplayMode* deckLinkDisplayMode; - - if (FAILED(deckLinkOutput->GetDisplayModeIterator(&displayModeIterator))) { - log_msg(LOG_LEVEL_ERROR, MOD_NAME "Fatal: cannot create display mode iterator.\n"); - return false; - } - - while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) { - BMD_BOOL supported; - HRESULT res = deckLinkOutput->DoesSupportVideoMode(bmdVideoConnectionUnspecified, deckLinkDisplayMode->GetDisplayMode(), pf, bmdNoVideoOutputConversion, bmdSupportedVideoModeDefault, nullptr, &supported); - deckLinkDisplayMode->Release(); - if (res != S_OK) { - CALL_AND_CHECK(res, "DoesSupportVideoMode"); - continue; - } - if (supported) { - displayModeIterator->Release(); - return true; - } - } - displayModeIterator->Release(); - - return false; -} - static bool display_decklink_get_property(void *state, int property, void *val, size_t *len) { struct state_decklink *s = (struct state_decklink *)state; @@ -1553,7 +1519,7 @@ static bool display_decklink_get_property(void *state, int property, void *val, interlacing_t supported_il_modes[] = {PROGRESSIVE, INTERLACED_MERGED, SEGMENTED_FRAME}; int count = 0; for (auto & c : uv_to_bmd_codec_map) { - if (decklink_display_supports_codec(s->deckLinkOutput, c.second)) { + if (decklink_supports_codec(s->deckLinkOutput, c.second)) { codecs[count++] = c.first; } } @@ -2144,7 +2110,7 @@ static void print_output_modes (IDeckLink* deckLink) } color_printf("\n\tsupported pixel formats:" TERM_BOLD); for (auto & c : uv_to_bmd_codec_map) { - if (decklink_display_supports_codec(deckLinkOutput, c.second)) { + if (decklink_supports_codec(deckLinkOutput, c.second)) { printf(" %s", get_codec_name(c.first)); } }