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> 2008-05-29 Sebastian Dröge <slomo@circular-chaos.org>
* win32/common/libgstaudio.def: * 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)) if (!gst_structure_get_int (s, "channels", &channels))
return FALSE; /* probably a range */ return FALSE; /* probably a range */
if (channels > 8) { val = gst_structure_get_value (s, "channel-positions");
GST_LOG ("%d channels, undefined channel positions are implicit", channels); 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; *unpositioned_layout = TRUE;
return 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); 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); GST_LOG ("fixed undefined channel-positions in %" GST_PTR_FORMAT, s);
*unpositioned_layout = TRUE; *unpositioned_layout = TRUE;
} else { } else {
@ -656,16 +654,18 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
allow_mixing = (unpositioned == FALSE); allow_mixing = (unpositioned == FALSE);
} }
if (!allow_mixing || channels == 8) { if (!allow_mixing) {
gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL); gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL);
if (gst_structure_has_field (structure, "channel-positions")) if (gst_structure_has_field (structure, "channel-positions"))
gst_structure_set_value (s, "channel-positions", gst_structure_set_value (s, "channel-positions",
gst_structure_get_value (structure, "channel-positions")); gst_structure_get_value (structure, "channel-positions"));
} else { } else {
if (channels == 0) 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 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_structure_remove_field (s, "channel-positions");
} }
gst_caps_append_structure (ret, s); gst_caps_append_structure (ret, s);
@ -696,7 +696,7 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
*/ */
s = gst_structure_copy (s); s = gst_structure_copy (s);
if (allow_mixing) { 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"); gst_structure_remove_field (s, "channel-positions");
} else { } else {
/* allow_mixing can only be FALSE if we got a fixed number of channels */ /* 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 */ /* 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}, 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,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE,
GST_AUDIO_CHANNEL_POSITION_NONE} GST_AUDIO_CHANNEL_POSITION_NONE}
}; };
static void 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); 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); "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 */ /* (B) CONVERSION FROM 'BETTER' TO 'WORSE' FORMAT */
/* 1 channel, NONE positions, int16 => int8 */ /* 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); "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 */ /* (C) NO CONVERSION, SAME FORMAT */
/* 1 channel, NONE positions, int16 => int16 */ /* 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); "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 */ /* (C) int16 => float */
/* 9 channels, NONE positions, 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); "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 /* 9 channels, NONE positions, int16 => float (same as above, but no
* position on output caps to see if audioconvert transforms correctly) */ * 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); "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 */ /* 8 channels, NONE positions => 2 channels: should fail, no mixing allowed */
{ {
guint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; guint16 in[] = { 0, 0, 0, 0, 0, 0, 0, 0 };