mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
gst/audioconvert/gstchannelmix.c: Fix #341696: crash when mixing L+R+C to mono or stereo.
Original commit message from CVS: * gst/audioconvert/gstchannelmix.c: (gst_channel_mix_fill_others): Fix #341696: crash when mixing L+R+C to mono or stereo. * tests/check/Makefile.am: * tests/check/elements/audioconvert.c: (set_channel_positions), (get_float_mc_caps), (get_int_mc_caps), (GST_START_TEST), (audioconvert_suite): Add test for the above, including some generic framework bits for testing multichannel things.
This commit is contained in:
parent
e2747e34fe
commit
400ade1e8f
4 changed files with 122 additions and 1 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2006-05-14 Michael Smith <msmith@fluendo.com>
|
||||
|
||||
* gst/audioconvert/gstchannelmix.c: (gst_channel_mix_fill_others):
|
||||
Fix #341696: crash when mixing L+R+C to mono or stereo.
|
||||
* tests/check/Makefile.am:
|
||||
* tests/check/elements/audioconvert.c: (set_channel_positions),
|
||||
(get_float_mc_caps), (get_int_mc_caps), (GST_START_TEST),
|
||||
(audioconvert_suite):
|
||||
Add test for the above, including some generic framework bits for
|
||||
testing multichannel things.
|
||||
|
||||
=== release 0.10.7 ===
|
||||
|
||||
2006-05-14 Jan Schmidt <thaytan@mad.scientist.com>
|
||||
|
|
|
@ -350,7 +350,7 @@ gst_channel_mix_fill_others (AudioConvertCtx * this)
|
|||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, RATIO_FRONT_REAR);
|
||||
} else if (in_has_center && !out_has_center && out_has_front) {
|
||||
} else if (in_has_rear && !out_has_rear && out_has_front) {
|
||||
gst_channel_mix_fill_one_other (this->matrix,
|
||||
&this->in, in_r,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
|
|
|
@ -77,6 +77,14 @@ libs_cddabasesrc_CFLAGS = \
|
|||
-I$(top_srcdir)/gst-libs \
|
||||
$(CFLAGS) $(AM_CFLAGS)
|
||||
|
||||
elements_audioconvert_LDADD = \
|
||||
$(top_builddir)/gst-libs/gst/audio/libgstaudio-@GST_MAJORMINOR@.la \
|
||||
$(LDADD)
|
||||
|
||||
elements_audioconvert_CFLAGS = \
|
||||
-I$(top_srcdir)/gst-libs \
|
||||
$(CFLAGS) $(AM_CFLAGS)
|
||||
|
||||
libs_video_LDADD = \
|
||||
$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \
|
||||
$(LDADD)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/audio/multichannel.h>
|
||||
|
||||
GList *buffers = NULL;
|
||||
gboolean have_eos = FALSE;
|
||||
|
@ -159,6 +160,88 @@ get_float_caps (guint channels, gchar * endianness, guint width)
|
|||
return caps;
|
||||
}
|
||||
|
||||
/* Copied from vorbis; the particular values used don't matter */
|
||||
static GstAudioChannelPosition channelpositions[][6] = {
|
||||
{ /* Mono */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
|
||||
{ /* Stereo */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
||||
{ /* Stereo + Centre */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
|
||||
{ /* Quadraphonic */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
},
|
||||
{ /* Stereo + Centre + rear stereo */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
},
|
||||
{ /* Full 5.1 Surround */
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
|
||||
GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
|
||||
GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
|
||||
GST_AUDIO_CHANNEL_POSITION_LFE,
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
set_channel_positions (GstCaps * caps, int channels,
|
||||
GstAudioChannelPosition * channelpositions)
|
||||
{
|
||||
GValue chanpos = { 0 };
|
||||
GValue pos = { 0 };
|
||||
GstStructure *structure = gst_caps_get_structure (caps, 0);
|
||||
int c;
|
||||
|
||||
g_value_init (&chanpos, GST_TYPE_ARRAY);
|
||||
g_value_init (&pos, GST_TYPE_AUDIO_CHANNEL_POSITION);
|
||||
|
||||
for (c = 0; c < channels; c++) {
|
||||
g_value_set_enum (&pos, channelpositions[c]);
|
||||
gst_value_array_append_value (&chanpos, &pos);
|
||||
}
|
||||
g_value_unset (&pos);
|
||||
|
||||
gst_structure_set_value (structure, "channel-positions", &chanpos);
|
||||
g_value_unset (&chanpos);
|
||||
}
|
||||
|
||||
/* For channels > 2, caps have to have channel positions. This adds some simple
|
||||
* ones. Only implemented for channels between 1 and 6.
|
||||
*/
|
||||
static GstCaps *
|
||||
get_float_mc_caps (guint channels, gchar * endianness, guint width)
|
||||
{
|
||||
GstCaps *caps = get_float_caps (channels, endianness, width);
|
||||
|
||||
if (channels <= 6)
|
||||
set_channel_positions (caps, channels, channelpositions[channels - 1]);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
get_int_mc_caps (guint channels, gchar * endianness, guint width,
|
||||
guint depth, gboolean signedness)
|
||||
{
|
||||
GstCaps *caps = get_int_caps (channels, endianness, width, depth, signedness);
|
||||
|
||||
if (channels <= 6)
|
||||
set_channel_positions (caps, channels, channelpositions[channels - 1]);
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* eats the refs to the caps */
|
||||
static void
|
||||
verify_convert (const gchar * which, void *in, int inlength,
|
||||
|
@ -341,6 +424,24 @@ GST_START_TEST (test_float_conversion)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_multichannel_conversion)
|
||||
{
|
||||
{
|
||||
/* Ensure that audioconvert prefers to convert to integer, rather than mix
|
||||
* to mono
|
||||
*/
|
||||
gfloat in[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
|
||||
gfloat out[] = { 0.0, 0.0 };
|
||||
|
||||
/* only one direction conversion, the other direction does
|
||||
* not produce exactly the same as the input due to floating
|
||||
* point rounding errors etc. */
|
||||
RUN_CONVERSION ("3 channels to 1", in, get_float_mc_caps (3,
|
||||
"BYTE_ORDER", 32), out, get_float_caps (1, "BYTE_ORDER", 32));
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
Suite *
|
||||
audioconvert_suite (void)
|
||||
|
@ -352,6 +453,7 @@ audioconvert_suite (void)
|
|||
tcase_add_test (tc_chain, test_int16);
|
||||
tcase_add_test (tc_chain, test_int_conversion);
|
||||
tcase_add_test (tc_chain, test_float_conversion);
|
||||
tcase_add_test (tc_chain, test_multichannel_conversion);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue