From fdd708c41887ff7de2083a6d61a689bd67ee2fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 30 May 2008 08:42:17 +0000 Subject: [PATCH] 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. --- ChangeLog | 13 ++ gst/audioconvert/gstaudioconvert.c | 26 ++-- tests/check/elements/audioconvert.c | 215 +++++++++++++++++++++++++++- 3 files changed, 239 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5dc2c66a09..ff341e56de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-05-30 Sebastian Dröge + + * 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 * win32/common/libgstaudio.def: diff --git a/gst/audioconvert/gstaudioconvert.c b/gst/audioconvert/gstaudioconvert.c index fa4eed220f..d051445e3b 100644 --- a/gst/audioconvert/gstaudioconvert.c +++ b/gst/audioconvert/gstaudioconvert.c @@ -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 */ diff --git a/tests/check/elements/audioconvert.c b/tests/check/elements/audioconvert.c index 8331b4aa82..58c69dd8c5 100644 --- a/tests/check/elements/audioconvert.c +++ b/tests/check/elements/audioconvert.c @@ -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 };