diff options
author | Marton Balint <cus@passwd.hu> | 2016-06-18 12:04:15 +0200 |
---|---|---|
committer | Marton Balint <cus@passwd.hu> | 2016-06-26 19:18:02 +0200 |
commit | da89c6e37cf2fb3645611e8196cc28b6acfb9bd6 (patch) | |
tree | a53225df829e12250d4bb8c0e316dde7eb8dd317 | |
parent | 8f9fa49bd8bfd8cd2008da97eec7acf18873b960 (diff) | |
download | ffmpeg-da89c6e37cf2fb3645611e8196cc28b6acfb9bd6.tar.gz |
avdevice/decklink: add support for audio and video input selection
Reviewed-by: Deti Fliegl <deti@fliegl.de>
Signed-off-by: Marton Balint <cus@passwd.hu>
-rw-r--r-- | doc/indevs.texi | 10 | ||||
-rw-r--r-- | libavdevice/decklink_common.cpp | 43 | ||||
-rw-r--r-- | libavdevice/decklink_common.h | 21 | ||||
-rw-r--r-- | libavdevice/decklink_common_c.h | 2 | ||||
-rw-r--r-- | libavdevice/decklink_dec.cpp | 5 | ||||
-rw-r--r-- | libavdevice/decklink_dec_c.c | 16 |
6 files changed, 97 insertions, 0 deletions
diff --git a/doc/indevs.texi b/doc/indevs.texi index 479932a020..5239287e76 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}. +@item video_input +Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi}, +@samp{optical_sdi}, @samp{component}, @samp{composite} or @samp{s_video}. +Defaults to @samp{unset}. + +@item audio_input +Sets the audio input source. Must be @samp{unset}, @samp{embedded}, +@samp{aes_ebu}, @samp{analog}, @samp{analog_xlr}, @samp{analog_rca} or +@samp{microphone}. Defaults to @samp{unset}. + @end table @subsection Examples diff --git a/libavdevice/decklink_common.cpp b/libavdevice/decklink_common.cpp index b6a2c96584..362567341e 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_ERROR, "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 201eb15462..44edf19a6f 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 f24f8f099c..8de853d12c 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 fc9633f5e9..7f45224308 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 72baa7d981..06281fb6d7 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 }, }; |