mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
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>
This commit is contained in:
parent
8f9fa49bd8
commit
da89c6e37c
@ -255,6 +255,16 @@ Defaults to @samp{2}.
|
|||||||
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
|
Sets the decklink device duplex mode. Must be @samp{unset}, @samp{half} or @samp{full}.
|
||||||
Defaults to @samp{unset}.
|
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
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
|
@ -98,6 +98,35 @@ HRESULT ff_decklink_get_display_name(IDeckLink *This, const char **displayName)
|
|||||||
return hr;
|
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 ff_decklink_set_format(AVFormatContext *avctx,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int tb_num, int tb_den,
|
int tb_num, int tb_den,
|
||||||
@ -129,6 +158,13 @@ int ff_decklink_set_format(AVFormatContext *avctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (direction == DIRECTION_IN) {
|
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);
|
res = ctx->dli->GetDisplayModeIterator (&itermode);
|
||||||
} else {
|
} else {
|
||||||
res = ctx->dlo->GetDisplayModeIterator (&itermode);
|
res = ctx->dlo->GetDisplayModeIterator (&itermode);
|
||||||
@ -224,6 +260,13 @@ int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direct
|
|||||||
HRESULT res;
|
HRESULT res;
|
||||||
|
|
||||||
if (direction == DIRECTION_IN) {
|
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);
|
res = ctx->dli->GetDisplayModeIterator (&itermode);
|
||||||
} else {
|
} else {
|
||||||
res = ctx->dlo->GetDisplayModeIterator (&itermode);
|
res = ctx->dlo->GetDisplayModeIterator (&itermode);
|
||||||
|
@ -53,6 +53,8 @@ struct decklink_ctx {
|
|||||||
BMDTimeValue bmd_tb_den;
|
BMDTimeValue bmd_tb_den;
|
||||||
BMDTimeValue bmd_tb_num;
|
BMDTimeValue bmd_tb_num;
|
||||||
BMDDisplayMode bmd_mode;
|
BMDDisplayMode bmd_mode;
|
||||||
|
BMDVideoConnection video_input;
|
||||||
|
BMDAudioConnection audio_input;
|
||||||
int bmd_width;
|
int bmd_width;
|
||||||
int bmd_height;
|
int bmd_height;
|
||||||
int bmd_field_dominance;
|
int bmd_field_dominance;
|
||||||
@ -102,6 +104,25 @@ IDeckLinkIterator *CreateDeckLinkIteratorInstance(void);
|
|||||||
typedef uint32_t buffercount_type;
|
typedef uint32_t buffercount_type;
|
||||||
#endif
|
#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);
|
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);
|
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 {
|
|||||||
int v210;
|
int v210;
|
||||||
int audio_channels;
|
int audio_channels;
|
||||||
int duplex_mode;
|
int duplex_mode;
|
||||||
|
int audio_input;
|
||||||
|
int video_input;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
|
#endif /* AVDEVICE_DECKLINK_COMMON_C_H */
|
||||||
|
@ -28,6 +28,7 @@ extern "C" {
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "libavformat/avformat.h"
|
#include "libavformat/avformat.h"
|
||||||
#include "libavformat/internal.h"
|
#include "libavformat/internal.h"
|
||||||
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
#if CONFIG_LIBZVBI
|
#if CONFIG_LIBZVBI
|
||||||
#include <libzvbi.h>
|
#include <libzvbi.h>
|
||||||
@ -446,6 +447,10 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
|
|||||||
ctx->teletext_lines = cctx->teletext_lines;
|
ctx->teletext_lines = cctx->teletext_lines;
|
||||||
ctx->preroll = cctx->preroll;
|
ctx->preroll = cctx->preroll;
|
||||||
ctx->duplex_mode = cctx->duplex_mode;
|
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;
|
cctx->ctx = ctx;
|
||||||
|
|
||||||
#if !CONFIG_LIBZVBI
|
#if !CONFIG_LIBZVBI
|
||||||
|
@ -40,6 +40,22 @@ static const AVOption options[] = {
|
|||||||
{ "unset", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0}, 0, 0, DEC, "duplex_mode"},
|
{ "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"},
|
{ "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"},
|
{ "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 },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user