mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
audioconvert: add possibility to reorder input channels
When audioconvert has unpositionned audio channels as input it can now use reordering configurations to automatically position those channels. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5923>
This commit is contained in:
parent
40f7d7f1f7
commit
8fb96253be
5 changed files with 1510 additions and 22 deletions
|
@ -865,6 +865,30 @@
|
|||
"type": "guint",
|
||||
"writable": true
|
||||
},
|
||||
"input-channels-reorder": {
|
||||
"blurb": "The positions configuration to use to reorder the input channels consecutively according to their index.",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "gst (0)",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "GstAudioConvertInputChannelsReorder",
|
||||
"writable": true
|
||||
},
|
||||
"input-channels-reorder-mode": {
|
||||
"blurb": "The input channels reordering mode used to apply the selected positions configuration.",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "none (0)",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "GstAudioConvertInputChannelsReorderMode",
|
||||
"writable": true
|
||||
},
|
||||
"mix-matrix": {
|
||||
"blurb": "Transformation matrix for input/output channels.",
|
||||
"conditionally-available": false,
|
||||
|
@ -894,7 +918,68 @@
|
|||
},
|
||||
"filename": "gstaudioconvert",
|
||||
"license": "LGPL",
|
||||
"other-types": {},
|
||||
"other-types": {
|
||||
"GstAudioConvertInputChannelsReorder": {
|
||||
"kind": "enum",
|
||||
"values": [
|
||||
{
|
||||
"desc": "Reorder the input channels using the default GStreamer order",
|
||||
"name": "gst",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder the input channels using the SMPTE order",
|
||||
"name": "smpte",
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder the input channels using the CINE order",
|
||||
"name": "cine",
|
||||
"value": "2"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder the input channels using the AC3 order",
|
||||
"name": "ac3",
|
||||
"value": "3"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder the input channels using the AAC order",
|
||||
"name": "aac",
|
||||
"value": "4"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder and mix all input channels to a single mono channel",
|
||||
"name": "mono",
|
||||
"value": "5"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder and mix all input channels to a single left and a single right stereo channels alternately",
|
||||
"name": "alternate",
|
||||
"value": "6"
|
||||
}
|
||||
]
|
||||
},
|
||||
"GstAudioConvertInputChannelsReorderMode": {
|
||||
"kind": "enum",
|
||||
"values": [
|
||||
{
|
||||
"desc": "Never reorder the input channels",
|
||||
"name": "none",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"desc": "Reorder the input channels only if they are unpositioned",
|
||||
"name": "unpositioned",
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"desc": "Always reorder the input channels according to the selected configuration",
|
||||
"name": "force",
|
||||
"value": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"package": "GStreamer Base Plug-ins",
|
||||
"source": "gst-plugins-base",
|
||||
"tracers": {},
|
||||
|
|
|
@ -631,6 +631,75 @@ gst_audio_channel_mixer_fill_special (gfloat ** matrix, gint in_channels,
|
|||
* Automagically generate conversion matrix.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_NONE = 0,
|
||||
GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_MONO,
|
||||
GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_STEREO
|
||||
} GstAudioChannelMixerVirtualInput;
|
||||
|
||||
/* Detects specific input channels configurations introduced in the
|
||||
* audioconvert element (since version 1.26) with the
|
||||
* `GstAudioConvertInputChannelsReorder` configurations.
|
||||
*
|
||||
* If all input channels are positioned to GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
* the automatic mixing matrix should be configured like if there was only one
|
||||
* virtual input mono channel. This virtual mono channel is the mix of all the
|
||||
* real mono channels.
|
||||
*
|
||||
* If all input channels with an even index are positioned to
|
||||
* GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT and all input channels with an odd
|
||||
* index are positioned to GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, then the
|
||||
* automatic mixing matrix should be configured like if there were only one
|
||||
* virtual input left channel and one virtual input right channel. This virtual
|
||||
* left or right channel is the mix of all the real left or right channels.
|
||||
*/
|
||||
static gboolean
|
||||
gst_audio_channel_mixer_detect_virtual_input_channels (gint channels,
|
||||
GstAudioChannelPosition * position,
|
||||
GstAudioChannelMixerVirtualInput * virtual_input)
|
||||
{
|
||||
g_return_val_if_fail (position != NULL, FALSE);
|
||||
g_return_val_if_fail (virtual_input != NULL, FALSE);
|
||||
|
||||
*virtual_input = GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_NONE;
|
||||
|
||||
if (channels < 2)
|
||||
return FALSE;
|
||||
|
||||
static const GstAudioChannelPosition alternate_positions[2] =
|
||||
{ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT
|
||||
};
|
||||
|
||||
gboolean is_mono = TRUE;
|
||||
gboolean is_alternate = TRUE;
|
||||
for (gint i = 0; i < channels; ++i) {
|
||||
if (position[i] != GST_AUDIO_CHANNEL_POSITION_MONO)
|
||||
is_mono = FALSE;
|
||||
|
||||
if (position[i] != alternate_positions[i % 2])
|
||||
is_alternate = FALSE;
|
||||
|
||||
if (!is_mono && !is_alternate)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (is_mono) {
|
||||
g_assert (!is_alternate);
|
||||
*virtual_input = GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_MONO;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (is_alternate && (channels > 2)) {
|
||||
g_assert (!is_mono);
|
||||
*virtual_input = GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_STEREO;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audio_channel_mixer_fill_matrix (gfloat ** matrix,
|
||||
GstAudioChannelMixerFlags flags, gint in_channels,
|
||||
|
@ -641,15 +710,71 @@ gst_audio_channel_mixer_fill_matrix (gfloat ** matrix,
|
|||
out_channels, out_position))
|
||||
return;
|
||||
|
||||
gst_audio_channel_mixer_fill_identical (matrix, in_channels, in_position,
|
||||
/* If all input channels are positioned to mono, the mix matrix should be
|
||||
* configured like if there was only one virtual input mono channel. This
|
||||
* virtual mono channel is the mix of all the real input mono channels.
|
||||
*
|
||||
* If all input channels are positioned to left and right alternately, the mix
|
||||
* matrix should be configured like if there were only two virtual input
|
||||
* channels: one left and one right. This virtual left or right channel is the
|
||||
* mix of all the real input left or right channels.
|
||||
*/
|
||||
gint in_size = in_channels;
|
||||
GstAudioChannelMixerVirtualInput virtual_input =
|
||||
GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_NONE;
|
||||
if (gst_audio_channel_mixer_detect_virtual_input_channels (in_size,
|
||||
in_position, &virtual_input)) {
|
||||
switch (virtual_input) {
|
||||
case GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_MONO:
|
||||
in_size = 1;
|
||||
break;
|
||||
case GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_STEREO:
|
||||
in_size = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gst_audio_channel_mixer_fill_identical (matrix, in_size, in_position,
|
||||
out_channels, out_position, flags);
|
||||
|
||||
if (!(flags & GST_AUDIO_CHANNEL_MIXER_FLAGS_UNPOSITIONED_IN)) {
|
||||
gst_audio_channel_mixer_fill_compatible (matrix, in_channels, in_position,
|
||||
gst_audio_channel_mixer_fill_compatible (matrix, in_size, in_position,
|
||||
out_channels, out_position);
|
||||
gst_audio_channel_mixer_fill_others (matrix, in_channels, in_position,
|
||||
gst_audio_channel_mixer_fill_others (matrix, in_size, in_position,
|
||||
out_channels, out_position);
|
||||
gst_audio_channel_mixer_fill_normalize (matrix, in_channels, out_channels);
|
||||
gst_audio_channel_mixer_fill_normalize (matrix, in_size, out_channels);
|
||||
}
|
||||
|
||||
switch (virtual_input) {
|
||||
case GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_MONO:{
|
||||
for (gint out = 0; out < out_channels; ++out)
|
||||
matrix[0][out] /= in_channels;
|
||||
|
||||
for (gint in = 1; in < in_channels; ++in)
|
||||
memcpy (matrix[in], matrix[0], out_channels * sizeof (gfloat));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GST_AUDIO_CHANNEL_MIXER_VIRTUAL_INPUT_STEREO:{
|
||||
gint right_channels = in_channels >> 1;
|
||||
gint left_channels = right_channels + (in_channels % 2);
|
||||
|
||||
for (gint out = 0; out < out_channels; ++out) {
|
||||
matrix[0][out] /= left_channels;
|
||||
matrix[1][out] /= right_channels;
|
||||
}
|
||||
|
||||
for (gint in = 2; in < in_channels; ++in)
|
||||
memcpy (matrix[in], matrix[in % 2], out_channels * sizeof (gfloat));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,31 @@
|
|||
* |[
|
||||
* gst-launch-1.0 -v audiotestsrc ! audio/x-raw,channels=8 ! audioconvert mix-matrix="<>" ! audio/x-raw,channels=16,channel-mask=\(bitmask\)0x0000000000000000 ! fakesink
|
||||
* ]|
|
||||
*
|
||||
* If input channels are unpositioned but follow a standard layout, they can be
|
||||
* automatically positioned according to their index using one of the reorder
|
||||
* configurations.
|
||||
*
|
||||
* ## Example with unpositioned input channels reordering
|
||||
* |[
|
||||
* gst-launch-1.0 -v audiotestsrc ! audio/x-raw,channels=6,channel-mask=\(bitmask\)0x0000000000000000 ! audioconvert input-channels-reorder-mode=unpositioned input-channels-reorder=smpte ! fakesink
|
||||
* ]|
|
||||
* In this case the input channels will be automatically positioned to the
|
||||
* SMPTE order (left, right, center, lfe, rear-left and rear-right).
|
||||
*
|
||||
* The input channels reorder configurations can also be used to force the
|
||||
* repositioning of the input channels when needed, for example when channels'
|
||||
* positions are not correctly identified in an encoded file.
|
||||
*
|
||||
* ## Example with the forced reordering of input channels wrongly positioned
|
||||
* |[
|
||||
* gst-launch-1.0 -v audiotestsrc ! audio/x-raw,channels=3,channel-mask=\(bitmask\)0x0000000000000034 ! audioconvert input-channels-reorder-mode=force input-channels-reorder=aac ! fakesink
|
||||
* ]|
|
||||
* In this case the input channels are positioned upstream as center,
|
||||
* rear-left and rear-right in this order. Using the "force" reorder mode and
|
||||
* the "aac" order, the input channels are going to be repositioned to left,
|
||||
* right and lfe, ignoring the actual value of the `channel-mask` in the input
|
||||
* caps.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -158,7 +183,9 @@ enum
|
|||
PROP_DITHERING,
|
||||
PROP_NOISE_SHAPING,
|
||||
PROP_MIX_MATRIX,
|
||||
PROP_DITHERING_THRESHOLD
|
||||
PROP_DITHERING_THRESHOLD,
|
||||
PROP_INPUT_CHANNELS_REORDER,
|
||||
PROP_INPUT_CHANNELS_REORDER_MODE
|
||||
};
|
||||
|
||||
#define DEBUG_INIT \
|
||||
|
@ -192,6 +219,80 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
static GQuark meta_tag_audio_quark;
|
||||
|
||||
/*** TYPE FUNCTIONS ***********************************************************/
|
||||
|
||||
#define GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER (gst_audio_convert_input_channels_reorder_get_type ())
|
||||
|
||||
static GType
|
||||
gst_audio_convert_input_channels_reorder_get_type (void)
|
||||
{
|
||||
static GType reorder_type = 0;
|
||||
|
||||
if (g_once_init_enter (&reorder_type)) {
|
||||
static GEnumValue reorder_types[] = {
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST,
|
||||
"Reorder the input channels using the default GStreamer order",
|
||||
"gst"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE,
|
||||
"Reorder the input channels using the SMPTE order",
|
||||
"smpte"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE,
|
||||
"Reorder the input channels using the CINE order",
|
||||
"cine"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3,
|
||||
"Reorder the input channels using the AC3 order",
|
||||
"ac3"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC,
|
||||
"Reorder the input channels using the AAC order",
|
||||
"aac"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO,
|
||||
"Reorder and mix all input channels to a single mono channel",
|
||||
"mono"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE,
|
||||
"Reorder and mix all input channels to a single left and a single right stereo channels alternately",
|
||||
"alternate"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
GType type = g_enum_register_static ("GstAudioConvertInputChannelsReorder",
|
||||
reorder_types);
|
||||
|
||||
g_once_init_leave (&reorder_type, type);
|
||||
}
|
||||
|
||||
return reorder_type;
|
||||
}
|
||||
|
||||
#define GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE (gst_audio_convert_input_channels_reorder_mode_get_type ())
|
||||
|
||||
static GType
|
||||
gst_audio_convert_input_channels_reorder_mode_get_type (void)
|
||||
{
|
||||
static GType reorder_mode_type = 0;
|
||||
|
||||
if (g_once_init_enter (&reorder_mode_type)) {
|
||||
static GEnumValue reorder_mode_types[] = {
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE,
|
||||
"Never reorder the input channels",
|
||||
"none"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED,
|
||||
"Reorder the input channels only if they are unpositioned",
|
||||
"unpositioned"},
|
||||
{GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE,
|
||||
"Always reorder the input channels according to the selected configuration",
|
||||
"force"},
|
||||
{0, NULL, NULL},
|
||||
};
|
||||
|
||||
GType type =
|
||||
g_enum_register_static ("GstAudioConvertInputChannelsReorderMode",
|
||||
reorder_mode_types);
|
||||
|
||||
g_once_init_leave (&reorder_mode_type, type);
|
||||
}
|
||||
|
||||
return reorder_mode_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_audio_convert_class_init (GstAudioConvertClass * klass)
|
||||
{
|
||||
|
@ -246,6 +347,53 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
|
|||
"Threshold for the output bit depth at/below which to apply dithering.",
|
||||
0, 32, 20, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstAudioConvert:input-channels-reorder:
|
||||
*
|
||||
* The positions configuration to use to reorder the input channels
|
||||
* consecutively according to their index. If a `mix-matrix` is specified,
|
||||
* this configuration is ignored.
|
||||
*
|
||||
* When the input channels reordering is activated (because the
|
||||
* `input-channels-reorder-mode` property is
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE or the input channels
|
||||
* are unpositioned and the reorder mode is
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED), input
|
||||
* channels will be reordered consecutively according to their index
|
||||
* independently of the `channel-mask` value in the sink pad audio caps.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_CHANNELS_REORDER,
|
||||
g_param_spec_enum ("input-channels-reorder",
|
||||
"Input Channels Reorder",
|
||||
"The positions configuration to use to reorder the input channels consecutively according to their index.",
|
||||
GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
gst_type_mark_as_plugin_api (GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER,
|
||||
0);
|
||||
|
||||
/**
|
||||
* GstAudioConvert:input-channels-reorder-mode:
|
||||
*
|
||||
* The input channels reordering mode used to apply the selected positions
|
||||
* configuration.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_INPUT_CHANNELS_REORDER_MODE,
|
||||
g_param_spec_enum ("input-channels-reorder-mode",
|
||||
"Input Channels Reorder Mode",
|
||||
"The input channels reordering mode used to apply the selected positions configuration.",
|
||||
GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
gst_type_mark_as_plugin_api
|
||||
(GST_TYPE_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE, 0);
|
||||
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
&gst_audio_convert_src_template);
|
||||
gst_element_class_add_static_pad_template (element_class,
|
||||
|
@ -304,6 +452,574 @@ gst_audio_convert_dispose (GObject * obj)
|
|||
G_OBJECT_CLASS (parent_class)->dispose (obj);
|
||||
}
|
||||
|
||||
/*** INPUT CHANNELS REORDER FUNCTIONS *****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gboolean has_stereo;
|
||||
gboolean lfe_as_last_channel;
|
||||
} GstAudioConvertInputChannelsReorderConfig;
|
||||
|
||||
static const GstAudioConvertInputChannelsReorderConfig
|
||||
input_channels_reorder_config[] = {
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST
|
||||
{TRUE, FALSE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE
|
||||
{TRUE, FALSE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE
|
||||
{TRUE, TRUE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3
|
||||
{TRUE, TRUE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC
|
||||
{TRUE, TRUE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO
|
||||
{FALSE, FALSE},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE
|
||||
{TRUE, FALSE}
|
||||
};
|
||||
|
||||
#define GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_NB G_N_ELEMENTS (input_channels_reorder_config)
|
||||
|
||||
static const GstAudioChannelPosition
|
||||
channel_position_per_reorder_config
|
||||
[GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_NB][64] = {
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE1,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE2,
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE (see: https://www.sis.se/api/document/preview/919377/)
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // Left front (L)
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // Right front (R)
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, // Center front (C)
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE1, // Low frequency enhancement (LFE)
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, // Left surround (Ls)
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, // Right surround (Rs)
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, // Left front center (Lc)
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, // Right front center (Rc)
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, // Rear surround left (Lsr)
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, // Rear surround right (Rsr)
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, // Rear center (Cs)
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, // Left side surround (Lss)
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, // Right side surround (Rss)
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, // Left wide front (Lw)
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, // Right wide front (Rw)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, // Left front vertical height (Lv)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, // Right front vertical height (Rv)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, // Center front vertical height (Cv)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, // Left surround vertical height rear (Lvr)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, // Right surround vertical height rear (Rvr)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, // Center vertical height rear (Cvr)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT, // Left vertical height side surround (Lvss)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT, // Right vertical height side surround (Rvss)
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, // Top center surround (Ts)
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE2, // Low frequency enhancement 2 (LFE2)
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT, // Left front vertical bottom (Lb)
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT, // Right front vertical bottom (Rb)
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER, // Center front vertical bottom (Cb)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Left vertical height surround (Lvs)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Right vertical height surround (Rvs)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Reserved
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Reserved
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Reserved
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Reserved
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Low frequency enhancement 3 (LFE3)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Left edge of screen (Leos)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Right edge of screen (Reos)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Half-way between center of screen and left edge of screen (Hwbcal)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Half-way between center of screen and right edge of screen (Hwbcar)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Left back surround (Lbs)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID, // Right back surround (Rbs)
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, // C
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, // Ls
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, // Rs
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, // Lc
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, // Rc
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, // Lsr
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, // Rsr
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, // Cs
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, // Ts
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, // Lw
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, // Rw
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, // Lv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, // Rv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, // Cv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, // Lvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, // Rvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, // Cvr
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, // Lss
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, // Rss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT, // Lvss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT, // Rvss
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT, // Lb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT, // Rb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER, // Cb
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE2, // LFE2
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE1, // LFE1
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, // C
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, // Ls
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, // Rs
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, // Lc
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, // Rc
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, // Lsr
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, // Rsr
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, // Cs
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, // Ts
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, // Lw
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, // Rw
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, // Lv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, // Rv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, // Cv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, // Lvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, // Rvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, // Cvr
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, // Lss
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, // Rss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT, // Lvss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT, // Rvss
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT, // Lb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT, // Rb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER, // Cb
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE2, // LFE2
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE1, // LFE1
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, // C
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, // Ls
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, // Rs
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, // Lc
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, // Rc
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT, // Lsr
|
||||
GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT, // Rsr
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, // Cs
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, // Ts
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT, // Lw
|
||||
GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT, // Rw
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, // Lv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, // Rv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, // Cv
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, // Lvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, // Rvr
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, // Cvr
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, // Lss
|
||||
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, // Rss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT, // Lvss
|
||||
GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT, // Rvss
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT, // Lb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT, // Rb
|
||||
GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER, // Cb
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE2, // LFE2
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE1, // LFE1
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
GST_AUDIO_CHANNEL_POSITION_INVALID,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
GST_AUDIO_CHANNEL_POSITION_MONO,
|
||||
},
|
||||
// GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE
|
||||
{
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, // L
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, // R
|
||||
}
|
||||
};
|
||||
|
||||
static const gchar *gst_audio_convert_input_channels_reorder_to_string
|
||||
(GstAudioConvertInputChannelsReorder reorder)
|
||||
{
|
||||
switch (reorder) {
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST:
|
||||
return "GST";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE:
|
||||
return "SMPTE";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE:
|
||||
return "CINE";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3:
|
||||
return "AC3";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC:
|
||||
return "AAC";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO:
|
||||
return "MONO";
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE:
|
||||
return "ALTERNATE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_audio_convert_position_channels_from_reorder_configuration (gint channels,
|
||||
GstAudioConvertInputChannelsReorder reorder,
|
||||
GstAudioChannelPosition * position)
|
||||
{
|
||||
g_return_val_if_fail (channels > 0, FALSE);
|
||||
g_return_val_if_fail (reorder >= 0
|
||||
&& reorder < GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_NB, FALSE);
|
||||
g_return_val_if_fail (position != NULL, FALSE);
|
||||
|
||||
GST_DEBUG ("ordering %d audio channel(s) according to the %s configuration",
|
||||
channels, gst_audio_convert_input_channels_reorder_to_string (reorder));
|
||||
|
||||
if (channels == 1) {
|
||||
position[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (channels == 2 && input_channels_reorder_config[reorder].has_stereo) {
|
||||
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (gint i = 0; i < channels; ++i) {
|
||||
if (i < G_N_ELEMENTS (channel_position_per_reorder_config[reorder]))
|
||||
position[i] = channel_position_per_reorder_config[reorder][i];
|
||||
else
|
||||
position[i] = GST_AUDIO_CHANNEL_POSITION_INVALID;
|
||||
}
|
||||
|
||||
if (channels > 2
|
||||
&& input_channels_reorder_config[reorder].lfe_as_last_channel) {
|
||||
position[channels - 1] = GST_AUDIO_CHANNEL_POSITION_LFE1;
|
||||
if (channels == 3 && input_channels_reorder_config[reorder].has_stereo) {
|
||||
position[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
position[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*** GSTREAMER FUNCTIONS ******************************************************/
|
||||
|
||||
/* BaseTransform vmethods */
|
||||
|
@ -352,12 +1068,14 @@ remove_channels_from_structure (GstCapsFeatures * features, GstStructure * s,
|
|||
{
|
||||
guint64 mask;
|
||||
gint channels;
|
||||
GstAudioConvert *this = GST_AUDIO_CONVERT (user_data);
|
||||
gboolean force_removing = *(gboolean *) user_data;
|
||||
|
||||
/* Only remove the channels and channel-mask if a (empty) mix matrix was manually specified,
|
||||
* if no channel-mask is specified, for non-NONE channel layouts or for a single channel layout
|
||||
/* Only remove the channels and channel-mask if a mix matrix was manually
|
||||
* specified or an input channels reordering is applied, or if no
|
||||
* channel-mask is specified, for non-NONE channel layouts or for a single
|
||||
* channel layout.
|
||||
*/
|
||||
if (this->mix_matrix_is_set ||
|
||||
if (force_removing ||
|
||||
!gst_structure_get (s, "channel-mask", GST_TYPE_BITMASK, &mask, NULL) ||
|
||||
(mask != 0 || (gst_structure_get_int (s, "channels", &channels)
|
||||
&& channels == 1))) {
|
||||
|
@ -393,7 +1111,12 @@ gst_audio_convert_transform_caps (GstBaseTransform * btrans,
|
|||
|
||||
gst_caps_map_in_place (tmp, remove_format_from_structure, NULL);
|
||||
gst_caps_map_in_place (tmp, remove_layout_from_structure, NULL);
|
||||
gst_caps_map_in_place (tmp, remove_channels_from_structure, btrans);
|
||||
|
||||
gboolean force_removing = this->mix_matrix_is_set
|
||||
|| (direction == GST_PAD_SINK
|
||||
&& this->input_channels_reorder_mode !=
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE);
|
||||
gst_caps_map_in_place (tmp, remove_channels_from_structure, &force_removing);
|
||||
|
||||
/* We can infer the required input / output channels based on the
|
||||
* matrix dimensions */
|
||||
|
@ -796,11 +1519,46 @@ gst_audio_convert_set_caps (GstBaseTransform * base, GstCaps * incaps,
|
|||
GST_AUDIO_CONVERTER_OPT_NOISE_SHAPING_METHOD,
|
||||
GST_TYPE_AUDIO_NOISE_SHAPING_METHOD, this->ns, NULL);
|
||||
|
||||
if (this->mix_matrix_is_set)
|
||||
if (this->mix_matrix_is_set) {
|
||||
gst_structure_set_value (config, GST_AUDIO_CONVERTER_OPT_MIX_MATRIX,
|
||||
&this->mix_matrix);
|
||||
|
||||
this->convert = gst_audio_converter_new (0, &in_info, &out_info, config);
|
||||
this->convert = gst_audio_converter_new (0, &in_info, &out_info, config);
|
||||
|
||||
} else if (this->input_channels_reorder_mode !=
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE) {
|
||||
GstAudioFlags in_flags;
|
||||
GstAudioChannelPosition in_position[64];
|
||||
gboolean restore_in = FALSE;
|
||||
|
||||
if (this->input_channels_reorder_mode ==
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE
|
||||
|| GST_AUDIO_INFO_IS_UNPOSITIONED (&in_info)) {
|
||||
in_flags = GST_AUDIO_INFO_FLAGS (&in_info);
|
||||
memcpy (in_position, in_info.position,
|
||||
GST_AUDIO_INFO_CHANNELS (&in_info) *
|
||||
sizeof (GstAudioChannelPosition));
|
||||
|
||||
if (gst_audio_convert_position_channels_from_reorder_configuration
|
||||
(GST_AUDIO_INFO_CHANNELS (&in_info), this->input_channels_reorder,
|
||||
in_info.position)) {
|
||||
GST_AUDIO_INFO_FLAGS (&in_info) &= ~GST_AUDIO_FLAG_UNPOSITIONED;
|
||||
restore_in = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
this->convert = gst_audio_converter_new (0, &in_info, &out_info, config);
|
||||
|
||||
if (restore_in) {
|
||||
GST_AUDIO_INFO_FLAGS (&in_info) = in_flags;
|
||||
memcpy (in_info.position, in_position,
|
||||
GST_AUDIO_INFO_CHANNELS (&in_info) *
|
||||
sizeof (GstAudioChannelPosition));
|
||||
}
|
||||
|
||||
} else {
|
||||
this->convert = gst_audio_converter_new (0, &in_info, &out_info, config);
|
||||
}
|
||||
|
||||
if (this->convert == NULL)
|
||||
goto no_converter;
|
||||
|
@ -1033,6 +1791,12 @@ gst_audio_convert_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PROP_INPUT_CHANNELS_REORDER:
|
||||
this->input_channels_reorder = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_INPUT_CHANNELS_REORDER_MODE:
|
||||
this->input_channels_reorder_mode = g_value_get_enum (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1059,6 +1823,12 @@ gst_audio_convert_get_property (GObject * object, guint prop_id,
|
|||
if (this->mix_matrix_is_set)
|
||||
g_value_copy (&this->mix_matrix, value);
|
||||
break;
|
||||
case PROP_INPUT_CHANNELS_REORDER:
|
||||
g_value_set_enum (value, this->input_channels_reorder);
|
||||
break;
|
||||
case PROP_INPUT_CHANNELS_REORDER_MODE:
|
||||
g_value_set_enum (value, this->input_channels_reorder_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -26,6 +26,150 @@
|
|||
#include <gst/base/gstbasetransform.h>
|
||||
#include <gst/audio/audio.h>
|
||||
|
||||
/**
|
||||
* GstAudioConvertInputChannelsReorder:
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST: reorder input channels
|
||||
* according to the default ordering in GStreamer: FRONT_LEFT, FRONT_RIGHT,
|
||||
* FRONT_CENTER, LFE1 and then the other channels. If there is only one
|
||||
* input channel available, it will be positioned to MONO.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE: reorder input channels
|
||||
* according to the SMPTE standard: FRONT_LEFT, FRONT_RIGHT, FRONT_CENTER,
|
||||
* LFE1 and then the other channels (the ordering is slightly different from
|
||||
* the default GStreamer order). This audio channels ordering is the only
|
||||
* one that is officially standardized and used by default in many audio
|
||||
* softwares (see: https://www.sis.se/api/document/preview/919377/). If
|
||||
* there is only one input channel available, it will be positioned to MONO.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE: reorder input channels as it
|
||||
* is commonly used in the cinema industry: FRONT_LEFT, FRONT_RIGHT,
|
||||
* FRONT_CENTER, the other channels and then LFE1. This configuration is not
|
||||
* standardized but usually appears in the literature related to the cinema
|
||||
* industry and as an alternate ordering in different audio softwares. On
|
||||
* some web sites, this configuration and the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3 ordering are switched. If
|
||||
* there is only one input channel available, it will be positioned to
|
||||
* MONO. If the number of available input channels is > 2, the last channel
|
||||
* will always be positioned to LFE1.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3: reorder input channels in the
|
||||
* same order as the default order of the AC3 format: FRONT_LEFT,
|
||||
* FRONT_CENTER, FRONT_RIGHT, the other channels (same order as in the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE policy) and then LFE1.
|
||||
* This configuration is also commonly used in the cinema industry and in
|
||||
* professional audio softwares (like ProTools under the name "FILM"
|
||||
* ordering). The only difference with the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE configuration is the
|
||||
* order of the first 3 channels. If there is only one input channel
|
||||
* available, it will be positioned to MONO. If the number of available
|
||||
* input channels is > 2, the last channel will always be positioned to
|
||||
* LFE1. If the number of available input channels is 2 or 3, the first two
|
||||
* channels will be positioned to FRONT_LEFT and FRONT_RIGHT.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC: reorder input channels in the
|
||||
* same order as the default order of the AAC format: FRONT_CENTER,
|
||||
* FRONT_LEFT, FRONT_RIGHT, the other channels (same order as in the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE configuration) and then
|
||||
* LFE1. The only difference with the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE configuration is the
|
||||
* order of the first 3 channels. If there is only one input channel
|
||||
* available, it will be positioned to MONO. If the number of available
|
||||
* input channels is > 2, the last channel will always be positioned to
|
||||
* LFE1. If the number of available input channels is 2 or 3, the first two
|
||||
* channels will be positioned to FRONT_LEFT and FRONT_RIGHT.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO: reorder all input channels
|
||||
* to MONO. All input channels are mixed together at the same level to a
|
||||
* virtual single mono channel. For `n` input channels, the virtual output
|
||||
* sample value is computed as:
|
||||
* `output_sample[MONO] = (1/n) x ∑ input_sample_for_channel(i)` with
|
||||
* `0 <= i < n`. A concrete usage for this configuration is, for example,
|
||||
* when importing audio from an array of multiple mono microphones and you
|
||||
* want to use them as a unique mono channel.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE: reorder all input
|
||||
* channels to FRONT_LEFT and FRONT_RIGHT channels alternately (or MONO if
|
||||
* there is only one input channel available). All left input channels are
|
||||
* mixed together, at the same level, to a single FRONT_LEFT virtual
|
||||
* channel and all right input channels are mixed together to a single
|
||||
* FRONT_RIGHT virtual channel. For `2n` input channels the FRONT_LEFT and
|
||||
* FRONT_RIGHT virtual output samples are computed as:
|
||||
* `output_sample[FRONT_LEFT] = (1/n) x ∑ input_sample_for_channel(2i)` and
|
||||
* `output_sample[FRONT_RIGHT] = (1/n) x ∑ input_sample_for_channel(2i+1)`
|
||||
* with `0 <= i < n` (in case of an odd number of input channels the
|
||||
* principle is the same but with an extra input left channel). A concrete
|
||||
* usage for this configuration is, for example, when importing audio from
|
||||
* an array of multiple stereo microphones and you want to use them as a
|
||||
* simple pair of stereo channels.
|
||||
*
|
||||
* Input audio channels reordering configurations.
|
||||
*
|
||||
* It defines different ways of reordering input audio channels when they are
|
||||
* not positioned by GStreamer. As a general matter, channels are always ordered
|
||||
* in the @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST order and the
|
||||
* `channel-mask` field in the audio caps allows specifying which channels are
|
||||
* active.
|
||||
*
|
||||
* Depending on the selected mode (see:
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED), input channels
|
||||
* can be automatically positioned when the `channel-mask` is not specified or
|
||||
* equals 0. In this case, all input channels will be positioned according to
|
||||
* the selected reordering configuration and the index of each input channel.
|
||||
* This can be useful when importing audio from an array of independent
|
||||
* microphones for example.
|
||||
*
|
||||
* The reordering configuration can also be forced (see:
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE) to reposition all
|
||||
* input channels according to each channel index. In this case the
|
||||
* `channel-mask` will be totally ignored and input channels will be reordered
|
||||
* just like if they were unpositioned. This can be useful when importing
|
||||
* multi-channels audio with errors in the channels positioning.
|
||||
*
|
||||
* For any of the former configurations, when the reordering is applied
|
||||
* (input channels are unpositioned or the "force" mode is active):
|
||||
* - When there is only one input channel available, it is positioned to MONO
|
||||
* always, independently of the selected configuration.
|
||||
* - When there are 2 input channels available, they are positioned to
|
||||
* FRONT_LEFT and FRONT_RIGHT (except for the
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO configuration where all
|
||||
* input channels are positioned to MONO).
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
typedef enum {
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST = 0,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE
|
||||
} GstAudioConvertInputChannelsReorder;
|
||||
|
||||
/**
|
||||
* GstAudioConvertInputChannelsReorderMode:
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE: never reorder the input
|
||||
* channels. If input channels are unpositioned and there are, at least, 3
|
||||
* input channels, an error will be generated.
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED: automatically
|
||||
* reorder the input channels according to the selected
|
||||
* #GstAudioConvertInputChannelsReorder configuration when, and only when,
|
||||
* they are unpositioned (the `channel-mask` equals 0 or is not specified
|
||||
* in the input caps).
|
||||
* @GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE: always reorder the
|
||||
* input channels according to the selected
|
||||
* #GstAudioConvertInputChannelsReorder configuration. The `channel-mask`
|
||||
* value in the input caps is completely ignored. Input channels are always
|
||||
* reordered as if they were unpositioned independently of the input caps.
|
||||
*
|
||||
* The different usage modes of the input channels reordering configuration.
|
||||
*
|
||||
* Independently of the selected mode, the explicit definition of a mix matrix
|
||||
* takes precedence over the reorder configuration. In this case, the provided
|
||||
* mix matrix will override the reorder configuration.
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
typedef enum {
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_NONE = 0,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED,
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_FORCE
|
||||
} GstAudioConvertInputChannelsReorderMode;
|
||||
|
||||
#define GST_TYPE_AUDIO_CONVERT (gst_audio_convert_get_type())
|
||||
G_DECLARE_FINAL_TYPE (GstAudioConvert, gst_audio_convert,
|
||||
GST, AUDIO_CONVERT, GstBaseTransform);
|
||||
|
@ -45,6 +189,8 @@ struct _GstAudioConvert
|
|||
GstAudioNoiseShapingMethod ns;
|
||||
GValue mix_matrix;
|
||||
gboolean mix_matrix_is_set;
|
||||
GstAudioConvertInputChannelsReorder input_channels_reorder;
|
||||
GstAudioConvertInputChannelsReorderMode input_channels_reorder_mode;
|
||||
|
||||
GstAudioInfo in_info;
|
||||
GstAudioInfo out_info;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/audio/audio.h>
|
||||
#include <gst/audioconvert/gstaudioconvert.h>
|
||||
|
||||
/* For ease of programming we use globals to keep refs for our floating
|
||||
* src and sink pads we create; otherwise we always have to do get_pad,
|
||||
|
@ -82,6 +83,46 @@ setup_audioconvert (GstCaps * outcaps, gboolean use_mix_matrix,
|
|||
return audioconvert;
|
||||
}
|
||||
|
||||
static GstElement *
|
||||
setup_audioconvert_with_input_channels_reorder (GstCaps * outcaps,
|
||||
GstAudioConvertInputChannelsReorder reorder)
|
||||
{
|
||||
GstPadTemplate *sinktemplate;
|
||||
static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (CONVERT_CAPS_TEMPLATE_STRING)
|
||||
);
|
||||
GstElement *audioconvert;
|
||||
|
||||
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 1);
|
||||
sinktemplate =
|
||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, outcaps);
|
||||
|
||||
GST_DEBUG ("setup_audioconvert with caps %" GST_PTR_FORMAT, outcaps);
|
||||
audioconvert = gst_check_setup_element ("audioconvert");
|
||||
g_object_set (G_OBJECT (audioconvert), "dithering", 0, NULL);
|
||||
g_object_set (G_OBJECT (audioconvert), "noise-shaping", 0, NULL);
|
||||
g_object_set (G_OBJECT (audioconvert), "input-channels-reorder",
|
||||
reorder, "input-channels-reorder-mode",
|
||||
GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MODE_UNPOSITIONED, NULL);
|
||||
|
||||
mysrcpad = gst_check_setup_src_pad (audioconvert, &srctemplate);
|
||||
mysinkpad =
|
||||
gst_check_setup_sink_pad_from_template (audioconvert, sinktemplate);
|
||||
/* this installs a getcaps func that will always return the caps we set
|
||||
* later */
|
||||
gst_pad_use_fixed_caps (mysinkpad);
|
||||
|
||||
gst_pad_set_active (mysrcpad, TRUE);
|
||||
gst_pad_set_active (mysinkpad, TRUE);
|
||||
|
||||
gst_object_unref (sinktemplate);
|
||||
|
||||
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 2);
|
||||
return audioconvert;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_audioconvert (GstElement * audioconvert)
|
||||
{
|
||||
|
@ -94,6 +135,41 @@ cleanup_audioconvert (GstElement * audioconvert)
|
|||
gst_check_teardown_element (audioconvert);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
format_input_channels_reorder_test_name (const gchar * test_name,
|
||||
GstAudioConvertInputChannelsReorder reorder)
|
||||
{
|
||||
const gchar *reorder_name = "unknown";
|
||||
switch (reorder) {
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST:
|
||||
reorder_name = "gst";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_SMPTE:
|
||||
reorder_name = "smpte";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_CINE:
|
||||
reorder_name = "cine";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AC3:
|
||||
reorder_name = "ac3";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_AAC:
|
||||
reorder_name = "aac";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_MONO:
|
||||
reorder_name = "mono";
|
||||
break;
|
||||
case GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE:
|
||||
reorder_name = "alternate";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return g_strdup_printf ("%s with input channels %s reorder", test_name,
|
||||
reorder_name);
|
||||
}
|
||||
|
||||
/* returns a newly allocated caps */
|
||||
static GstCaps *
|
||||
get_int_caps (guint channels, gint endianness, guint width,
|
||||
|
@ -159,6 +235,29 @@ get_float_caps (guint channels, gint endianness, guint width,
|
|||
return caps;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
get_unpositioned_input_caps (guint channels)
|
||||
{
|
||||
GstCaps *caps;
|
||||
GstAudioInfo info;
|
||||
|
||||
gst_audio_info_init (&info);
|
||||
gst_audio_info_set_format (&info,
|
||||
gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, 16, 16),
|
||||
GST_AUDIO_DEF_RATE, channels, NULL);
|
||||
info.layout = GST_AUDIO_LAYOUT_INTERLEAVED;
|
||||
|
||||
info.flags = GST_AUDIO_FLAG_UNPOSITIONED;
|
||||
for (guint i = 0; i < MIN (64, channels); ++i)
|
||||
info.position[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
|
||||
|
||||
caps = gst_audio_info_to_caps (&info);
|
||||
fail_unless (caps != NULL);
|
||||
GST_DEBUG ("returning caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* Copied from vorbis; the particular values used don't matter */
|
||||
static GstAudioChannelPosition channelpositions[][6] = {
|
||||
{ /* Mono */
|
||||
|
@ -413,7 +512,8 @@ static void
|
|||
verify_convert (const gchar * which, void *in, int inlength,
|
||||
GstCaps * incaps, void *out, int outlength, GstCaps * outcaps,
|
||||
GstFlowReturn expected_flow, gboolean in_place_allowed,
|
||||
gboolean use_mix_matrix, GValue * mix_matrix)
|
||||
gboolean use_mix_matrix, GValue * mix_matrix,
|
||||
GstElement * custom_audioconvert)
|
||||
{
|
||||
GstBuffer *inbuffer, *outbuffer;
|
||||
GstElement *audioconvert;
|
||||
|
@ -423,8 +523,13 @@ verify_convert (const gchar * which, void *in, int inlength,
|
|||
GST_DEBUG ("incaps: %" GST_PTR_FORMAT, incaps);
|
||||
GST_DEBUG ("outcaps: %" GST_PTR_FORMAT, outcaps);
|
||||
ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
|
||||
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 1);
|
||||
audioconvert = setup_audioconvert (outcaps, use_mix_matrix, mix_matrix);
|
||||
|
||||
if (custom_audioconvert) {
|
||||
audioconvert = custom_audioconvert;
|
||||
} else {
|
||||
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 1);
|
||||
audioconvert = setup_audioconvert (outcaps, use_mix_matrix, mix_matrix);
|
||||
}
|
||||
ASSERT_CAPS_REFCOUNT (outcaps, "outcaps", 2);
|
||||
|
||||
fail_unless (gst_element_set_state (audioconvert,
|
||||
|
@ -510,22 +615,36 @@ done:
|
|||
#define RUN_CONVERSION(which, inarray, in_get_caps, outarray, out_get_caps) \
|
||||
verify_convert (which, inarray, sizeof (inarray), \
|
||||
in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK, \
|
||||
TRUE, FALSE, &(GValue) G_VALUE_INIT);
|
||||
TRUE, FALSE, &(GValue) G_VALUE_INIT, NULL);
|
||||
|
||||
#define RUN_CONVERSION_WITH_MATRIX(which, inarray, in_get_caps, outarray, out_get_caps, mix_matrix) \
|
||||
#define RUN_CONVERSION_WITH_MATRIX(which, inarray, in_get_caps, outarray, out_get_caps, mix_matrix) \
|
||||
verify_convert (which, inarray, sizeof (inarray), \
|
||||
in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK, \
|
||||
TRUE, TRUE, mix_matrix);
|
||||
TRUE, TRUE, mix_matrix, NULL);
|
||||
|
||||
#define RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER(which, inarray, \
|
||||
in_channels, reorder, outarray, out_channels) \
|
||||
{ \
|
||||
GstCaps *in_get_caps = get_unpositioned_input_caps (in_channels); \
|
||||
GstCaps *out_get_caps = get_int_mc_caps (out_channels, G_BYTE_ORDER, 16, \
|
||||
16, TRUE, GST_AUDIO_LAYOUT_INTERLEAVED, NULL); \
|
||||
verify_convert ( \
|
||||
which, inarray, sizeof (inarray), in_get_caps, outarray, \
|
||||
sizeof (outarray), out_get_caps, GST_FLOW_OK, TRUE, FALSE, \
|
||||
&(GValue) G_VALUE_INIT, \
|
||||
setup_audioconvert_with_input_channels_reorder (out_get_caps, \
|
||||
reorder)); \
|
||||
}
|
||||
|
||||
#define RUN_CONVERSION_TO_FAIL(which, inarray, in_caps, outarray, out_caps) \
|
||||
verify_convert (which, inarray, sizeof (inarray), \
|
||||
in_caps, outarray, sizeof (outarray), out_caps, \
|
||||
GST_FLOW_NOT_NEGOTIATED, TRUE, FALSE, &(GValue) G_VALUE_INIT);
|
||||
GST_FLOW_NOT_NEGOTIATED, TRUE, FALSE, &(GValue) G_VALUE_INIT, NULL);
|
||||
|
||||
#define RUN_CONVERSION_NOT_INPLACE(which, inarray, in_get_caps, outarray, out_get_caps) \
|
||||
#define RUN_CONVERSION_NOT_INPLACE(which, inarray, in_get_caps, outarray, out_get_caps) \
|
||||
verify_convert (which, inarray, sizeof (inarray), \
|
||||
in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK, \
|
||||
FALSE, FALSE, &(GValue) G_VALUE_INIT);
|
||||
FALSE, FALSE, &(GValue) G_VALUE_INIT, NULL);
|
||||
|
||||
#define INTERLEAVED GST_AUDIO_LAYOUT_INTERLEAVED
|
||||
#define PLANAR GST_AUDIO_LAYOUT_NON_INTERLEAVED
|
||||
|
@ -1094,6 +1213,245 @@ GST_START_TEST (test_multichannel_conversion)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_multichannel_crossmixing_with_input_channels_reorder)
|
||||
{
|
||||
{
|
||||
gint16 in[] = { 12400, -120 };
|
||||
gint16 out[] = { 12400, -120 };
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("1 channel to 1", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 1, reorder,
|
||||
out, 1);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120 };
|
||||
gint16 out[] = { 12400, 12400, -120, -120 };
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("1 channel to 2", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 1, reorder,
|
||||
out, 2);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120 };
|
||||
gint16 out[] = { 12400, 12400, 8767, -120, -120, -85 };
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("1 channel to 3", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 1, reorder,
|
||||
out, 3);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, -10844, 5842 };
|
||||
gint16 out[] = { 6140, -2501 };
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("2 channels to 1", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 2, reorder,
|
||||
out, 1);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, -10844, 5842 };
|
||||
gint16 out[][4] = {
|
||||
{12400, -120, -10844, 5842},
|
||||
{12400, -120, -10844, 5842},
|
||||
{12400, -120, -10844, 5842},
|
||||
{12400, -120, -10844, 5842},
|
||||
{12400, -120, -10844, 5842},
|
||||
{6140, 6140, -2501, -2501},
|
||||
{12400, -120, -10844, 5842}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("2 channels to 2", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 2, reorder,
|
||||
out[reorder], 2);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, -10844, 5842 };
|
||||
gint16 out[][6] = {
|
||||
{8767, -85, 6140, -7667, 4130, -2501},
|
||||
{8767, -85, 6140, -7667, 4130, -2501},
|
||||
{8767, -85, 6140, -7667, 4130, -2501},
|
||||
{8767, -85, 6140, -7667, 4130, -2501},
|
||||
{8767, -85, 6140, -7667, 4130, -2501},
|
||||
{6140, 6140, 4341, -2501, -2501, -1768},
|
||||
{8767, -85, 6140, -7667, 4130, -2501}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("2 channels to 3", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 2, reorder,
|
||||
out[reorder], 3);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, 1120, -10844, 5842, -48 };
|
||||
gint16 out[][2] = {
|
||||
{4825, -1859},
|
||||
{4825, -1859},
|
||||
{4462, -1682},
|
||||
{4462, -1682},
|
||||
{4462, -1682},
|
||||
{4462, -1682},
|
||||
{3320, 198}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("3 channels to 1", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 3, reorder,
|
||||
out[reorder], 1);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, 1120, -10844, 5842, -48 };
|
||||
gint16 out[][4] = {
|
||||
{7717, 394, -6363, 3397},
|
||||
{7717, 394, -6363, 3397},
|
||||
{6760, 500, -5446, 2897},
|
||||
{6760, 500, -5446, 2897},
|
||||
{6760, 500, -5446, 2897},
|
||||
{4462, 4462, -1682, -1682},
|
||||
{6760, -120, -5446, 5842}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("3 channels to 2", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 3, reorder,
|
||||
out[reorder], 2);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] = { 12400, -120, 1120, -10844, 5842, -48 };
|
||||
gint16 out[][6] = {
|
||||
{12400, -120, 1120, -10844, 5842, -48},
|
||||
{12400, -120, 1120, -10844, 5842, -48},
|
||||
{6364, 471, 4462, -5127, 2727, -1682},
|
||||
{6364, 471, 4462, -5127, 2727, -1682},
|
||||
{6364, 471, 4462, -5127, 2727, -1682},
|
||||
{4462, 4462, 3154, -1682, -1682, -1189},
|
||||
{4780, -85, 3320, -3850, 4130, 198}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("3 channels to 3", reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 3, reorder,
|
||||
out[reorder], 3);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST
|
||||
(test_multichannel_downmixing_to_stereo_with_input_channels_reorder) {
|
||||
{
|
||||
gint16 in[] =
|
||||
{ 12400, -120, 1248, 10140, 368, -32124, 8145, 7411, -212, -5489, 18523,
|
||||
10003
|
||||
};
|
||||
gint16 out[][4] = {
|
||||
{7353, -1592, 3657, 2105},
|
||||
{7353, -1592, 3657, 2105},
|
||||
{-4296, -9713, 4755, 8254},
|
||||
{-4596, -9588, 6430, 7555},
|
||||
{-5746, -6837, 6362, 7716},
|
||||
{-1343, -1343, 6372, 6372},
|
||||
{4667, -7361, 8810, 3971}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("5.1 channels to stereo",
|
||||
reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 6, reorder,
|
||||
out[reorder], 2);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
gint16 in[] =
|
||||
{ 12400, -120, 1248, 10140, 368, -32124, 1247, -458, 8145, 7411, -212,
|
||||
-5489, 18523, 10003, 789, -5557
|
||||
};
|
||||
gint16 out[][4] = {
|
||||
{6739, -1645, 3467, 813},
|
||||
{6739, -1645, 3467, 813},
|
||||
{-1482, 260, 1921, 3242},
|
||||
{-1617, 508, 2673, 1857},
|
||||
{-3891, 1743, 2539, 1930},
|
||||
{-912, -912, 4202, 4202},
|
||||
{3816, -5640, 6811, 1592}
|
||||
};
|
||||
|
||||
for (gint reorder = GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_GST;
|
||||
reorder <= GST_AUDIO_CONVERT_INPUT_CHANNELS_REORDER_ALTERNATE;
|
||||
++reorder) {
|
||||
gchar *test_name =
|
||||
format_input_channels_reorder_test_name ("7.1 channels to stereo",
|
||||
reorder);
|
||||
RUN_CONVERSION_WITH_INPUT_CHANNELS_REORDER (test_name, in, 8, reorder,
|
||||
out[reorder], 2);
|
||||
g_free (test_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_passthrough)
|
||||
{
|
||||
/* int 8 bit */
|
||||
|
@ -1894,6 +2252,10 @@ audioconvert_suite (void)
|
|||
tcase_add_test (tc_chain, test_float_conversion);
|
||||
tcase_add_test (tc_chain, test_int_float_conversion);
|
||||
tcase_add_test (tc_chain, test_multichannel_conversion);
|
||||
tcase_add_test (tc_chain,
|
||||
test_multichannel_crossmixing_with_input_channels_reorder);
|
||||
tcase_add_test (tc_chain,
|
||||
test_multichannel_downmixing_to_stereo_with_input_channels_reorder);
|
||||
tcase_add_test (tc_chain, test_passthrough);
|
||||
tcase_add_test (tc_chain, test_caps_negotiation);
|
||||
tcase_add_test (tc_chain, test_convert_undefined_multichannel);
|
||||
|
|
Loading…
Reference in a new issue