History

avdevice/decklink: add support for audio and video input selection

Marton Balint committed 10 years ago

Commit da89c6e1 parent 8f9fa496 files · +97 −0Browse files

Unified · Split

6 files
  1. doc/indevs.texi +10 −0
  2. libavdevice/decklink_common.cpp +43 −0
  3. libavdevice/decklink_common.h +21 −0
  4. libavdevice/decklink_common_c.h +2 −0
  5. libavdevice/decklink_dec.cpp +5 −0
  6. libavdevice/decklink_dec_c.c +16 −0
doc/indevs.texi+10−0
@@ -255,6 +255,16 @@ Defaults to @samp{2}. · 254 unmodified lines
255Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.255Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
256Defaults to @samp{unset}.256Defaults to @samp{unset}.
257 257
258@item video_input
259Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi},
260@samp{optical_sdi}, @samp{component}, @samp{composite} or @samp{s_video}.
261Defaults to @samp{unset}.
262
263@item audio_input
264Sets the audio input source. Must be @samp{unset}, @samp{embedded},
265@samp{aes_ebu}, @samp{analog}, @samp{analog_xlr}, @samp{analog_rca} or
266@samp{microphone}. Defaults to @samp{unset}.
267
258@end table268@end table
259 269
260@subsection Examples270@subsection Examples
libavdevice/decklink_common.cpp+43−0
@@ -98,6 +98,35 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName) · 97 unmodified lines
98 return hr;98 return hr;
99}99}
100 100
101static int decklink_select_input(AVFormatContext *avctx, BMDDeckLinkConfigurationID cfg_id)
102{
103 struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
104 struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
105 BMDDeckLinkAttributeID attr_id = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? BMDDeckLinkAudioInputConnections : BMDDeckLinkVideoInputConnections;
106 int64_t bmd_input = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? ctx->audio_input : ctx->video_input;
107 const char *type_name = (cfg_id == bmdDeckLinkConfigAudioInputConnection) ? "audio" : "video";
108 int64_t supported_connections = 0;
109 HRESULT res;
110
111 if (bmd_input) {
112 res = ctx->attr->GetInt(attr_id, &supported_connections);
113 if (res != S_OK) {
114 av_log(avctx, AV_LOG_ERROR, "Failed to query supported %s inputs.\n", type_name);
115 return AVERROR_EXTERNAL;
116 }
117 if ((supported_connections & bmd_input) != bmd_input) {
118 av_log(avctx, AV_LOG_ERROR, "Device does not support selected %s input.\n", type_name);
119 return AVERROR(ENOSYS);
120 }
121 res = ctx->cfg->SetInt(cfg_id, bmd_input);
122 if (res != S_OK) {
123 av_log(avctx, AV_LOG_ERROR, "Failed to select %s input.\n", type_name);
124 return AVERROR_EXTERNAL;
125 }
126 }
127 return 0;
128}
129
101int ff_decklink_set_format(AVFormatContext *avctx,130int ff_decklink_set_format(AVFormatContext *avctx,
102 int width, int height,131 int width, int height,
103 int tb_num, int tb_den,132 int tb_num, int tb_den,
@@ -129,6 +158,13 @@ int ff_decklink_set_format(AVFormatContext *avctx, · 25 unmodified lines
129 }158 }
130 159
131 if (direction == DIRECTION_IN) {160 if (direction == DIRECTION_IN) {
161 int ret;
162 ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
163 if (ret < 0)
164 return ret;
165 ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
166 if (ret < 0)
167 return ret;
132 res = ctx->dli->GetDisplayModeIterator (&itermode);168 res = ctx->dli->GetDisplayModeIterator (&itermode);
133 } else {169 } else {
134 res = ctx->dlo->GetDisplayModeIterator (&itermode);170 res = ctx->dlo->GetDisplayModeIterator (&itermode);
@@ -224,6 +260,13 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct · 89 unmodified lines
224 HRESULT res;260 HRESULT res;
225 261
226 if (direction == DIRECTION_IN) {262 if (direction == DIRECTION_IN) {
263 int ret;
264 ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
265 if (ret < 0)
266 return ret;
267 ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
268 if (ret < 0)
269 return ret;
227 res = ctx->dli->GetDisplayModeIterator (&itermode);270 res = ctx->dli->GetDisplayModeIterator (&itermode);
228 } else {271 } else {
229 res = ctx->dlo->GetDisplayModeIterator (&itermode);272 res = ctx->dlo->GetDisplayModeIterator (&itermode);
libavdevice/decklink_common.h+21−0
@@ -53,6 +53,8 @@ struct decklink_ctx { · 52 unmodified lines
53 BMDTimeValue bmd_tb_den;53 BMDTimeValue bmd_tb_den;
54 BMDTimeValue bmd_tb_num;54 BMDTimeValue bmd_tb_num;
55 BMDDisplayMode bmd_mode;55 BMDDisplayMode bmd_mode;
56 BMDVideoConnection video_input;
57 BMDAudioConnection audio_input;
56 int bmd_width;58 int bmd_width;
57 int bmd_height;59 int bmd_height;
58 int bmd_field_dominance;60 int bmd_field_dominance;
@@ -102,6 +104,25 @@ IDeckLinkIterator *CreateDeckLinkIteratorInstance(void); · 43 unmodified lines
102typedef uint32_t buffercount_type;104typedef uint32_t buffercount_type;
103#endif105#endif
104 106
107static const BMDAudioConnection decklink_audio_connection_map[] = {
108 0,
109 bmdAudioConnectionEmbedded,
110 bmdAudioConnectionAESEBU,
111 bmdAudioConnectionAnalog,
112 bmdAudioConnectionAnalogXLR,
113 bmdAudioConnectionAnalogRCA,
114 bmdAudioConnectionMicrophone,
115};
116
117static const BMDVideoConnection decklink_video_connection_map[] = {
118 0,
119 bmdVideoConnectionSDI,
120 bmdVideoConnectionHDMI,
121 bmdVideoConnectionOpticalSDI,
122 bmdVideoConnectionComponent,
123 bmdVideoConnectionComposite,
124 bmdVideoConnectionSVideo,
125};
105 126
106HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);127HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName);
107int 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);128int 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);
libavdevice/decklink_common_c.h+2−0
@@ -35,6 +35,8 @@ struct decklink_cctx { · 34 unmodified lines
35 int v210;35 int v210;
36 int audio_channels;36 int audio_channels;
37 int duplex_mode;37 int duplex_mode;
38 int audio_input;
39 int video_input;
38};40};
39 41
40#endif /* AVDEVICE_DECKLINK_COMMON_C_H */42#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
libavdevice/decklink_dec.cpp+5−0
@@ -28,6 +28,7 @@ extern "C" { · 27 unmodified lines
28#include "config.h"28#include "config.h"
29#include "libavformat/avformat.h"29#include "libavformat/avformat.h"
30#include "libavformat/internal.h"30#include "libavformat/internal.h"
31#include "libavutil/common.h"
31#include "libavutil/imgutils.h"32#include "libavutil/imgutils.h"
32#if CONFIG_LIBZVBI33#if CONFIG_LIBZVBI
33#include <libzvbi.h>34#include <libzvbi.h>
@@ -446,6 +447,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) · 412 unmodified lines
446 ctx->teletext_lines = cctx->teletext_lines;447 ctx->teletext_lines = cctx->teletext_lines;
447 ctx->preroll = cctx->preroll;448 ctx->preroll = cctx->preroll;
448 ctx->duplex_mode = cctx->duplex_mode;449 ctx->duplex_mode = cctx->duplex_mode;
450 if (cctx->video_input > 0 && (unsigned int)cctx->video_input < FF_ARRAY_ELEMS(decklink_video_connection_map))
451 ctx->video_input = decklink_video_connection_map[cctx->video_input];
452 if (cctx->audio_input > 0 && (unsigned int)cctx->audio_input < FF_ARRAY_ELEMS(decklink_audio_connection_map))
453 ctx->audio_input = decklink_audio_connection_map[cctx->audio_input];
449 cctx->ctx = ctx;454 cctx->ctx = ctx;
450 455
451#if !CONFIG_LIBZVBI456#if !CONFIG_LIBZVBI
libavdevice/decklink_dec_c.c+16−0
@@ -40,6 +40,22 @@ static const AVOption options[] = { · 39 unmodified lines
40 { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"},40 { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"},
41 { "half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"},41 { "half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"},
42 { "full", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "duplex_mode"},42 { "full", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "duplex_mode"},
43 { "video_input", "video input", OFFSET(video_input), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 6, DEC, "video_input"},
44 { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "video_input"},
45 { "sdi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "video_input"},
46 { "hdmi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "video_input"},
47 { "optical_sdi", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0, DEC, "video_input"},
48 { "component", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0, DEC, "video_input"},
49 { "composite", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0, DEC, "video_input"},
50 { "s_video", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0, DEC, "video_input"},
51 { "audio_input", "audio input", OFFSET(audio_input), AV_OPT_TYPE_INT, { .i64 = 0}, 0, 6, DEC, "audio_input"},
52 { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "audio_input"},
53 { "embedded", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "audio_input"},
54 { "aes_ebu", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2}, 0, 0, DEC, "audio_input"},
55 { "analog", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3}, 0, 0, DEC, "audio_input"},
56 { "analog_xlr", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0, DEC, "audio_input"},
57 { "analog_rca", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0, DEC, "audio_input"},
58 { "microphone", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0, DEC, "audio_input"},
43 { NULL },59 { NULL },
44};60};
45 61

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t