mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-07 16:49:52 +00:00
Don't run inplace if that overwrites source data as we go. Add more tests. Fixes #339837 even more.
Original commit message from CVS: * gst/audioconvert/audioconvert.c: (float), (double), (float_hq), (double_hq), (audio_convert_get_func_index), (audio_convert_prepare_context), (audio_convert_convert): * gst/audioconvert/gstaudioconvert.c: (gst_audio_convert_class_init), (gst_audio_convert_get_unit_size), (gst_audio_convert_transform_caps): * tests/check/elements/audioconvert.c: (GST_START_TEST), (audioconvert_suite): Don't run inplace if that overwrites source data as we go. Add more tests. Fixes #339837 even more.
This commit is contained in:
parent
354c07de8b
commit
2c67c89457
4 changed files with 129 additions and 38 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2007-02-28 Stefan Kost <ensonic@users.sf.net>
|
||||
|
||||
* gst/audioconvert/audioconvert.c: (float), (double), (float_hq),
|
||||
(double_hq), (audio_convert_get_func_index),
|
||||
(audio_convert_prepare_context), (audio_convert_convert):
|
||||
* gst/audioconvert/gstaudioconvert.c:
|
||||
(gst_audio_convert_class_init), (gst_audio_convert_get_unit_size),
|
||||
(gst_audio_convert_transform_caps):
|
||||
* tests/check/elements/audioconvert.c: (GST_START_TEST),
|
||||
(audioconvert_suite):
|
||||
Don't run inplace if that overwrites source data as we go. Add more
|
||||
tests. Fixes #339837 even more.
|
||||
|
||||
2007-02-27 Julien MOUTTE <julien@moutte.net>
|
||||
|
||||
* tests/examples/seek/seek.c: (do_seek), (set_update_scale),
|
||||
|
|
|
@ -43,13 +43,12 @@ audio_convert_unpack_##name
|
|||
|
||||
#define MAKE_UNPACK_FUNC(name, stride, sign, READ_FUNC) \
|
||||
static void \
|
||||
MAKE_UNPACK_FUNC_NAME (name) (gpointer src, gint32 *dst, \
|
||||
MAKE_UNPACK_FUNC_NAME (name) (guint8 *src, gint32 *dst, \
|
||||
gint scale, gint count) \
|
||||
{ \
|
||||
guint8* p = (guint8 *) src; \
|
||||
for (;count; count--) { \
|
||||
*dst++ = (((gint32) READ_FUNC (p)) << scale) ^ (sign); \
|
||||
p+=stride; \
|
||||
*dst++ = (((gint32) READ_FUNC (src)) << scale) ^ (sign); \
|
||||
src+=stride; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -83,16 +82,14 @@ MAKE_UNPACK_FUNC_NAME (float_hq) (gfloat * src, gdouble * dst, gint s,
|
|||
gint count)
|
||||
{
|
||||
for (; count; count--)
|
||||
*dst++ = (gdouble) * src++;
|
||||
*dst++ = (gdouble) (*src++);
|
||||
}
|
||||
|
||||
static void
|
||||
MAKE_UNPACK_FUNC_NAME (double_hq) (gdouble * src, gdouble * dst, gint s,
|
||||
gint count)
|
||||
{
|
||||
/* FIXME: memcpy */
|
||||
for (; count; count--)
|
||||
*dst++ = *src++;
|
||||
memcpy (dst, src, count * sizeof (gdouble));
|
||||
}
|
||||
|
||||
#define READ8(p) GST_READ_UINT8(p)
|
||||
|
@ -150,8 +147,9 @@ static void
|
|||
MAKE_PACK_FUNC_NAME (double) (gint32 * src, gdouble * dst, gint scale,
|
||||
gint count)
|
||||
{
|
||||
for (; count; count--)
|
||||
for (; count; count--) {
|
||||
*dst++ = INT2DOUBLE (*src++);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -165,9 +163,7 @@ static void
|
|||
MAKE_PACK_FUNC_NAME (double_hq) (gdouble * src, gdouble * dst, gint s,
|
||||
gint count)
|
||||
{
|
||||
/* FIXME: memcpy */
|
||||
for (; count; count--)
|
||||
*dst++ = *src++;
|
||||
memcpy (dst, src, count * sizeof (gdouble));
|
||||
}
|
||||
|
||||
#define WRITE8(p, v) GST_WRITE_UINT8 (p, v)
|
||||
|
@ -303,16 +299,17 @@ audio_convert_prepare_context (AudioConvertCtx * ctx, AudioConvertFmt * in,
|
|||
/* if both formats are float/double use double as intermediate format and
|
||||
* and switch mixing */
|
||||
if (in->is_int || out->is_int) {
|
||||
GST_DEBUG ("use int mixing");
|
||||
GST_INFO ("use int mixing");
|
||||
ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_int;
|
||||
} else {
|
||||
GST_DEBUG ("use float mixing");
|
||||
GST_INFO ("use float mixing");
|
||||
ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_float;
|
||||
if (!(ctx->unpack = unpack_funcs[idx_in + 2]))
|
||||
goto not_supported;
|
||||
if (!(ctx->pack = pack_funcs[idx_out + 2]))
|
||||
goto not_supported;
|
||||
}
|
||||
GST_INFO ("unitsizes: %d -> %d", in->unit_size, out->unit_size);
|
||||
|
||||
/* check if input is in default format */
|
||||
ctx->in_default = check_default (in);
|
||||
|
@ -321,8 +318,11 @@ audio_convert_prepare_context (AudioConvertCtx * ctx, AudioConvertFmt * in,
|
|||
/* check if output is in default format */
|
||||
ctx->out_default = check_default (out);
|
||||
|
||||
ctx->in_scale = 32 - in->depth;
|
||||
ctx->out_scale = 32 - out->depth;
|
||||
GST_INFO ("in default %d, mix passthrough %d, out default %d",
|
||||
ctx->in_default, ctx->mix_passthrough, ctx->out_default);
|
||||
|
||||
ctx->in_scale = (in->is_int) ? (32 - in->depth) : 0;
|
||||
ctx->out_scale = (out->is_int) ? (32 - out->depth) : 0;
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
@ -369,7 +369,7 @@ audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
|
|||
{
|
||||
gint insize, outsize, size;
|
||||
gpointer outbuf, tmpbuf;
|
||||
gint biggest = 0;
|
||||
gint intemp = 0, outtemp = 0, biggest;
|
||||
|
||||
g_return_val_if_fail (ctx != NULL, FALSE);
|
||||
g_return_val_if_fail (src != NULL, FALSE);
|
||||
|
@ -383,16 +383,19 @@ audio_convert_convert (AudioConvertCtx * ctx, gpointer src,
|
|||
outsize = ctx->out.unit_size * samples;
|
||||
|
||||
/* find biggest temp buffer size */
|
||||
size = (ctx->in.is_int || ctx->out.is_int) ? 32 : 64;
|
||||
size = (ctx->in.is_int || ctx->out.is_int) ?
|
||||
sizeof (gint32) : sizeof (gdouble);
|
||||
|
||||
if (!ctx->in_default)
|
||||
biggest = insize * size / ctx->in.width;
|
||||
intemp = insize * size * 8 / ctx->in.width;
|
||||
if (!ctx->mix_passthrough)
|
||||
biggest = MAX (biggest, outsize * size / ctx->out.width);
|
||||
outtemp = outsize * size * 8 / ctx->out.width;
|
||||
biggest = MAX (intemp, outtemp);
|
||||
|
||||
/* see if one of the buffers can be used as temp */
|
||||
if (outsize >= biggest)
|
||||
if ((outsize >= biggest) && (ctx->out.unit_size <= size))
|
||||
tmpbuf = dst;
|
||||
else if (insize >= biggest && src_writable)
|
||||
else if ((insize >= biggest) && src_writable && (ctx->in.unit_size >= size))
|
||||
tmpbuf = src;
|
||||
else {
|
||||
if (biggest > ctx->tmpbufsize) {
|
||||
|
|
|
@ -197,6 +197,7 @@ static void
|
|||
gst_audio_convert_class_init (GstAudioConvertClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
|
||||
gint i;
|
||||
|
||||
gobject_class->dispose = gst_audio_convert_dispose;
|
||||
|
@ -206,20 +207,20 @@ gst_audio_convert_class_init (GstAudioConvertClass * klass)
|
|||
for (i = 0; i < GST_AUDIO_CHANNEL_POSITION_NUM; i++)
|
||||
supported_positions[i] = i;
|
||||
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->get_unit_size =
|
||||
basetransform_class->get_unit_size =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_get_unit_size);
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->transform_caps =
|
||||
basetransform_class->transform_caps =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_transform_caps);
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->fixate_caps =
|
||||
basetransform_class->fixate_caps =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_fixate_caps);
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
|
||||
basetransform_class->set_caps =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_set_caps);
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
|
||||
basetransform_class->transform_ip =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_transform_ip);
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->transform =
|
||||
basetransform_class->transform =
|
||||
GST_DEBUG_FUNCPTR (gst_audio_convert_transform);
|
||||
|
||||
GST_BASE_TRANSFORM_CLASS (klass)->passthrough_on_same_caps = TRUE;
|
||||
basetransform_class->passthrough_on_same_caps = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -315,6 +316,7 @@ gst_audio_convert_get_unit_size (GstBaseTransform * base, GstCaps * caps,
|
|||
if (!gst_audio_convert_parse_caps (caps, &fmt))
|
||||
goto parse_error;
|
||||
|
||||
GST_INFO_OBJECT (base, "unit_size = %u", fmt.unit_size);
|
||||
*size = fmt.unit_size;
|
||||
|
||||
audio_convert_clean_fmt (&fmt);
|
||||
|
@ -323,6 +325,7 @@ gst_audio_convert_get_unit_size (GstBaseTransform * base, GstCaps * caps,
|
|||
|
||||
parse_error:
|
||||
{
|
||||
GST_INFO_OBJECT (base, "failed to parse caps to get unit_size");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -525,14 +528,9 @@ gst_audio_convert_transform_caps (GstBaseTransform * base,
|
|||
* done the equivalent above. */
|
||||
if (!gst_structure_get_int (structure, "width", &width) || width > 16) {
|
||||
if (isfloat) {
|
||||
/* These are invalid widths/depths for float, but we don't actually use
|
||||
* them - we just pass it to append_with_other_format, which makes them
|
||||
* valid
|
||||
*/
|
||||
GstStructure *s2 = gst_structure_copy (s);
|
||||
|
||||
set_structure_widths (s2, 16, 32);
|
||||
gst_structure_set (s2, "depth", GST_TYPE_INT_RANGE, 16, 32, NULL);
|
||||
set_structure_widths_32_and_64 (s2);
|
||||
append_with_other_format (ret, s2, TRUE);
|
||||
gst_structure_free (s2);
|
||||
} else {
|
||||
|
|
|
@ -348,6 +348,7 @@ verify_convert (const gchar * which, void *in, int inlength,
|
|||
verify_convert (which, inarray, sizeof (inarray), \
|
||||
in_get_caps, outarray, sizeof (outarray), out_get_caps)
|
||||
|
||||
|
||||
GST_START_TEST (test_int16)
|
||||
{
|
||||
/* stereo to mono */
|
||||
|
@ -384,6 +385,32 @@ GST_START_TEST (test_int16)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_float32)
|
||||
{
|
||||
/* stereo to mono */
|
||||
{
|
||||
gfloat in[] = { 0.6, -0.0078125, 0.03125, 0.03125 };
|
||||
gfloat out[] = { 0.29609375, 0.03125 };
|
||||
|
||||
RUN_CONVERSION ("float32 stereo to mono",
|
||||
in, get_float_caps (2, "BYTE_ORDER", 32),
|
||||
out, get_float_caps (1, "BYTE_ORDER", 32));
|
||||
}
|
||||
/* mono to stereo */
|
||||
{
|
||||
gfloat in[] = { 0.015625, 0.03125 };
|
||||
gfloat out[] = { 0.015625, 0.015625, 0.03125, 0.03125 };
|
||||
|
||||
RUN_CONVERSION ("float32 mono to stereo",
|
||||
in, get_float_caps (1, "BYTE_ORDER", 32),
|
||||
out, get_float_caps (2, "BYTE_ORDER", 32));
|
||||
}
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_int_conversion)
|
||||
{
|
||||
/* 8 <-> 16 signed */
|
||||
|
@ -448,6 +475,7 @@ GST_START_TEST (test_int_conversion)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_float_conversion)
|
||||
{
|
||||
/* 32 float <-> 16 signed */
|
||||
|
@ -459,9 +487,55 @@ GST_START_TEST (test_float_conversion)
|
|||
/* 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 ("32 float to 16 signed", in, get_float_caps (1,
|
||||
"BYTE_ORDER", 32), out, get_int_caps (1, "BYTE_ORDER", 16, 16, TRUE)
|
||||
);
|
||||
RUN_CONVERSION ("32 float to 16 signed",
|
||||
in, get_float_caps (1, "BYTE_ORDER", 32),
|
||||
out, get_int_caps (1, "BYTE_ORDER", 16, 16, TRUE));
|
||||
}
|
||||
{
|
||||
gint16 in[] = { 0, -32768, 16384, -16384 };
|
||||
gfloat out[] = { 0.0, -1.0, 0.5, -0.5 };
|
||||
|
||||
RUN_CONVERSION ("16 signed to 32 float",
|
||||
in, get_int_caps (1, "BYTE_ORDER", 16, 16, TRUE),
|
||||
out, get_float_caps (1, "BYTE_ORDER", 32));
|
||||
}
|
||||
|
||||
/* 64 float <-> 16 signed */
|
||||
/* NOTE: if audioconvert was doing dithering we'd have a problem */
|
||||
{
|
||||
gdouble in[] = { 0.0, 1.0, -1.0, 0.5, -0.5, 1.1, -1.1 };
|
||||
gint16 out[] = { 0, 32767, -32768, 16384, -16384, 32767, -32768 };
|
||||
|
||||
/* 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 ("64 float to 16 signed",
|
||||
in, get_float_caps (1, "BYTE_ORDER", 64),
|
||||
out, get_int_caps (1, "BYTE_ORDER", 16, 16, TRUE));
|
||||
}
|
||||
{
|
||||
gint16 in[] = { 0, -32768, 16384, -16384 };
|
||||
gdouble out[] = { 0.0,
|
||||
4.6566128752457969e-10 * (gdouble) (-32768L << 16), /* ~ -1.0 */
|
||||
4.6566128752457969e-10 * (gdouble) (16384L << 16), /* ~ 0.5 */
|
||||
4.6566128752457969e-10 * (gdouble) (-16384L << 16), /* ~ -0.5 */
|
||||
};
|
||||
|
||||
RUN_CONVERSION ("16 signed to 64 float",
|
||||
in, get_int_caps (1, "BYTE_ORDER", 16, 16, TRUE),
|
||||
out, get_float_caps (1, "BYTE_ORDER", 64));
|
||||
}
|
||||
{
|
||||
gint32 in[] = { 0, (-1L << 31), (1L << 30), (-1L << 30) };
|
||||
gdouble out[] = { 0.0,
|
||||
4.6566128752457969e-10 * (gdouble) (-1L << 31), /* ~ -1.0 */
|
||||
4.6566128752457969e-10 * (gdouble) (1L << 30), /* ~ 0.5 */
|
||||
4.6566128752457969e-10 * (gdouble) (-1L << 30), /* ~ -0.5 */
|
||||
};
|
||||
|
||||
RUN_CONVERSION ("32 signed to 64 float",
|
||||
in, get_int_caps (1, "BYTE_ORDER", 32, 32, TRUE),
|
||||
out, get_float_caps (1, "BYTE_ORDER", 64));
|
||||
}
|
||||
|
||||
/* 64-bit float <-> 32-bit float */
|
||||
|
@ -481,6 +555,7 @@ GST_START_TEST (test_float_conversion)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_multichannel_conversion)
|
||||
{
|
||||
{
|
||||
|
@ -501,6 +576,7 @@ GST_START_TEST (test_multichannel_conversion)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
GST_START_TEST (test_channel_remapping)
|
||||
{
|
||||
/* float */
|
||||
|
@ -606,6 +682,7 @@ audioconvert_suite (void)
|
|||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_int16);
|
||||
tcase_add_test (tc_chain, test_float32);
|
||||
tcase_add_test (tc_chain, test_int_conversion);
|
||||
tcase_add_test (tc_chain, test_float_conversion);
|
||||
tcase_add_test (tc_chain, test_multichannel_conversion);
|
||||
|
|
Loading…
Reference in a new issue