[FFmpeg-devel] [PATCH 7/8] avdevice/decklink: add support for audio and video input selection

Deti Fliegl deti at fliegl.de
Sun Jun 26 11:10:46 CEST 2016


Patch accepted, please apply.

On 23/06/16 02:47, Marton Balint wrote:
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
>  doc/indevs.texi                 | 10 ++++++++++
>  libavdevice/decklink_common.cpp | 43 +++++++++++++++++++++++++++++++++++++++++
>  libavdevice/decklink_common.h   | 21 ++++++++++++++++++++
>  libavdevice/decklink_common_c.h |  2 ++
>  libavdevice/decklink_dec.cpp    |  5 +++++
>  libavdevice/decklink_dec_c.c    | 16 +++++++++++++++
>  6 files changed, 97 insertions(+)
>
> diff --git a/doc/indevs.texi b/doc/indevs.texi
> index 479932a..5239287 100644
> --- a/doc/indevs.texi
> +++ b/doc/indevs.texi
> @@ -255,6 +255,16 @@ Defaults to @samp{2}.
>  Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
>  Defaults to @samp{unset}.
>
> + at item video_input
> +Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi},
> + at samp{optical_sdi}, @samp{component}, @samp{composite} or @samp{s_video}.
> +Defaults to @samp{unset}.
> +
> + at item audio_input
> +Sets the audio input source. Must be @samp{unset}, @samp{embedded},
> + at samp{aes_ebu}, @samp{analog}, @samp{analog_xlr}, @samp{analog_rca} or
> + at samp{microphone}. Defaults to @samp{unset}.
> +
>  @end table
>
>  @subsection Examples
> diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp
> index c6e127e..1ef521b 100644
> --- a/libavdevice/decklink_common.cpp
> +++ b/libavdevice/decklink_common.cpp
> @@ -98,6 +98,35 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName)
>      return hr;
>  }
>
> +static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
> +{
> +    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
> +    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
> +    BMDDeckLinkAttributeID attr_id = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? BMDDeckLinkAudioInputConnections : BMDDeckLinkVideoInputConnections;
> +    int64_t bmd_input              = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? ctx->audio_input : ctx->video_input;
> +    const char *type_name          = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? "audio" : "video";
> +    int64_t supported_connections = 0;
> +    HRESULT res;
> +
> +    if (bmd_input) {
> +        res = ctx->attr->GetInt(attr_id, &supported_connections);
> +        if (res != S_OK) {
> +            av_log(avctx, AV_LOG_ERROR, "Failed to query supported %s inputs.\n", type_name);
> +            return AVERROR_EXTERNAL;
> +        }
> +        if ((supported_connections & bmd_input) != bmd_input) {
> +            av_log(avctx, AV_LOG_ERROR, "Device does not support selected %s input.\n", type_name);
> +            return AVERROR(ENOSYS);
> +        }
> +        res = ctx->cfg->SetInt(cfg_id, bmd_input);
> +        if (res != S_OK) {
> +            av_log(avctx, AV_LOG_WARNING, "Failed to select %s input.\n", type_name);
> +            return AVERROR_EXTERNAL;
> +        }
> +    }
> +    return 0;
> +}
> +
>  int ff_decklink_set_format(AVFormatContext *avctx,
>                                 int width, int height,
>                                 int tb_num, int tb_den,
> @@ -129,6 +158,13 @@ int ff_decklink_set_format(AVFormatContext *avctx,
>      }
>
>      if (direction == DIRECTION_IN) {
> +        int ret;
> +        ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
> +        if (ret < 0)
> +            return ret;
> +        ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
> +        if (ret < 0)
> +            return ret;
>          res = ctx->dli->GetDisplayModeIterator (&itermode);
>      } else {
>          res = ctx->dlo->GetDisplayModeIterator (&itermode);
> @@ -224,6 +260,13 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct
>      HRESULT res;
>
>      if (direction == DIRECTION_IN) {
> +        int ret;
> +        ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
> +        if (ret < 0)
> +            return ret;
> +        ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
> +        if (ret < 0)
> +            return ret;
>          res = ctx->dli->GetDisplayModeIterator (&itermode);
>      } else {
>          res = ctx->dlo->GetDisplayModeIterator (&itermode);
> diff --git a/libavdevice/decklink_common.h b/libavdevice/decklink_common.h
> index 201eb15..44edf19 100644
> --- a/libavdevice/decklink_common.h
> +++ b/libavdevice/decklink_common.h
> @@ -53,6 +53,8 @@ struct decklink_ctx {
>      BMDTimeValue bmd_tb_den;
>      BMDTimeValue bmd_tb_num;
>      BMDDisplayMode bmd_mode;
> +    BMDVideoConnection video_input;
> +    BMDAudioConnection audio_input;
>      int bmd_width;
>      int bmd_height;
>      int bmd_field_dominance;
> @@ -102,6 +104,25 @@ IDeckLinkIterator *CreateDeckLinkIteratorInstance(void);
>  typedef uint32_t buffercount_type;
>  #endif
>
> +static const BMDAudioConnection decklink_audio_connection_map[] = {
> +    0,
> +    bmdAudioConnectionEmbedded,
> +    bmdAudioConnectionAESEBU,
> +    bmdAudioConnectionAnalog,
> +    bmdAudioConnectionAnalogXLR,
> +    bmdAudioConnectionAnalogRCA,
> +    bmdAudioConnectionMicrophone,
> +};
> +
> +static const BMDVideoConnection decklink_video_connection_map[] = {
> +    0,
> +    bmdVideoConnectionSDI,
> +    bmdVideoConnectionHDMI,
> +    bmdVideoConnectionOpticalSDI,
> +    bmdVideoConnectionComponent,
> +    bmdVideoConnectionComposite,
> +    bmdVideoConnectionSVideo,
> +};
>
>  HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);
>  int ff_decklink_set_format(AVFormatContext *avctx, int width, int height, int tb_num, int tb_den, decklink_direction_t direction = DIRECTION_OUT, int num = 0);
> diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h
> index f24f8f0..8de853d 100644
> --- a/libavdevice/decklink_common_c.h
> +++ b/libavdevice/decklink_common_c.h
> @@ -35,6 +35,8 @@ struct decklink_cctx {
>      int v210;
>      int audio_channels;
>      int duplex_mode;
> +    int audio_input;
> +    int video_input;
>  };
>
>  #endif /* AVDEVICE_DECKLINK_COMMON_C_H */
> diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
> index fc9633f..7f45224 100644
> --- a/libavdevice/decklink_dec.cpp
> +++ b/libavdevice/decklink_dec.cpp
> @@ -28,6 +28,7 @@ extern "C" {
>  #include "config.h"
>  #include "libavformat/avformat.h"
>  #include "libavformat/internal.h"
> +#include "libavutil/common.h"
>  #include "libavutil/imgutils.h"
>  #if CONFIG_LIBZVBI
>  #include <libzvbi.h>
> @@ -446,6 +447,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
>      ctx->teletext_lines = cctx->teletext_lines;
>      ctx->preroll      = cctx->preroll;
>      ctx->duplex_mode  = cctx->duplex_mode;
> +    if (cctx->video_input > 0 && (unsigned int)cctx->video_input < FF_ARRAY_ELEMS(decklink_video_connection_map))
> +        ctx->video_input = decklink_video_connection_map[cctx->video_input];
> +    if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input < FF_ARRAY_ELEMS(decklink_audio_connection_map))
> +        ctx->audio_input = decklink_audio_connection_map[cctx->audio_input];
>      cctx->ctx = ctx;
>
>  #if !CONFIG_LIBZVBI
> diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c
> index 72baa7d..06281fb 100644
> --- a/libavdevice/decklink_dec_c.c
> +++ b/libavdevice/decklink_dec_c.c
> @@ -40,6 +40,22 @@ static const AVOption options[] = {
>      { "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"},
> +    { "video_input",  "video input",              OFFSET(video_input),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 6,    DEC, "video_input"},
> +    { "unset",         NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0,    DEC, "video_input"},
> +    { "sdi",           NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0,    DEC, "video_input"},
> +    { "hdmi",          NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0,    DEC, "video_input"},
> +    { "optical_sdi",   NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0,    DEC, "video_input"},
> +    { "component",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,    DEC, "video_input"},
> +    { "composite",     NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,    DEC, "video_input"},
> +    { "s_video",       NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0,    DEC, "video_input"},
> +    { "audio_input",  "audio input",              OFFSET(audio_input),    AV_OPT_TYPE_INT,   { .i64 = 0}, 0, 6,    DEC, "audio_input"},
> +    { "unset",         NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0,    DEC, "audio_input"},
> +    { "embedded",      NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0,    DEC, "audio_input"},
> +    { "aes_ebu",       NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0,    DEC, "audio_input"},
> +    { "analog",        NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0,    DEC, "audio_input"},
> +    { "analog_xlr",    NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,    DEC, "audio_input"},
> +    { "analog_rca",    NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,    DEC, "audio_input"},
> +    { "microphone",    NULL,                                          0,  AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0,    DEC, "audio_input"},
>      { NULL },
>  };
>
>



More information about the ffmpeg-devel mailing list