gst/audioconvert/gstaudioconvert.c: Allow up to 11 positioned channels now that audioconvert can handle this but add ...

Original commit message from CVS:
* gst/audioconvert/gstaudioconvert.c:
(structure_has_fixed_channel_positions),
(gst_audio_convert_transform_caps):
Allow up to 11 positioned channels now that audioconvert can handle
this but add no default positions for > 8 channels.
* tests/check/elements/audioconvert.c: (GST_START_TEST):
Add some unit tests for the above change: Test conversion of
11 positioned channels to stereo and the other way around, test
conversion of 15 unpositioned channels in different ways.
This commit is contained in:
Sebastian Dröge 2008-05-30 08:42:17 +00:00
parent 79cf1cf8fd
commit fdd708c418
3 changed files with 239 additions and 15 deletions

View file

@ -1,3 +1,16 @@
2008-05-30 Sebastian Dröge <slomo@circular-chaos.org>
* gst/audioconvert/gstaudioconvert.c:
(structure_has_fixed_channel_positions),
(gst_audio_convert_transform_caps):
Allow up to 11 positioned channels now that audioconvert can handle
this but add no default positions for > 8 channels.
* tests/check/elements/audioconvert.c: (GST_START_TEST):
Add some unit tests for the above change: Test conversion of
11 positioned channels to stereo and the other way around, test
conversion of 15 unpositioned channels in different ways.
2008-05-29 Sebastian Dröge <slomo@circular-chaos.org>
* win32/common/libgstaudio.def:

View file

@ -548,20 +548,18 @@ structure_has_fixed_channel_positions (GstStructure * s,
if (!gst_structure_get_int (s, "channels", &channels))
return FALSE; /* probably a range */
if (channels > 8) {
GST_LOG ("%d channels, undefined channel positions are implicit", channels);
val = gst_structure_get_value (s, "channel-positions");
if ((val == NULL || !gst_value_is_fixed (val)) && channels <= 8) {
GST_LOG ("no or unfixed channel-positions in %" GST_PTR_FORMAT, s);
return FALSE;
} else if (val == NULL || !gst_value_is_fixed (val)) {
GST_LOG ("implicit undefined channel-positions");
*unpositioned_layout = TRUE;
return TRUE;
}
val = gst_structure_get_value (s, "channel-positions");
if (val == NULL || !gst_value_is_fixed (val)) {
GST_LOG ("no or unfixed channel-positions in %" GST_PTR_FORMAT, s);
return FALSE;
}
pos = gst_audio_get_channel_positions (s);
if ((pos && pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) || channels > 8) {
if (pos && pos[0] == GST_AUDIO_CHANNEL_POSITION_NONE) {
GST_LOG ("fixed undefined channel-positions in %" GST_PTR_FORMAT, s);
*unpositioned_layout = TRUE;
} else {
@ -656,16 +654,18 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
allow_mixing = (unpositioned == FALSE);
}
if (!allow_mixing || channels == 8) {
if (!allow_mixing) {
gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL);
if (gst_structure_has_field (structure, "channel-positions"))
gst_structure_set_value (s, "channel-positions",
gst_structure_get_value (structure, "channel-positions"));
} else {
if (channels == 0)
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 8, NULL);
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL);
else if (channels == 11)
gst_structure_set (s, "channels", G_TYPE_INT, 11, NULL);
else
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 8, NULL);
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, channels, 11, NULL);
gst_structure_remove_field (s, "channel-positions");
}
gst_caps_append_structure (ret, s);
@ -696,7 +696,7 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
*/
s = gst_structure_copy (s);
if (allow_mixing) {
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 8, NULL);
gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, 11, NULL);
gst_structure_remove_field (s, "channel-positions");
} else {
/* allow_mixing can only be FALSE if we got a fixed number of channels */

View file

@ -231,7 +231,7 @@ static GstAudioChannelPosition mixed_up_positions[][6] = {
};
/* we get this when recording from a soundcard with lots of input channels */
static GstAudioChannelPosition undefined_positions[][9] = {
static GstAudioChannelPosition undefined_positions[][15] = {
{
GST_AUDIO_CHANNEL_POSITION_NONE},
{
@ -285,8 +285,88 @@ static GstAudioChannelPosition undefined_positions[][9] = {
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE},
{
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE}
};
static void
@ -961,6 +1041,31 @@ GST_START_TEST (test_multichannel_conversion)
RUN_CONVERSION ("5.1 to 2 channels", in, in_caps, out, out_caps);
}
{
gint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
gint16 out[] = { 0, 0 };
GstCaps *in_caps = get_int_mc_caps (11, "BYTE_ORDER", 16, 16, TRUE, FALSE);
GstCaps *out_caps = get_int_mc_caps (2, "BYTE_ORDER", 16, 16, TRUE, FALSE);
GstAudioChannelPosition in_layout[11] = {
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER,
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
GST_AUDIO_CHANNEL_POSITION_LFE,
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
};
set_channel_positions (in_caps, 11, in_layout);
RUN_CONVERSION ("11 channels to 2", in,
gst_caps_copy (in_caps), out, gst_caps_copy (out_caps));
RUN_CONVERSION ("2 channels to 11", out, out_caps, in, in_caps);
}
}
@ -1310,6 +1415,27 @@ GST_START_TEST (test_convert_undefined_multichannel)
"int8 => int16", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int8 => int16 */
{
guint16 out[] =
{ 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000, 0x0000, 0xff00,
0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000, 0x0000
};
guint8 in[] =
{ 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00, 0xff, 0x00,
0x20, 0x80, 0x20, 0x00
};
GstCaps *out_caps =
get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
GstCaps *in_caps = get_int_mc_caps (15, "BYTE_ORDER", 8, 8, FALSE, FALSE);
set_channel_positions (out_caps, 15, undefined_positions[15 - 1]);
set_channel_positions (in_caps, 15, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int8 => int16", in, in_caps, out, out_caps);
}
/* (B) CONVERSION FROM 'BETTER' TO 'WORSE' FORMAT */
/* 1 channel, NONE positions, int16 => int8 */
@ -1370,6 +1496,27 @@ GST_START_TEST (test_convert_undefined_multichannel)
"int16 => int8", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => int8 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
guint8 out[] =
{ 0x00, 0xff, 0x00, 0x20, 0x80, 0x20, 0x00, 0xff, 0x00, 0xff, 0x00,
0x20, 0x80, 0x20, 0x00
};
GstCaps *in_caps = get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
GstCaps *out_caps = get_int_mc_caps (15, "BYTE_ORDER", 8, 8, FALSE, FALSE);
set_channel_positions (out_caps, 15, undefined_positions[15 - 1]);
set_channel_positions (in_caps, 15, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => int8", in, in_caps, out, out_caps);
}
/* (C) NO CONVERSION, SAME FORMAT */
/* 1 channel, NONE positions, int16 => int16 */
@ -1432,6 +1579,28 @@ GST_START_TEST (test_convert_undefined_multichannel)
"int16 => int16", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => int16 */
{
guint16 in[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
guint16 out[] = { 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000, 0xff00, 0x0000, 0xff00, 0x0000, 0x2000, 0x8000, 0x2000,
0x0000
};
GstCaps *in_caps = get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
GstCaps *out_caps =
get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
set_channel_positions (out_caps, 15, undefined_positions[15 - 1]);
set_channel_positions (in_caps, 15, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => int16", in, in_caps, out, out_caps);
}
/* (C) int16 => float */
/* 9 channels, NONE positions, int16 => float */
@ -1450,6 +1619,27 @@ GST_START_TEST (test_convert_undefined_multichannel)
"int16 => float", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => float */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000
};
gfloat out[] =
{ -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0,
0.0, -1.0
};
GstCaps *in_caps = get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
GstCaps *out_caps = get_float_mc_caps (15, "BYTE_ORDER", 32, FALSE);
set_channel_positions (out_caps, 15, undefined_positions[15 - 1]);
set_channel_positions (in_caps, 15, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 9 channels, NONE positions, int16 => float (same as above, but no
* position on output caps to see if audioconvert transforms correctly) */
{
@ -1467,6 +1657,27 @@ GST_START_TEST (test_convert_undefined_multichannel)
"int16 => float", in, in_caps, out, out_caps);
}
/* 15 channels, NONE positions, int16 => float (same as above, but no
* position on output caps to see if audioconvert transforms correctly) */
{
guint16 in[] = { 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000, 0x8000, 0x0000, 0x8000, 0x0000, 0x8000, 0x8000, 0x8000,
0x0000
};
gfloat out[] =
{ -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0,
0.0, -1.0
};
GstCaps *in_caps = get_int_mc_caps (15, "BYTE_ORDER", 16, 16, FALSE, FALSE);
GstCaps *out_caps = get_float_mc_caps (15, "BYTE_ORDER", 32, FALSE);
//set_channel_positions (out_caps, 9, undefined_positions[9 - 1]);
set_channel_positions (in_caps, 15, undefined_positions[15 - 1]);
RUN_CONVERSION ("15 channels, undefined layout, identity conversion, "
"int16 => float", in, in_caps, out, out_caps);
}
/* 8 channels, NONE positions => 2 channels: should fail, no mixing allowed */
{
guint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0 };