This patch also makes BlackMagic drivers v10.6.1 a hard requirement. Reviewed-by: Deti Fliegl <deti@fliegl.de> Signed-off-by: Marton Balint <cus@passwd.hu>tags/n3.2
@@ -5625,7 +5625,8 @@ enabled cuvid && { check_lib cuviddec.h cuvidCreateDecoder -lnvcuvid | |||||
enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint | enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint | ||||
enabled coreimage_filter && { check_header_objcc QuartzCore/CoreImage.h || disable coreimage_filter; } | 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 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 frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; } | ||||
enabled gmp && require2 gmp gmp.h mpz_export -lgmp | enabled gmp && require2 gmp gmp.h mpz_export -lgmp | ||||
enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init | enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init | ||||
@@ -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}. | Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp{16}. | ||||
Defaults to @samp{2}. | 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 | @end table | ||||
@subsection Examples | @subsection Examples | ||||
@@ -111,6 +111,23 @@ int ff_decklink_set_format(AVFormatContext *avctx, | |||||
int i = 1; | int i = 1; | ||||
HRESULT res; | 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) { | if (direction == DIRECTION_IN) { | ||||
res = ctx->dli->GetDisplayModeIterator (&itermode); | res = ctx->dli->GetDisplayModeIterator (&itermode); | ||||
} else { | } else { | ||||
@@ -249,6 +266,10 @@ void ff_decklink_cleanup(AVFormatContext *avctx) | |||||
ctx->dli->Release(); | ctx->dli->Release(); | ||||
if (ctx->dlo) | if (ctx->dlo) | ||||
ctx->dlo->Release(); | ctx->dlo->Release(); | ||||
if (ctx->attr) | |||||
ctx->attr->Release(); | |||||
if (ctx->cfg) | |||||
ctx->cfg->Release(); | |||||
if (ctx->dl) | if (ctx->dl) | ||||
ctx->dl->Release(); | ctx->dl->Release(); | ||||
} | } | ||||
@@ -279,5 +300,17 @@ int ff_decklink_init_device(AVFormatContext *avctx, const char* name) | |||||
if (!ctx->dl) | if (!ctx->dl) | ||||
return AVERROR(ENXIO); | 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; | return 0; | ||||
} | } |
@@ -44,6 +44,8 @@ struct decklink_ctx { | |||||
IDeckLink *dl; | IDeckLink *dl; | ||||
IDeckLinkOutput *dlo; | IDeckLinkOutput *dlo; | ||||
IDeckLinkInput *dli; | IDeckLinkInput *dli; | ||||
IDeckLinkConfiguration *cfg; | |||||
IDeckLinkAttributes *attr; | |||||
decklink_output_callback *output_callback; | decklink_output_callback *output_callback; | ||||
decklink_input_callback *input_callback; | decklink_input_callback *input_callback; | ||||
@@ -77,6 +79,7 @@ struct decklink_ctx { | |||||
int list_formats; | int list_formats; | ||||
int64_t teletext_lines; | int64_t teletext_lines; | ||||
double preroll; | double preroll; | ||||
int duplex_mode; | |||||
int frames_preroll; | int frames_preroll; | ||||
int frames_buffer; | int frames_buffer; | ||||
@@ -34,6 +34,7 @@ struct decklink_cctx { | |||||
double preroll; | double preroll; | ||||
int v210; | int v210; | ||||
int audio_channels; | int audio_channels; | ||||
int duplex_mode; | |||||
}; | }; | ||||
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */ | #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ |
@@ -445,6 +445,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) | |||||
ctx->list_formats = cctx->list_formats; | ctx->list_formats = cctx->list_formats; | ||||
ctx->teletext_lines = cctx->teletext_lines; | ctx->teletext_lines = cctx->teletext_lines; | ||||
ctx->preroll = cctx->preroll; | ctx->preroll = cctx->preroll; | ||||
ctx->duplex_mode = cctx->duplex_mode; | |||||
cctx->ctx = ctx; | cctx->ctx = ctx; | ||||
#if !CONFIG_LIBZVBI | #if !CONFIG_LIBZVBI | ||||
@@ -36,6 +36,10 @@ static const AVOption options[] = { | |||||
{ "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0x7fff9fffeLL}, 0, 0, DEC, "teletext_lines"}, | { "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"}, | { "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 }, | { "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 }, | { NULL }, | ||||
}; | }; | ||||