[FFmpeg-cvslog] avdevice/decklink: add support for audio and video input selection
Marton Balint
git at videolan.org
Sun Jun 26 19:20:08 CEST 2016
ffmpeg | branch: master | Marton Balint <cus at passwd.hu> | Sat Jun 18 12:04:15 2016 +0200| [da89c6e37cf2fb3645611e8196cc28b6acfb9bd6] | committer: Marton Balint
avdevice/decklink: add support for audio and video input selection
Reviewed-by: Deti Fliegl <deti at fliegl.de>
Signed-off-by: Marton Balint <cus at passwd.hu>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=da89c6e37cf2fb3645611e8196cc28b6acfb9bd6
---
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 b6a2c96..3625673 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 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-cvslog
mailing list