Unified · Split
| @@ -255,6 +255,16 @@ Defaults to @samp{2}. · 254 unmodified lines | |||
| 255 | Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}. | 255 | Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}. |
| 256 | Defaults to @samp{unset}. | 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 | @end table | 268 | @end table |
| 259 | 269 | ||
| 260 | @subsection Examples | 270 | @subsection Examples |
| @@ -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 | ||
| 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 | int ff_decklink_set_format(AVFormatContext *avctx, | 130 | int 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); |
| @@ -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 | |||
| 102 | typedef uint32_t buffercount_type; | 104 | typedef uint32_t buffercount_type; |
| 103 | #endif | 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 | HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName); | 127 | HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName); |
| 107 | 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); | 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 | 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 */ |
| @@ -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_LIBZVBI | 33 | #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_LIBZVBI | 456 | #if !CONFIG_LIBZVBI |
| @@ -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 | ||