From 12b4cded53257550f7ea0ebf4f4d6a233041f12e Mon Sep 17 00:00:00 2001
From: Pierre Perick
Date: Fri, 27 Mar 2026 18:05:56 +0100
Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20add=20dual=20stream=20support=20?=
=?UTF-8?q?for=203G-B=20interface=20in=20VideoMaster?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
doc/indevs.texi | 9 ++
libavdevice/videomaster_common.c | 174 +++++++++++++++++++++++++------
libavdevice/videomaster_common.h | 24 ++++-
libavdevice/videomaster_dec.c | 156 +++++++++++++++++----------
5 files changed, 273 insertions(+), 91 deletions(-)
diff --git a/.gitignore b/.gitignore
index e810d11107f26..4c4c2653ece8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,4 @@
/src
/mapfile
/tools/python/__pycache__/
+.vscode/
\ No newline at end of file
diff --git a/doc/indevs.texi b/doc/indevs.texi
index 82d59d087c75d..009901cb74356 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -1536,6 +1536,9 @@ Set the audio sample rate in Hz to capture. This option is only used when the in
@item buffer_packing
Specifies the buffer packing format and whether to enable the FPGA's color space converter on the board. If not set, the default buffer packing is YUV422 10-bit when the Line Padding property can be enabled, or YUV422 8-bit otherwise.
+@item dual_stream
+Force the 3G-B dual stream interface when it cannot be auto-detected. A 3G Level B-DS stream received on the RX0 physical connector is split into two independent streams: one RX0 stream receives the A link and one RX1 stream receives the B link. When enabled, FFmpeg expects the two streams to be provided on consecutive channels (RX0 for the A link, RX1 for the B link). This option is only relevant for SDI 3G Level B-DS signals. An error is displayed if the selected board and channel do not support the 3G-B dual stream interface. Accepted values are @option{1} (or @option{true}) to enable dual stream mode, and @option{0} (or @option{false}) to disable it. Default is @option{false}.
+
@end table
@subsection Examples
@@ -1566,6 +1569,12 @@ Capture a video clip from the options using the ltc companion card timestamp sou
ffmpeg -channel_index 0 -board_index 0 -timestamp_source ltc_companion_card -f videomaster -i dummy -c:a copy -c:v copy output.avi
@end example
+@item
+Capture a 3G Level B-DS dual stream signal received on RX0/RX1 of board 0
+@example
+ffmpeg -f videomaster -board_index 0 -channel_index 0 -dual_stream 1 -i dummy -c:a copy -c:v copy output.avi
+@end example
+
@end itemize
@section vfwcap
diff --git a/libavdevice/videomaster_common.c b/libavdevice/videomaster_common.c
index 0259f330035fc..71866bcbcbc2e 100644
--- a/libavdevice/videomaster_common.c
+++ b/libavdevice/videomaster_common.c
@@ -333,6 +333,16 @@ static int get_nb_channels_from_audio_infoframe_and_aes_status(
*/
static VHD_CORE_BOARDPROPERTY get_passive_loopback_property(int channel_index);
+/**
+ * @brief Get the RX SDI board property from the given index
+ *
+ * @param index Index of the RX SDI
+ * @return uint32_t The RX SDI board property
+
+ */
+static uint32_t
+get_rx_sdi_board_property_clock_divisor_from_index(uint32_t index);
+
/**
* @brief Get the rx stream type Videomaster enumeration from the channel index
*
@@ -533,7 +543,8 @@ int add_device_info_into_list(VideoMasterContext *videomaster_context,
&videomaster_context->video_height,
&videomaster_context->video_frame_rate_num,
&videomaster_context->video_frame_rate_den,
- &videomaster_context->video_interlaced),
+ &videomaster_context->video_interlaced,
+ videomaster_context->dual_stream),
"", error_msg);
snprintf(error_msg, sizeof(error_msg),
@@ -887,7 +898,8 @@ int get_audio_stream_properties_from_audio_infoframe(
&videomaster_context->video_height,
&videomaster_context->video_frame_rate_num,
&videomaster_context->video_frame_rate_den,
- &videomaster_context->video_interlaced),
+ &videomaster_context->video_interlaced,
+ videomaster_context->dual_stream),
"Video stream properties retrieved successfully",
"Could not retrieve video stream properties");
@@ -1163,6 +1175,39 @@ int get_nb_channels_from_audio_infoframe_and_aes_status(
return return_code;
}
+uint32_t get_rx_sdi_board_property_clock_divisor_from_index(uint32_t index)
+{
+ switch (index)
+ {
+ case 0:
+ return VHD_SDI_BP_RX0_CLOCK_DIV;
+ case 1:
+ return VHD_SDI_BP_RX1_CLOCK_DIV;
+ case 2:
+ return VHD_SDI_BP_RX2_CLOCK_DIV;
+ case 3:
+ return VHD_SDI_BP_RX3_CLOCK_DIV;
+ case 4:
+ return VHD_SDI_BP_RX4_CLOCK_DIV;
+ case 5:
+ return VHD_SDI_BP_RX5_CLOCK_DIV;
+ case 6:
+ return VHD_SDI_BP_RX6_CLOCK_DIV;
+ case 7:
+ return VHD_SDI_BP_RX7_CLOCK_DIV;
+ case 8:
+ return VHD_SDI_BP_RX8_CLOCK_DIV;
+ case 9:
+ return VHD_SDI_BP_RX9_CLOCK_DIV;
+ case 10:
+ return VHD_SDI_BP_RX10_CLOCK_DIV;
+ case 11:
+ return VHD_SDI_BP_RX11_CLOCK_DIV;
+ default:
+ return VHD_SDI_BP_RX0_CLOCK_DIV;
+ }
+}
+
VHD_STREAMTYPE get_rx_stream_type_from_index(uint32_t index)
{
switch (index)
@@ -1455,7 +1500,7 @@ int init_audio_info(VideoMasterContext *videomaster_context,
VHD_AUDIOGROUP *audio_group = NULL;
VHD_AUDIOCHANNEL *audio_channel = NULL;
VHD_AUDIOFORMAT buffer_format = videomaster_context->audio_sample_size ==
- AV_VIDEOMASTER_SAMPLE_SIZE_16
+ AV_VIDEOMASTER_SAMPLE_SIZE_16
? VHD_AF_16
: VHD_AF_24;
uint32_t channel_count = 0;
@@ -2091,7 +2136,8 @@ int ff_videomaster_get_video_stream_properties(
AVFormatContext *avctx, HANDLE board_handle, HANDLE stream_handle,
uint32_t channel_index, enum AVVideoMasterChannelType *channel_type,
union VideoMasterVideoInfo *video_info, uint32_t *width, uint32_t *height,
- uint32_t *frame_rate_num, uint32_t *frame_rate_den, bool *interlaced)
+ uint32_t *frame_rate_num, uint32_t *frame_rate_den, bool *interlaced,
+ bool dual_stream)
{
uint32_t frame_rate = 0;
uint32_t total_width = 0;
@@ -2199,39 +2245,80 @@ int ff_videomaster_get_video_stream_properties(
}
else
{
- handle_vhd_status(
- avctx,
- VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL, channel_index,
- VHD_SDI_CP_VIDEO_STANDARD,
- (uint32_t *)&video_info->sdi.video_standard),
- "", "");
+ if (dual_stream)
+ {
+ video_info->sdi.interface = VHD_INTERFACE_3G_B_DS_425_1;
+
+ // must start the stream with correct interface to get auto
+ // detection
+ HANDLE stream_handle = NULL;
+ VHD_OpenStreamHandle(board_handle,
+ get_rx_stream_type_from_index(channel_index),
+ VHD_SDI_STPROC_JOINED, NULL, &stream_handle,
+ NULL);
+ VHD_SetStreamProperty(stream_handle, VHD_SDI_SP_INTERFACE,
+ video_info->sdi.interface);
+
+ handle_vhd_status(avctx,
+ VHD_GetStreamProperty(
+ stream_handle, VHD_SDI_SP_VIDEO_STANDARD,
+ (uint32_t *)&video_info->sdi.video_standard),
+ "", "");
+ int status = VHD_StartStream(stream_handle);
+
+ handle_vhd_status(avctx,
+ VHD_GetStreamProperty(
+ stream_handle, VHD_SDI_SP_VIDEO_STANDARD,
+ (uint32_t *)&video_info->sdi.video_standard),
+ "", "");
+
+ handle_vhd_status(
+ avctx,
+ VHD_GetBoardProperty(
+ board_handle,
+ get_rx_sdi_board_property_clock_divisor_from_index(
+ channel_index),
+ (uint32_t *)&video_info->sdi.clock_divisor),
+ "", "");
+ if (status == VHDERR_NOERROR)
+ VHD_StopStream(stream_handle);
+ VHD_CloseStreamHandle(stream_handle);
+ }
+ else
+ {
+ handle_vhd_status(
+ avctx,
+ VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL,
+ channel_index, VHD_SDI_CP_INTERFACE,
+ (uint32_t *)&video_info->sdi.interface),
+ "", "");
+ handle_vhd_status(avctx,
+ VHD_GetChannelProperty(
+ board_handle, VHD_RX_CHANNEL, channel_index,
+ VHD_SDI_CP_VIDEO_STANDARD,
+ (uint32_t *)&video_info->sdi.video_standard),
+ "", "");
+
+ handle_vhd_status(avctx,
+ VHD_GetChannelProperty(
+ board_handle, VHD_RX_CHANNEL, channel_index,
+ VHD_SDI_CP_CLOCK_DIVISOR,
+ (uint32_t *)&video_info->sdi.clock_divisor),
+ "", "");
+
+ handle_vhd_status(
+ avctx,
+ VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL,
+ channel_index, VHD_SDI_CP_GENLOCK_OFFSET,
+ &video_info->sdi.genlock_offset),
+ "", "");
+ }
handle_vhd_status(avctx,
VHD_GetVideoCharacteristics(
video_info->sdi.video_standard, width, height,
(BOOL32 *)interlaced, &frame_rate),
"", "");
- handle_vhd_status(
- avctx,
- VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL, channel_index,
- VHD_SDI_CP_CLOCK_DIVISOR,
- (uint32_t *)&video_info->sdi.clock_divisor),
- "", "");
-
- handle_vhd_status(
- avctx,
- VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL, channel_index,
- VHD_SDI_CP_INTERFACE,
- (uint32_t *)&video_info->sdi.interface),
- "", "");
-
- handle_vhd_status(
- avctx,
- VHD_GetChannelProperty(board_handle, VHD_RX_CHANNEL, channel_index,
- VHD_SDI_CP_GENLOCK_OFFSET,
- &video_info->sdi.genlock_offset),
- "", "");
-
*frame_rate_num = frame_rate * 1000;
switch (video_info->sdi.clock_divisor)
{
@@ -2255,6 +2342,29 @@ int ff_videomaster_get_video_stream_properties(
return 0;
}
+bool ff_videomaster_is_3g_b_ds_interface_supported(
+ VideoMasterContext *videomaster_context)
+{
+ bool interface_supported = false;
+ enum AVVideoMasterChannelType channel_type =
+ ff_videomaster_get_channel_type_from_index(
+ videomaster_context->avctx, videomaster_context->board_handle,
+ videomaster_context->channel_index);
+ if (videomaster_context->board_handle &&
+ channel_type == AV_VIDEOMASTER_CHANNEL_SDI)
+ VHD_GetBoardCapSDIInterface(videomaster_context->board_handle,
+ get_rx_stream_type_from_index(
+ videomaster_context->channel_index),
+ VHD_INTERFACE_3G_B_DS_425_1,
+ (BOOL32 *)&interface_supported);
+ else
+ {
+ av_log(videomaster_context->avctx, AV_LOG_ERROR,
+ "Board handle is missing or channel type is not SDI\n");
+ }
+ return interface_supported;
+}
+
bool ff_videomaster_is_channel_locked(VideoMasterContext *videomaster_context)
{
bool channel_locked = false;
@@ -2428,7 +2538,7 @@ const char *ff_videomaster_sample_size_to_string(
int ff_videomaster_start_stream(VideoMasterContext *videomaster_context)
{
int av_error = 0;
- int has_field_merge_capability = 0;
+ int has_field_merge_capability = 0;
const VideoMasterBufferPackingInfo *info = NULL;
av_log(videomaster_context->avctx, AV_LOG_TRACE,
"ff_videomaster_start_stream: IN\n");
diff --git a/libavdevice/videomaster_common.h b/libavdevice/videomaster_common.h
index 0eecd56573d74..7695c2a2f108b 100644
--- a/libavdevice/videomaster_common.h
+++ b/libavdevice/videomaster_common.h
@@ -234,7 +234,9 @@ typedef struct VideoMasterContext
enum AVVideoMasterChannelType
channel_type; ///< type of the channel (HDMI or SDI)
enum AVVideoMasterTimeStampType
- timestamp_source; ///< source of the timestamp
+ timestamp_source; ///< source of the timestamp
+ bool dual_stream; ///< true if the stream must be configured with 3GB-DS
+ ///< interface
uint32_t api_version; ///< API version
uint32_t number_of_boards; ///< number of boards detected
@@ -318,6 +320,8 @@ typedef struct VideoMasterData
int64_t sample_rate; ///< sample rate of the audio stream
int64_t sample_size; ///< bits per sample in the audio stream
int64_t buffer_packing; ///< buffer packing format
+ bool dual_stream; ///< true if the stream must be configured with 3GB-DS
+ ///< interface
} VideoMasterData;
/**
@@ -546,6 +550,8 @@ int ff_videomaster_get_timestamp(VideoMasterContext *videomaster_context,
* @param frame_rate_den Pointer to store the denominator of the frame rate of
* the video stream.
* @param interlaced Pointer to store whether the video stream is interlaced.
+ * @param dual_stream Indicates whether the stream must be configured with 3G B
+ * DS interface instead of auto-detect one.
*
* @return 0 on success, or a negative AVERROR code on failure.
*/
@@ -553,7 +559,17 @@ int ff_videomaster_get_video_stream_properties(
AVFormatContext *avctx, HANDLE board_handle, HANDLE stream_handle,
uint32_t channel_index, enum AVVideoMasterChannelType *channel_type,
union VideoMasterVideoInfo *video_info, uint32_t *width, uint32_t *height,
- uint32_t *frame_rate_num, uint32_t *frame_rate_den, bool *interlaced);
+ uint32_t *frame_rate_num, uint32_t *frame_rate_den, bool *interlaced,
+ bool dual_stream);
+
+/**
+ * @brief Checks if 3G-B DS interface is supported on the VideoMaster device.
+ *
+ * @param videomaster_context The VideoMaster context to use.
+ * @return true if 3G-B DS interface is supported, false otherwise.
+ */
+bool ff_videomaster_is_3g_b_ds_interface_supported(
+ VideoMasterContext *videomaster_context);
/**
* @brief Checks if the channel is locked on the VideoMaster device.
@@ -611,8 +627,8 @@ bool ff_videomaster_is_ltc_on_board_timestamp_supported(
* @brief Opens a handle to the VideoMaster board.
*
* This function initializes and opens a handle to the VideoMaster board
- * specified by the board index board_index in the provided VideoMaster context.
- * The handle is used for subsequent operations on the board.
+ * specified by the board index board_index in the provided VideoMaster
+ * context. The handle is used for subsequent operations on the board.
*
* @param videomaster_context The VideoMaster context to use.
* @return 0 on success, or negative AVERROR code on failure:
diff --git a/libavdevice/videomaster_dec.c b/libavdevice/videomaster_dec.c
index 6d9a87e045993..19a94bba67195 100644
--- a/libavdevice/videomaster_dec.c
+++ b/libavdevice/videomaster_dec.c
@@ -24,7 +24,6 @@
#endif
#define OFFSET(x) offsetof(struct VideoMasterData, x)
-#define DEC AV_OPT_FLAG_DECODING_PARAM
/** Static function declaration */
/**
@@ -218,6 +217,30 @@ int check_board_index(VideoMasterContext *videomaster_context)
return 0;
}
+int check_dual_stream(VideoMasterContext *videomaster_context)
+{
+ if (videomaster_context->dual_stream &&
+ !ff_videomaster_is_3g_b_ds_interface_supported(videomaster_context))
+ {
+ av_log(videomaster_context->avctx, AV_LOG_ERROR,
+ "3G-B DS interface is not supported on this device and for this "
+ "channel. Dual-stream "
+ "mode cannot be enabled.\n");
+ return AVERROR(EINVAL);
+ }
+ else if (videomaster_context->dual_stream)
+ {
+ av_log(videomaster_context->avctx, AV_LOG_TRACE,
+ "3G-B Dual-Stream interface enabled\n");
+ }
+ else
+ {
+ av_log(videomaster_context->avctx, AV_LOG_TRACE,
+ "3G-B Dual-Stream interface disabled\n");
+ }
+ return 0;
+}
+
int check_channel_index(VideoMasterContext *videomaster_context)
{
videomaster_context->has_video = false;
@@ -233,7 +256,8 @@ int check_channel_index(VideoMasterContext *videomaster_context)
videomaster_context->channel_index);
return AVERROR(EINVAL);
}
- else if (!ff_videomaster_is_channel_locked(videomaster_context))
+ else if (!ff_videomaster_is_channel_locked(videomaster_context) &&
+ !videomaster_context->dual_stream)
{
av_log(videomaster_context->avctx, AV_LOG_TRACE,
"Channel %d is not locked\n",
@@ -255,7 +279,8 @@ int check_channel_index(VideoMasterContext *videomaster_context)
&videomaster_context->video_height,
&videomaster_context->video_frame_rate_num,
&videomaster_context->video_frame_rate_den,
- &videomaster_context->video_interlaced) == 0)
+ &videomaster_context->video_interlaced,
+ videomaster_context->dual_stream) == 0)
{
videomaster_context->has_video = true;
float frame_rate =
@@ -410,7 +435,6 @@ int check_channel_index(VideoMasterContext *videomaster_context)
int check_header_arguments(VideoMasterContext *videomaster_context)
{
-
if (check_board_index(videomaster_context) != 0)
{
av_log(videomaster_context->avctx, AV_LOG_ERROR,
@@ -426,6 +450,15 @@ int check_header_arguments(VideoMasterContext *videomaster_context)
return AVERROR(EIO);
}
+ if (check_dual_stream(videomaster_context) != 0)
+ {
+ av_log(videomaster_context->avctx, AV_LOG_ERROR,
+ "Failed to check dual-stream integrity\n");
+ ff_videomaster_close_stream_handle(videomaster_context);
+ ff_videomaster_close_board_handle(videomaster_context);
+ return AVERROR(EIO);
+ }
+
if (check_channel_index(videomaster_context) != 0)
{
av_log(videomaster_context->avctx, AV_LOG_ERROR,
@@ -670,6 +703,7 @@ int parse_command_line_arguments(AVFormatContext *avctx)
videomaster_context->video_buffer_packing =
videomaster_data->buffer_packing;
+ videomaster_context->dual_stream = videomaster_data->dual_stream;
}
av_log(avctx, AV_LOG_INFO,
@@ -1028,7 +1062,7 @@ static const AVOption options[] = {
{ .i64 = -1 },
-1,
INT_MAX,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
NULL },
{ "channel_index",
@@ -1041,7 +1075,7 @@ static const AVOption options[] = {
{ .i64 = -1 },
-1,
INT_MAX,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
NULL },
{ "timestamp_source",
@@ -1055,7 +1089,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_OSCILLATOR },
AV_VIDEOMASTER_TIMESTAMP_OSCILLATOR,
AV_VIDEOMASTER_TIMESTAMP_NB - 1,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "osc",
@@ -1065,7 +1099,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_OSCILLATOR },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "system",
@@ -1075,7 +1109,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_SYSTEM },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "hw",
@@ -1085,7 +1119,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_HARDWARE },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "ltc_on_board",
@@ -1095,7 +1129,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_LTC_ON_BOARD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "ltc_companion_card",
@@ -1105,7 +1139,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_TIMESTAMP_LTC_COMPANION_CARD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM |
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM |
AV_OPT_FLAG_AUDIO_PARAM,
.unit = "timestamp_source" },
{ "nb_channels",
@@ -1118,7 +1152,7 @@ static const AVOption options[] = {
{ .i64 = -1 },
-1,
INT_MAX,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
NULL },
{
"sample_rate",
@@ -1131,7 +1165,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_RATE_UNKNOWN },
AV_VIDEOMASTER_SAMPLE_RATE_UNKNOWN,
AV_VIDEOMASTER_SAMPLE_RATE_48000,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_rate_value",
},
{ "48000",
@@ -1141,7 +1175,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_RATE_48000 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_rate_value" },
{ "44100",
NULL,
@@ -1150,7 +1184,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_RATE_44100 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_rate_value" },
{ "32000",
NULL,
@@ -1159,7 +1193,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_RATE_32000 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_rate_value" },
{
"sample_size",
@@ -1173,7 +1207,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_SIZE_UNKNOWN },
AV_VIDEOMASTER_SAMPLE_SIZE_UNKNOWN,
AV_VIDEOMASTER_SAMPLE_SIZE_24,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_size_value",
},
{ "16",
@@ -1183,7 +1217,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_SIZE_16 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_size_value" },
{ "24",
NULL,
@@ -1192,7 +1226,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_SAMPLE_SIZE_24 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_AUDIO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM,
.unit = "sample_size_value" },
{
"buffer_packing",
@@ -1205,7 +1239,7 @@ static const AVOption options[] = {
{ .i64 = AV_NB_VIDEOMASTER_BUFFER_PACKINGS },
0,
AV_NB_VIDEOMASTER_BUFFER_PACKINGS,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value",
},
{ "YUV422_8",
@@ -1215,7 +1249,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV422_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUVK4224_8",
NULL,
@@ -1224,7 +1258,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUVK4224_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUV422_10",
NULL,
@@ -1233,7 +1267,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV422_10 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUVK4224_10",
NULL,
@@ -1242,7 +1276,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUVK4224_10 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUV4444_8",
NULL,
@@ -1251,7 +1285,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV4444_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUVK4444_8",
NULL,
@@ -1260,7 +1294,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUVK4444_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUV444_10",
NULL,
@@ -1269,7 +1303,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV444_10 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUVK4444_10",
NULL,
@@ -1278,7 +1312,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUVK4444_10 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGB_32",
NULL,
@@ -1287,7 +1321,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGB_32 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGBA_32",
NULL,
@@ -1296,7 +1330,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGBA_32 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGB_24",
NULL,
@@ -1305,7 +1339,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGB_24 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU420_8",
NULL,
@@ -1314,7 +1348,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU420_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV420_8",
NULL,
@@ -1323,7 +1357,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV420_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU420_10_MSB_PAD",
NULL,
@@ -1332,7 +1366,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU420_10_MSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU420_10_LSB_PAD",
NULL,
@@ -1341,7 +1375,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU420_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV420_10_MSB_PAD",
NULL,
@@ -1350,7 +1384,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV420_10_MSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV420_10_LSB_PAD",
NULL,
@@ -1359,7 +1393,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV420_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGB_64",
NULL,
@@ -1368,7 +1402,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGB_64 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUV422_16",
NULL,
@@ -1377,7 +1411,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV422_16 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "YUV444_8",
NULL,
@@ -1386,7 +1420,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV444_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "ICTCP_422_8",
NULL,
@@ -1395,7 +1429,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_ICTCP_422_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "ICTCP_422_10",
NULL,
@@ -1404,7 +1438,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_ICTCP_422_10 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV422_10_LSB_PAD",
NULL,
@@ -1413,7 +1447,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV422_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV422_10_MSB_PAD",
NULL,
@@ -1422,7 +1456,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV422_10_MSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU422_10_LSB_PAD",
NULL,
@@ -1431,7 +1465,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU422_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU422_10_MSB_PAD",
NULL,
@@ -1440,7 +1474,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU422_10_MSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV422_8",
NULL,
@@ -1449,7 +1483,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YUV422_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YVU422_8",
NULL,
@@ -1458,7 +1492,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_YVU422_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_YUV422_10_NOPAD_BIGEND",
NULL,
@@ -1467,7 +1501,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_YUV422_10_NOPAD_BIGEND },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_PALETTE_RGBA_8",
NULL,
@@ -1476,7 +1510,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PALETTE_RGBA_8 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_NV12",
NULL,
@@ -1485,7 +1519,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_NV12 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "PLANAR_RGB444_10_LSB_PAD",
NULL,
@@ -1494,7 +1528,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_PLANAR_RGB444_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGBA4444_10_LSB_PAD",
NULL,
@@ -1503,7 +1537,7 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGBA4444_10_LSB_PAD },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
{ "RGBA4444_16",
NULL,
@@ -1512,8 +1546,20 @@ static const AVOption options[] = {
{ .i64 = AV_VIDEOMASTER_BUFFER_PACKING_RGBA4444_16 },
0,
0,
- AV_OPT_FLAG_DECODING_PARAM | DEC | AV_OPT_FLAG_VIDEO_PARAM,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
.unit = "buffer_packing_value" },
+ { "dual_stream",
+ "Force 3GB dual stream interface (that cannot be auto-detect). A 3G "
+ "Level B-DS stream received on the RX0 physicla connector is received by "
+ "two independant streams: one RX0 stream received the A link and one RX1 "
+ "stream received the B link.",
+ OFFSET(dual_stream),
+ AV_OPT_TYPE_BOOL,
+ { .i64 = 0 },
+ 0,
+ 1,
+ AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM,
+ NULL },
{ NULL },
};