diff --git a/configure b/configure index 6aadf9c7c8..19aea617b2 100755 --- a/configure +++ b/configure @@ -5625,7 +5625,8 @@ enabled cuvid && { check_lib cuviddec.h cuvidCreateDecoder -lnvcuvid enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint enabled coreimage_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimage_filter; } enabled coreimagesrc_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimagesrc_filter; } -enabled decklink && { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; } +enabled decklink && { { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; } && + { check_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } } enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } enabled gmp && require2 gmp gmp.h mpz_export -lgmp enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init diff --git a/doc/indevs.texi b/doc/indevs.texi index 3fb852b1f8..479932a020 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -251,6 +251,10 @@ To use this option, ffmpeg needs to be compiled with @code{--enable-libzvbi}. Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp{16}. Defaults to @samp{2}. +@item duplex_mode +Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}. +Defaults to @samp{unset}. + @end table @subsection Examples diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index 2711fc1138..b6a2c96584 100644 --- a/libavdevice/decklink_common.cpp +++ b/libavdevice/decklink_common.cpp @@ -111,6 +111,23 @@ int ff_decklink_set_format(AVFormatContext *avctx, int i = 1; HRESULT res; + if (ctx->duplex_mode) { + bool duplex_supported = false; + + if (ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK) + duplex_supported = false; + + if (duplex_supported) { + res = ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode, ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf); + if (res != S_OK) + av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n"); + else + av_log(avctx, AV_LOG_VERBOSE, "Succesfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half"); + } else { + av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n"); + } + } + if (direction == DIRECTION_IN) { res = ctx->dli->GetDisplayModeIterator (&itermode); } else { @@ -249,6 +266,10 @@ void ff_decklink_cleanup(AVFormatContext *avctx) ctx->dli->Release(); if (ctx->dlo) ctx->dlo->Release(); + if (ctx->attr) + ctx->attr->Release(); + if (ctx->cfg) + ctx->cfg->Release(); if (ctx->dl) ctx->dl->Release(); } @@ -279,5 +300,17 @@ int ff_decklink_init_device(AVFormatContext *avctx, const char* name) if (!ctx->dl) return AVERROR(ENXIO); + if (ctx->dl->QueryInterface(IID_IDeckLinkConfiguration, (void **)&ctx->cfg) != S_OK) { + av_log(avctx, AV_LOG_ERROR, "Could not get configuration interface for '%s'\n", name); + ff_decklink_cleanup(avctx); + return AVERROR_EXTERNAL; + } + + if (ctx->dl->QueryInterface(IID_IDeckLinkAttributes, (void **)&ctx->attr) != S_OK) { + av_log(avctx, AV_LOG_ERROR, "Could not get attributes interface for '%s'\n", name); + ff_decklink_cleanup(avctx); + return AVERROR_EXTERNAL; + } + return 0; } diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h index ee39ff234e..201eb15462 100644 --- a/libavdevice/decklink_common.h +++ b/libavdevice/decklink_common.h @@ -44,6 +44,8 @@ struct decklink_ctx { IDeckLink *dl; IDeckLinkOutput *dlo; IDeckLinkInput *dli; + IDeckLinkConfiguration *cfg; + IDeckLinkAttributes *attr; decklink_output_callback *output_callback; decklink_input_callback *input_callback; @@ -77,6 +79,7 @@ struct decklink_ctx { int list_formats; int64_t teletext_lines; double preroll; + int duplex_mode; int frames_preroll; int frames_buffer; diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 2b5d92f250..f24f8f099c 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -34,6 +34,7 @@ struct decklink_cctx { double preroll; int v210; int audio_channels; + int duplex_mode; }; #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 371be20ef9..fc9633f5e9 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -445,6 +445,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) ctx->list_formats = cctx->list_formats; ctx->teletext_lines = cctx->teletext_lines; ctx->preroll = cctx->preroll; + ctx->duplex_mode = cctx->duplex_mode; cctx->ctx = ctx; #if !CONFIG_LIBZVBI diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 40c21a753b..72baa7d981 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -36,6 +36,10 @@ static const AVOption options[] = { { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, { "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7ffffffffLL}, 0, 0, DEC, "teletext_lines"}, { "channels", "number of audio channels", OFFSET(audio_channels), AV_OPT_TYPE_INT , { .i64 = 2 }, 2, 16, DEC }, + { "duplex_mode", "duplex mode", OFFSET(duplex_mode), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 2, DEC, "duplex_mode"}, + { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"}, + { "half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"}, + { "full", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "duplex_mode"}, { NULL }, };