diff mbox series

[FFmpeg-devel,v3,4/4] avdevice/decklink: support for more duplex mode for Decklink 8K Pro

Message ID 1628552283-26880-4-git-send-email-lance.lmwang@gmail.com
State New
Headers show
Series [FFmpeg-devel,v3,1/4] avdevice/decklink: add link configuration
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Limin Wang Aug. 9, 2021, 11:38 p.m. UTC
From: Limin Wang <lance.lmwang@gmail.com>

Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
---
 doc/indevs.texi                 | 16 +++++++++++++++-
 doc/outdevs.texi                | 16 +++++++++++++++-
 libavdevice/decklink_common.cpp |  4 ++--
 libavdevice/decklink_common.h   | 11 +++++++++++
 libavdevice/decklink_dec_c.c    | 10 ++++++++++
 libavdevice/decklink_enc_c.c    | 10 ++++++++++
 6 files changed, 63 insertions(+), 4 deletions(-)

Comments

Marton Balint Aug. 12, 2021, 8:05 p.m. UTC | #1
On Tue, 10 Aug 2021, lance.lmwang@gmail.com wrote:

> From: Limin Wang <lance.lmwang@gmail.com>
>
> Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> ---
> doc/indevs.texi                 | 16 +++++++++++++++-
> doc/outdevs.texi                | 16 +++++++++++++++-
> libavdevice/decklink_common.cpp |  4 ++--
> libavdevice/decklink_common.h   | 11 +++++++++++
> libavdevice/decklink_dec_c.c    | 10 ++++++++++
> libavdevice/decklink_enc_c.c    | 10 ++++++++++
> 6 files changed, 63 insertions(+), 4 deletions(-)
>
> diff --git a/doc/indevs.texi b/doc/indevs.texi
> index b377924..c2ec0f4 100644
> --- a/doc/indevs.texi
> +++ b/doc/indevs.texi
> @@ -344,9 +344,23 @@ Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp
> Defaults to @samp{2}.
>
> @item duplex_mode
> -Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
> +Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
> +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> +@samp{four_sub_device_half}
> Defaults to @samp{unset}.
>
> +Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
> +For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
> +sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
> +is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
> +
> +Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):
> +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> +@samp{four_sub_device_half}
> +
> +Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:
> +@samp{half}, @samp{full}
> +
> @item timecode_format
> Timecode type to include in the frame and video stream metadata. Must be
> @samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc},
> diff --git a/doc/outdevs.texi b/doc/outdevs.texi
> index cc0c94a..47dd913 100644
> --- a/doc/outdevs.texi
> +++ b/doc/outdevs.texi
> @@ -198,9 +198,23 @@ Amount of time to preroll video in seconds.
> Defaults to @option{0.5}.
>
> @item duplex_mode
> -Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
> +Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
> +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> +@samp{four_sub_device_half}
> Defaults to @samp{unset}.
>
> +Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
> +For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
> +sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
> +is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
> +
> +Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):

Valid profile modes for DeckLink 8K Pro (with DeckLink SDK >= 11.0)

> +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> +@samp{four_sub_device_half}
> +
> +Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:

modes

> +@samp{half}, @samp{full}
> +
> @item timing_offset
> Sets the genlock timing pixel offset on the used output.
> Defaults to @samp{unset}.
> diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
> index 0569462..8e77f4d 100644
> --- a/libavdevice/decklink_common.cpp
> +++ b/libavdevice/decklink_common.cpp
> @@ -182,7 +182,7 @@ int ff_decklink_set_configs(AVFormatContext *avctx,
>         if (duplex_supported) {
> #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
>             IDeckLinkProfile *profile = NULL;
> -            BMDProfileID bmd_profile_id = ctx->duplex_mode == 2 ? bmdProfileOneSubDeviceFullDuplex : bmdProfileTwoSubDevicesHalfDuplex;
> +            BMDProfileID bmd_profile_id = decklink_profile_id_map[ctx->duplex_mode];

I'd rather check if ctx->duplex_mode is not out of the array indexes and 
return EINVAL if it is. Should not happen, but in other places we check 
it so, let's check it here as well for consistencty.

>             res = manager->GetProfile(bmd_profile_id, &profile);
>             if (res == S_OK) {
>                 res = profile->SetActive();
> @@ -195,7 +195,7 @@ int ff_decklink_set_configs(AVFormatContext *avctx,
>             if (res != S_OK)
>                 av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
>             else
> -                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half");
> +                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2  || ctx->duplex_mode == 4 ? "full" : "half");

stray space before ||

>         } else {
>             av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
>         }
> diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
> index ad8b33c..5b11dcd 100644
> --- a/libavdevice/decklink_common.h
> +++ b/libavdevice/decklink_common.h
> @@ -208,6 +208,17 @@ static const BMDLinkConfiguration decklink_link_conf_map[] = {
>     bmdLinkConfigurationQuadLink
> };
>
> +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> +static const BMDProfileID decklink_profile_id_map[] = {
> +    (BMDProfileID)0,
> +    bmdProfileTwoSubDevicesHalfDuplex,
> +    bmdProfileOneSubDeviceFullDuplex,
> +    bmdProfileOneSubDeviceHalfDuplex,
> +    bmdProfileTwoSubDevicesFullDuplex,
> +    bmdProfileFourSubDevicesHalfDuplex,
> +};
> +#endif
> +
> int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction);
> int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT);
> int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction);
> diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
> index 1d93e8b..2159702 100644
> --- a/libavdevice/decklink_dec_c.c
> +++ b/libavdevice/decklink_dec_c.c
> @@ -45,10 +45,20 @@ 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 },
> +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> +    { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 5,    DEC, "duplex_mode"},
> +#else
>     { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 2,    DEC, "duplex_mode"},
> +#endif
>     { "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"},
> +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> +    { "one_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0,    DEC, "duplex_mode"},
> +    { "one_sub_device_half",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0,    DEC, "duplex_mode"},
> +    { "two_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,    DEC, "duplex_mode"},
> +    { "four_sub_device_half",     NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,    DEC, "duplex_mode"},
> +#endif
>     { "timecode_format", "timecode format",           OFFSET(tc_format),  AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 8,    DEC, "tc_format"},
>     { "none",          NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0,    DEC, "tc_format"},
>     { "rp188vitc",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0,    DEC, "tc_format"},
> diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c
> index 559f078..d86ba1f 100644
> --- a/libavdevice/decklink_enc_c.c
> +++ b/libavdevice/decklink_enc_c.c
> @@ -31,10 +31,20 @@ static const AVOption options[] = {
>     { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0   }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED},
>     { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, ENC },
>     { "preroll"     , "video preroll in seconds", OFFSET(preroll     ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC },
> +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> +    { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 5, ENC, "duplex_mode"},
> +#else
>     { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 2, ENC, "duplex_mode"},
> +#endif
>     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "duplex_mode"},
>     { "half"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "duplex_mode"},
>     { "full"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
> +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b020000

I guess this also supposed to be 0x0b000000.

> +    { "one_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
> +    { "one_sub_device_half",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 3   }, 0, 0, ENC, "duplex_mode"},
> +    { "two_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 4   }, 0, 0, ENC, "duplex_mode"},
> +    { "four_sub_device_half",     NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 5   }, 0, 0, ENC, "duplex_mode"},
> +#endif
>     { "link" ,         "single/dual/quad SDI link configuration", OFFSET(link), AV_OPT_TYPE_INT, { .i64 = 0   }, 0, 3, ENC, "link"},
>     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "link"},
>     { "single"      ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "link"},

This also needs a micro bump. Or, if you push these four patches at once, 
then it is also OK (I think) to only bump in the last patch.

Thanks,
Marton
Limin Wang Aug. 13, 2021, 3:25 a.m. UTC | #2
On Thu, Aug 12, 2021 at 10:05:47PM +0200, Marton Balint wrote:
> 
> 
> On Tue, 10 Aug 2021, lance.lmwang@gmail.com wrote:
> 
> > From: Limin Wang <lance.lmwang@gmail.com>
> > 
> > Signed-off-by: Limin Wang <lance.lmwang@gmail.com>
> > ---
> > doc/indevs.texi                 | 16 +++++++++++++++-
> > doc/outdevs.texi                | 16 +++++++++++++++-
> > libavdevice/decklink_common.cpp |  4 ++--
> > libavdevice/decklink_common.h   | 11 +++++++++++
> > libavdevice/decklink_dec_c.c    | 10 ++++++++++
> > libavdevice/decklink_enc_c.c    | 10 ++++++++++
> > 6 files changed, 63 insertions(+), 4 deletions(-)
> > 
> > diff --git a/doc/indevs.texi b/doc/indevs.texi
> > index b377924..c2ec0f4 100644
> > --- a/doc/indevs.texi
> > +++ b/doc/indevs.texi
> > @@ -344,9 +344,23 @@ Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp
> > Defaults to @samp{2}.
> > 
> > @item duplex_mode
> > -Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
> > +Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
> > +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> > +@samp{four_sub_device_half}
> > Defaults to @samp{unset}.
> > 
> > +Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
> > +For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
> > +sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
> > +is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
> > +
> > +Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):
> > +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> > +@samp{four_sub_device_half}
> > +
> > +Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:
> > +@samp{half}, @samp{full}
> > +
> > @item timecode_format
> > Timecode type to include in the frame and video stream metadata. Must be
> > @samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc},
> > diff --git a/doc/outdevs.texi b/doc/outdevs.texi
> > index cc0c94a..47dd913 100644
> > --- a/doc/outdevs.texi
> > +++ b/doc/outdevs.texi
> > @@ -198,9 +198,23 @@ Amount of time to preroll video in seconds.
> > Defaults to @option{0.5}.
> > 
> > @item duplex_mode
> > -Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
> > +Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
> > +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> > +@samp{four_sub_device_half}
> > Defaults to @samp{unset}.
> > 
> > +Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
> > +For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
> > +sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
> > +is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
> > +
> > +Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):
> 
> Valid profile modes for DeckLink 8K Pro (with DeckLink SDK >= 11.0)
> 
> > +@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
> > +@samp{four_sub_device_half}
> > +
> > +Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:
> 
> modes

Fixed with modes.

> 
> > +@samp{half}, @samp{full}
> > +
> > @item timing_offset
> > Sets the genlock timing pixel offset on the used output.
> > Defaults to @samp{unset}.
> > diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
> > index 0569462..8e77f4d 100644
> > --- a/libavdevice/decklink_common.cpp
> > +++ b/libavdevice/decklink_common.cpp
> > @@ -182,7 +182,7 @@ int ff_decklink_set_configs(AVFormatContext *avctx,
> >         if (duplex_supported) {
> > #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> >             IDeckLinkProfile *profile = NULL;
> > -            BMDProfileID bmd_profile_id = ctx->duplex_mode == 2 ? bmdProfileOneSubDeviceFullDuplex : bmdProfileTwoSubDevicesHalfDuplex;
> > +            BMDProfileID bmd_profile_id = decklink_profile_id_map[ctx->duplex_mode];
> 
> I'd rather check if ctx->duplex_mode is not out of the array indexes and
> return EINVAL if it is. Should not happen, but in other places we check it
> so, let's check it here as well for consistencty.

will add the valid check before.

> 
> >             res = manager->GetProfile(bmd_profile_id, &profile);
> >             if (res == S_OK) {
> >                 res = profile->SetActive();
> > @@ -195,7 +195,7 @@ int ff_decklink_set_configs(AVFormatContext *avctx,
> >             if (res != S_OK)
> >                 av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
> >             else
> > -                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half");
> > +                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2  || ctx->duplex_mode == 4 ? "full" : "half");
> 
> stray space before ||

fixed.

> 
> >         } else {
> >             av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
> >         }
> > diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
> > index ad8b33c..5b11dcd 100644
> > --- a/libavdevice/decklink_common.h
> > +++ b/libavdevice/decklink_common.h
> > @@ -208,6 +208,17 @@ static const BMDLinkConfiguration decklink_link_conf_map[] = {
> >     bmdLinkConfigurationQuadLink
> > };
> > 
> > +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> > +static const BMDProfileID decklink_profile_id_map[] = {
> > +    (BMDProfileID)0,
> > +    bmdProfileTwoSubDevicesHalfDuplex,
> > +    bmdProfileOneSubDeviceFullDuplex,
> > +    bmdProfileOneSubDeviceHalfDuplex,
> > +    bmdProfileTwoSubDevicesFullDuplex,
> > +    bmdProfileFourSubDevicesHalfDuplex,
> > +};
> > +#endif
> > +
> > int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction);
> > int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT);
> > int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction);
> > diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
> > index 1d93e8b..2159702 100644
> > --- a/libavdevice/decklink_dec_c.c
> > +++ b/libavdevice/decklink_dec_c.c
> > @@ -45,10 +45,20 @@ 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 },
> > +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> > +    { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 5,    DEC, "duplex_mode"},
> > +#else
> >     { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 2,    DEC, "duplex_mode"},
> > +#endif
> >     { "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"},
> > +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> > +    { "one_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0,    DEC, "duplex_mode"},
> > +    { "one_sub_device_half",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0,    DEC, "duplex_mode"},
> > +    { "two_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,    DEC, "duplex_mode"},
> > +    { "four_sub_device_half",     NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,    DEC, "duplex_mode"},
> > +#endif
> >     { "timecode_format", "timecode format",           OFFSET(tc_format),  AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 8,    DEC, "tc_format"},
> >     { "none",          NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0,    DEC, "tc_format"},
> >     { "rp188vitc",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0,    DEC, "tc_format"},
> > diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c
> > index 559f078..d86ba1f 100644
> > --- a/libavdevice/decklink_enc_c.c
> > +++ b/libavdevice/decklink_enc_c.c
> > @@ -31,10 +31,20 @@ static const AVOption options[] = {
> >     { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0   }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED},
> >     { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, ENC },
> >     { "preroll"     , "video preroll in seconds", OFFSET(preroll     ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC },
> > +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
> > +    { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 5, ENC, "duplex_mode"},
> > +#else
> >     { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 2, ENC, "duplex_mode"},
> > +#endif
> >     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "duplex_mode"},
> >     { "half"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "duplex_mode"},
> >     { "full"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
> > +#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b020000
> 
> I guess this also supposed to be 0x0b000000.

yeah, one missing, fixed.

> 
> > +    { "one_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
> > +    { "one_sub_device_half",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 3   }, 0, 0, ENC, "duplex_mode"},
> > +    { "two_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 4   }, 0, 0, ENC, "duplex_mode"},
> > +    { "four_sub_device_half",     NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 5   }, 0, 0, ENC, "duplex_mode"},
> > +#endif
> >     { "link" ,         "single/dual/quad SDI link configuration", OFFSET(link), AV_OPT_TYPE_INT, { .i64 = 0   }, 0, 3, ENC, "link"},
> >     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "link"},
> >     { "single"      ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "link"},
> 
> This also needs a micro bump. Or, if you push these four patches at once,
> then it is also OK (I think) to only bump in the last patch.

OK, will bump the version for the last patch.

> 
> Thanks,
> Marton
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/doc/indevs.texi b/doc/indevs.texi
index b377924..c2ec0f4 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -344,9 +344,23 @@  Defines number of audio channels to capture. Must be @samp{2}, @samp{8} or @samp
 Defaults to @samp{2}.
 
 @item duplex_mode
-Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
+Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
+@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
+@samp{four_sub_device_half}
 Defaults to @samp{unset}.
 
+Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
+For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
+sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
+is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
+
+Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):
+@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
+@samp{four_sub_device_half}
+
+Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:
+@samp{half}, @samp{full}
+
 @item timecode_format
 Timecode type to include in the frame and video stream metadata. Must be
 @samp{none}, @samp{rp188vitc}, @samp{rp188vitc2}, @samp{rp188ltc},
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index cc0c94a..47dd913 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -198,9 +198,23 @@  Amount of time to preroll video in seconds.
 Defaults to @option{0.5}.
 
 @item duplex_mode
-Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
+Sets the decklink device duplex/profile mode. Must be @samp{unset}, @samp{half}, @samp{full},
+@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
+@samp{four_sub_device_half}
 Defaults to @samp{unset}.
 
+Note: DeckLink SDK 11.0 have replaced the duplex property by a profile property.
+For the DeckLink Duo 2 and DeckLink Quad 2, a profile is shared between any 2
+sub-devices that utilize the same connectors. For the DeckLink 8K Pro, a profile
+is shared between all 4 sub-devices. So DeckLink 8K Pro support four profiles.
+
+Valid profile mode for DeckLink 8K Pro(Updated DeckLink SDK to >= 11.0):
+@samp{one_sub_device_full}, @samp{one_sub_device_half}, @samp{two_sub_device_full},
+@samp{four_sub_device_half}
+
+Valid profile mode for DeckLink Quad 2 and DeckLink Duo 2:
+@samp{half}, @samp{full}
+
 @item timing_offset
 Sets the genlock timing pixel offset on the used output.
 Defaults to @samp{unset}.
diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
index 0569462..8e77f4d 100644
--- a/libavdevice/decklink_common.cpp
+++ b/libavdevice/decklink_common.cpp
@@ -182,7 +182,7 @@  int ff_decklink_set_configs(AVFormatContext *avctx,
         if (duplex_supported) {
 #if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
             IDeckLinkProfile *profile = NULL;
-            BMDProfileID bmd_profile_id = ctx->duplex_mode == 2 ? bmdProfileOneSubDeviceFullDuplex : bmdProfileTwoSubDevicesHalfDuplex;
+            BMDProfileID bmd_profile_id = decklink_profile_id_map[ctx->duplex_mode];
             res = manager->GetProfile(bmd_profile_id, &profile);
             if (res == S_OK) {
                 res = profile->SetActive();
@@ -195,7 +195,7 @@  int ff_decklink_set_configs(AVFormatContext *avctx,
             if (res != S_OK)
                 av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
             else
-                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half");
+                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2  || ctx->duplex_mode == 4 ? "full" : "half");
         } else {
             av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
         }
diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
index ad8b33c..5b11dcd 100644
--- a/libavdevice/decklink_common.h
+++ b/libavdevice/decklink_common.h
@@ -208,6 +208,17 @@  static const BMDLinkConfiguration decklink_link_conf_map[] = {
     bmdLinkConfigurationQuadLink
 };
 
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
+static const BMDProfileID decklink_profile_id_map[] = {
+    (BMDProfileID)0,
+    bmdProfileTwoSubDevicesHalfDuplex,
+    bmdProfileOneSubDeviceFullDuplex,
+    bmdProfileOneSubDeviceHalfDuplex,
+    bmdProfileTwoSubDevicesFullDuplex,
+    bmdProfileFourSubDevicesHalfDuplex,
+};
+#endif
+
 int ff_decklink_set_configs(AVFormatContext *avctx, decklink_direction_t direction);
 int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, enum AVFieldOrder field_order, decklink_direction_t direction = DIRECTION_OUT);
 int ff_decklink_set_format(AVFormatContext *avctx, decklink_direction_t direction);
diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
index 1d93e8b..2159702 100644
--- a/libavdevice/decklink_dec_c.c
+++ b/libavdevice/decklink_dec_c.c
@@ -45,10 +45,20 @@  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 },
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
+    { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 5,    DEC, "duplex_mode"},
+#else
     { "duplex_mode",  "duplex mode",              OFFSET(duplex_mode),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 2,    DEC, "duplex_mode"},
+#endif
     { "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"},
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
+    { "one_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0,    DEC, "duplex_mode"},
+    { "one_sub_device_half",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0,    DEC, "duplex_mode"},
+    { "two_sub_device_full",      NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,    DEC, "duplex_mode"},
+    { "four_sub_device_half",     NULL,                               0,  AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,    DEC, "duplex_mode"},
+#endif
     { "timecode_format", "timecode format",           OFFSET(tc_format),  AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 8,    DEC, "tc_format"},
     { "none",          NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0,    DEC, "tc_format"},
     { "rp188vitc",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0,    DEC, "tc_format"},
diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c
index 559f078..d86ba1f 100644
--- a/libavdevice/decklink_enc_c.c
+++ b/libavdevice/decklink_enc_c.c
@@ -31,10 +31,20 @@  static const AVOption options[] = {
     { "list_devices", "use ffmpeg -sinks decklink instead", OFFSET(list_devices), AV_OPT_TYPE_BOOL, { .i64 = 0   }, 0, 1, ENC | AV_OPT_FLAG_DEPRECATED},
     { "list_formats", "list supported formats"  , OFFSET(list_formats), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 1, ENC },
     { "preroll"     , "video preroll in seconds", OFFSET(preroll     ), AV_OPT_TYPE_DOUBLE, { .dbl = 0.5 }, 0, 5, ENC },
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b000000
+    { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 5, ENC, "duplex_mode"},
+#else
     { "duplex_mode" , "duplex mode"             , OFFSET(duplex_mode ), AV_OPT_TYPE_INT   , { .i64 = 0   }, 0, 2, ENC, "duplex_mode"},
+#endif
     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "duplex_mode"},
     { "half"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "duplex_mode"},
     { "full"        ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
+#if BLACKMAGIC_DECKLINK_API_VERSION >= 0x0b020000
+    { "one_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 2   }, 0, 0, ENC, "duplex_mode"},
+    { "one_sub_device_half",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 3   }, 0, 0, ENC, "duplex_mode"},
+    { "two_sub_device_full",      NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 4   }, 0, 0, ENC, "duplex_mode"},
+    { "four_sub_device_half",     NULL           ,0                   , AV_OPT_TYPE_CONST , { .i64 = 5   }, 0, 0, ENC, "duplex_mode"},
+#endif
     { "link" ,         "single/dual/quad SDI link configuration", OFFSET(link), AV_OPT_TYPE_INT, { .i64 = 0   }, 0, 3, ENC, "link"},
     { "unset"       ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 0   }, 0, 0, ENC, "link"},
     { "single"      ,  NULL                     , 0                   , AV_OPT_TYPE_CONST , { .i64 = 1   }, 0, 0, ENC, "link"},