Unified · Split
| @@ -255,6 +255,16 @@ Defaults to @samp{2}. · 254 unmodified lines | ||
| 255 | 255 | Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}. |
| 256 | 256 | Defaults to @samp{unset}. |
| 257 | 257 | |
| 258 | +@item video_input | |
| 259 | +Sets the video input source. Must be @samp{unset}, @samp{sdi}, @samp{hdmi}, | |
| 260 | +@samp{optical_sdi}, @samp{component}, @samp{composite} or @samp{s_video}. | |
| 261 | +Defaults to @samp{unset}. | |
| 262 | + | |
| 263 | +@item audio_input | |
| 264 | +Sets 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 | 268 | @end table |
| 259 | 269 | |
| 260 | 270 | @subsection Examples |
| @@ -98,6 +98,35 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName) · 97 unmodified lines | ||
| 98 | 98 | return hr; |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | +static 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 | + | |
| 101 | 130 | int ff_decklink_set_format(AVFormatContext *avctx, |
| 102 | 131 | int width, int height, |
| 103 | 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 | 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 | 168 | res = ctx->dli->GetDisplayModeIterator (&itermode); |
| 133 | 169 | } else { |
| 134 | 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 | 260 | HRESULT res; |
| 225 | 261 | |
| 226 | 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 | 270 | res = ctx->dli->GetDisplayModeIterator (&itermode); |
| 228 | 271 | } else { |
| 229 | 272 | res = ctx->dlo->GetDisplayModeIterator (&itermode); |
| @@ -53,6 +53,8 @@ struct decklink_ctx { · 52 unmodified lines | ||
| 53 | 53 | BMDTimeValue bmd_tb_den; |
| 54 | 54 | BMDTimeValue bmd_tb_num; |
| 55 | 55 | BMDDisplayMode bmd_mode; |
| 56 | + BMDVideoConnection video_input; | |
| 57 | + BMDAudioConnection audio_input; | |
| 56 | 58 | int bmd_width; |
| 57 | 59 | int bmd_height; |
| 58 | 60 | int bmd_field_dominance; |
| @@ -102,6 +104,25 @@ IDeckLinkIterator *CreateDeckLinkIteratorInstance(void); · 43 unmodified lines | ||
| 102 | 104 | typedef uint32_t buffercount_type; |
| 103 | 105 | #endif |
| 104 | 106 | |
| 107 | +static const BMDAudioConnection decklink_audio_connection_map[] = { | |
| 108 | + 0, | |
| 109 | + bmdAudioConnectionEmbedded, | |
| 110 | + bmdAudioConnectionAESEBU, | |
| 111 | + bmdAudioConnectionAnalog, | |
| 112 | + bmdAudioConnectionAnalogXLR, | |
| 113 | + bmdAudioConnectionAnalogRCA, | |
| 114 | + bmdAudioConnectionMicrophone, | |
| 115 | +}; | |
| 116 | + | |
| 117 | +static const BMDVideoConnection decklink_video_connection_map[] = { | |
| 118 | + 0, | |
| 119 | + bmdVideoConnectionSDI, | |
| 120 | + bmdVideoConnectionHDMI, | |
| 121 | + bmdVideoConnectionOpticalSDI, | |
| 122 | + bmdVideoConnectionComponent, | |
| 123 | + bmdVideoConnectionComposite, | |
| 124 | + bmdVideoConnectionSVideo, | |
| 125 | +}; | |
| 105 | 126 | |
| 106 | 127 | HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName); |
| 107 | 128 | 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); |
| @@ -35,6 +35,8 @@ struct decklink_cctx { · 34 unmodified lines | ||
| 35 | 35 | int v210; |
| 36 | 36 | int audio_channels; |
| 37 | 37 | int duplex_mode; |
| 38 | + int audio_input; | |
| 39 | + int video_input; | |
| 38 | 40 | }; |
| 39 | 41 | |
| 40 | 42 | #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ |
| @@ -28,6 +28,7 @@ extern "C" { · 27 unmodified lines | ||
| 28 | 28 | #include "config.h" |
| 29 | 29 | #include "libavformat/avformat.h" |
| 30 | 30 | #include "libavformat/internal.h" |
| 31 | +#include "libavutil/common.h" | |
| 31 | 32 | #include "libavutil/imgutils.h" |
| 32 | 33 | #if CONFIG_LIBZVBI |
| 33 | 34 | #include <libzvbi.h> |
| @@ -446,6 +447,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx) · 412 unmodified lines | ||
| 446 | 447 | ctx->teletext_lines = cctx->teletext_lines; |
| 447 | 448 | ctx->preroll = cctx->preroll; |
| 448 | 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 | 454 | cctx->ctx = ctx; |
| 450 | 455 | |
| 451 | 456 | #if !CONFIG_LIBZVBI |
| @@ -40,6 +40,22 @@ static const AVOption options[] = { · 39 unmodified lines | ||
| 40 | 40 | { "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"}, |
| 41 | 41 | { "half", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1}, 0, 0, DEC, "duplex_mode"}, |
| 42 | 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 | 59 | { NULL }, |
| 44 | 60 | }; |
| 45 | 61 | |