summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2015-12-29 14:23:59 +0100
committerStefan Sauer <ensonic@users.sf.net>2015-12-29 14:40:32 +0100
commit7bbfa39ada905b44743170f6c29d13e5fefb5888 (patch)
treece44304097041991d3eb9cf5ba76aae432401fff
parentf2ecf85103444563aed640402f08975de6e7f1f7 (diff)
audioconvert: fix passthrough operation
We did not take the sample size into account. Rearrange the tests to have more conversion test and an extra test case for passthrough operations. Fixes #759890
-rw-r--r--gst-libs/gst/audio/audio-converter.c8
-rw-r--r--tests/check/elements/audioconvert.c219
2 files changed, 161 insertions, 66 deletions
diff --git a/gst-libs/gst/audio/audio-converter.c b/gst-libs/gst/audio/audio-converter.c
index 030b4c95e..a27a830f5 100644
--- a/gst-libs/gst/audio/audio-converter.c
+++ b/gst-libs/gst/audio/audio-converter.c
@@ -869,6 +869,7 @@ gst_audio_converter_samples (GstAudioConverter * convert,
in_samples = MIN (in_samples, out_samples);
if (in_samples == 0) {
+ GST_LOG ("skipping empty buffer");
*in_consumed = 0;
*out_produced = 0;
return TRUE;
@@ -877,8 +878,13 @@ gst_audio_converter_samples (GstAudioConverter * convert,
chain = convert->pack_chain;
if (convert->passthrough) {
+ gsize bytes = in_samples * chain->inc *
+ (convert->in.bpf / convert->in.channels);
+
+ GST_LOG ("passthrough: %" G_GSIZE_FORMAT " / %" G_GSIZE_FORMAT " bytes",
+ in_samples, bytes);
for (i = 0; i < chain->blocks; i++)
- memcpy (out[i], in[i], in_samples * chain->inc);
+ memcpy (out[i], in[i], bytes);
*out_produced = in_samples;
*in_consumed = in_samples;
return TRUE;
diff --git a/tests/check/elements/audioconvert.c b/tests/check/elements/audioconvert.c
index 23b5e4adb..fe497b937 100644
--- a/tests/check/elements/audioconvert.c
+++ b/tests/check/elements/audioconvert.c
@@ -106,7 +106,7 @@ get_int_caps (guint channels, gint endianness, guint width,
fmt = gst_audio_format_build_integer (signedness, endianness, width, depth);
gst_audio_info_init (&info);
- gst_audio_info_set_format (&info, fmt, 48000, channels, NULL);
+ gst_audio_info_set_format (&info, fmt, GST_AUDIO_DEF_RATE, channels, NULL);
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
@@ -141,8 +141,8 @@ get_float_caps (guint channels, gint endianness, guint width)
g_assert (channels <= 2);
gst_audio_info_init (&info);
- gst_audio_info_set_format (&info, get_float_format (endianness, width), 48000,
- channels, NULL);
+ gst_audio_info_set_format (&info, get_float_format (endianness, width),
+ GST_AUDIO_DEF_RATE, channels, NULL);
caps = gst_audio_info_to_caps (&info);
fail_unless (caps != NULL);
@@ -338,10 +338,10 @@ get_float_mc_caps (guint channels, gint endianness, guint width,
if (position) {
gst_audio_info_set_format (&info, get_float_format (endianness, width),
- 48000, channels, position);
+ GST_AUDIO_DEF_RATE, channels, position);
} else if (channels <= 6) {
gst_audio_info_set_format (&info, get_float_format (endianness, width),
- 48000, channels, channelpositions[channels - 1]);
+ GST_AUDIO_DEF_RATE, channels, channelpositions[channels - 1]);
} else {
GstAudioChannelPosition pos[64];
gint i;
@@ -349,7 +349,7 @@ get_float_mc_caps (guint channels, gint endianness, guint width,
for (i = 0; i < 64; i++)
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
gst_audio_info_set_format (&info, get_float_format (endianness, width),
- 48000, channels, pos);
+ GST_AUDIO_DEF_RATE, channels, pos);
}
caps = gst_audio_info_to_caps (&info);
@@ -373,9 +373,10 @@ get_int_mc_caps (guint channels, gint endianness, guint width,
gst_audio_info_init (&info);
if (position) {
- gst_audio_info_set_format (&info, fmt, 48000, channels, position);
+ gst_audio_info_set_format (&info, fmt, GST_AUDIO_DEF_RATE, channels,
+ position);
} else if (channels <= 6) {
- gst_audio_info_set_format (&info, fmt, 48000, channels,
+ gst_audio_info_set_format (&info, fmt, GST_AUDIO_DEF_RATE, channels,
channelpositions[channels - 1]);
} else {
GstAudioChannelPosition pos[64];
@@ -383,7 +384,7 @@ get_int_mc_caps (guint channels, gint endianness, guint width,
for (i = 0; i < 64; i++)
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
- gst_audio_info_set_format (&info, fmt, 48000, channels, pos);
+ gst_audio_info_set_format (&info, fmt, GST_AUDIO_DEF_RATE, channels, pos);
}
caps = gst_audio_info_to_caps (&info);
@@ -398,7 +399,7 @@ get_int_mc_caps (guint channels, gint endianness, guint width,
static void
verify_convert (const gchar * which, void *in, int inlength,
GstCaps * incaps, void *out, int outlength, GstCaps * outcaps,
- GstFlowReturn expected_flow)
+ GstFlowReturn expected_flow, gboolean in_place_allowed)
{
GstBuffer *inbuffer, *outbuffer;
GstElement *audioconvert;
@@ -422,6 +423,13 @@ verify_convert (const gchar * which, void *in, int inlength,
gst_buffer_fill (inbuffer, 0, in, inlength);
ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
+ if (!in_place_allowed) {
+ /* take extra ref to force processing */
+ gst_buffer_ref (inbuffer);
+ gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (audioconvert),
+ FALSE);
+ }
+
/* pushing gives away my reference ... */
GST_DEBUG ("push it");
fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), expected_flow);
@@ -434,6 +442,11 @@ verify_convert (const gchar * which, void *in, int inlength,
fail_unless (g_list_length (buffers) == 1);
fail_if ((outbuffer = (GstBuffer *) buffers->data) == NULL);
+ if (!in_place_allowed) {
+ /* release extra ref */
+ gst_buffer_unref (inbuffer);
+ }
+
ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
fail_unless_equals_int (gst_buffer_get_size (outbuffer), outlength);
@@ -477,11 +490,18 @@ done:
#define RUN_CONVERSION(which, inarray, in_get_caps, outarray, out_get_caps) \
verify_convert (which, inarray, sizeof (inarray), \
- in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK)
+ in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK, \
+ TRUE)
#define RUN_CONVERSION_TO_FAIL(which, inarray, in_caps, outarray, out_caps) \
verify_convert (which, inarray, sizeof (inarray), \
- in_caps, outarray, sizeof (outarray), out_caps, GST_FLOW_NOT_NEGOTIATED)
+ in_caps, outarray, sizeof (outarray), out_caps, \
+ GST_FLOW_NOT_NEGOTIATED, TRUE)
+
+#define RUN_CONVERSION_NOT_INPLACE(which, inarray, in_get_caps, outarray, out_get_caps) \
+ verify_convert (which, inarray, sizeof (inarray), \
+ in_get_caps, outarray, sizeof (outarray), out_get_caps, GST_FLOW_OK, \
+ FALSE)
GST_START_TEST (test_int16)
@@ -672,6 +692,63 @@ GST_END_TEST;
GST_START_TEST (test_float_conversion)
{
+ /* 64-bit float <-> 32-bit float */
+ {
+ gdouble in[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
+ gfloat out[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
+
+ RUN_CONVERSION ("64 float to 32 float",
+ in, get_float_caps (1, G_BYTE_ORDER, 64),
+ out, get_float_caps (1, G_BYTE_ORDER, 32));
+
+ RUN_CONVERSION ("32 float to 64 float",
+ out, get_float_caps (1, G_BYTE_ORDER, 32),
+ in, get_float_caps (1, G_BYTE_ORDER, 64));
+ }
+
+ /* 32-bit float little endian <-> big endian */
+ {
+ gfloat le[] = { GFLOAT_TO_LE (0.0), GFLOAT_TO_LE (1.0), GFLOAT_TO_LE (-1.0),
+ GFLOAT_TO_LE (0.5), GFLOAT_TO_LE (-0.5)
+ };
+ gfloat be[] = { GFLOAT_TO_BE (0.0), GFLOAT_TO_BE (1.0), GFLOAT_TO_BE (-1.0),
+ GFLOAT_TO_BE (0.5), GFLOAT_TO_BE (-0.5)
+ };
+
+ RUN_CONVERSION ("32 float LE to BE",
+ le, get_float_caps (1, G_LITTLE_ENDIAN, 32),
+ be, get_float_caps (1, G_BIG_ENDIAN, 32));
+
+ RUN_CONVERSION ("32 float BE to LE",
+ be, get_float_caps (1, G_BIG_ENDIAN, 32),
+ le, get_float_caps (1, G_LITTLE_ENDIAN, 32));
+ }
+
+ /* 64-bit float little endian <-> big endian */
+ {
+ gdouble le[] =
+ { GDOUBLE_TO_LE (0.0), GDOUBLE_TO_LE (1.0), GDOUBLE_TO_LE (-1.0),
+ GDOUBLE_TO_LE (0.5), GDOUBLE_TO_LE (-0.5)
+ };
+ gdouble be[] =
+ { GDOUBLE_TO_BE (0.0), GDOUBLE_TO_BE (1.0), GDOUBLE_TO_BE (-1.0),
+ GDOUBLE_TO_BE (0.5), GDOUBLE_TO_BE (-0.5)
+ };
+
+ RUN_CONVERSION ("64 float LE to BE",
+ le, get_float_caps (1, G_LITTLE_ENDIAN, 64),
+ be, get_float_caps (1, G_BIG_ENDIAN, 64));
+
+ RUN_CONVERSION ("64 float BE to LE",
+ be, get_float_caps (1, G_BIG_ENDIAN, 64),
+ le, get_float_caps (1, G_LITTLE_ENDIAN, 64));
+ }
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_int_float_conversion)
+{
/* 32 float <-> 16 signed */
/* NOTE: if audioconvert was doing dithering we'd have a problem */
{
@@ -756,63 +833,10 @@ GST_START_TEST (test_float_conversion)
in, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
out, get_float_caps (1, G_BYTE_ORDER, 64));
}
-
- /* 64-bit float <-> 32-bit float */
- {
- gdouble in[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
- gfloat out[] = { 0.0, 1.0, -1.0, 0.5, -0.5 };
-
- RUN_CONVERSION ("64 float to 32 float",
- in, get_float_caps (1, G_BYTE_ORDER, 64),
- out, get_float_caps (1, G_BYTE_ORDER, 32));
-
- RUN_CONVERSION ("32 float to 64 float",
- out, get_float_caps (1, G_BYTE_ORDER, 32),
- in, get_float_caps (1, G_BYTE_ORDER, 64));
- }
-
- /* 32-bit float little endian <-> big endian */
- {
- gfloat le[] = { GFLOAT_TO_LE (0.0), GFLOAT_TO_LE (1.0), GFLOAT_TO_LE (-1.0),
- GFLOAT_TO_LE (0.5), GFLOAT_TO_LE (-0.5)
- };
- gfloat be[] = { GFLOAT_TO_BE (0.0), GFLOAT_TO_BE (1.0), GFLOAT_TO_BE (-1.0),
- GFLOAT_TO_BE (0.5), GFLOAT_TO_BE (-0.5)
- };
-
- RUN_CONVERSION ("32 float LE to BE",
- le, get_float_caps (1, G_LITTLE_ENDIAN, 32),
- be, get_float_caps (1, G_BIG_ENDIAN, 32));
-
- RUN_CONVERSION ("32 float BE to LE",
- be, get_float_caps (1, G_BIG_ENDIAN, 32),
- le, get_float_caps (1, G_LITTLE_ENDIAN, 32));
- }
-
- /* 64-bit float little endian <-> big endian */
- {
- gdouble le[] =
- { GDOUBLE_TO_LE (0.0), GDOUBLE_TO_LE (1.0), GDOUBLE_TO_LE (-1.0),
- GDOUBLE_TO_LE (0.5), GDOUBLE_TO_LE (-0.5)
- };
- gdouble be[] =
- { GDOUBLE_TO_BE (0.0), GDOUBLE_TO_BE (1.0), GDOUBLE_TO_BE (-1.0),
- GDOUBLE_TO_BE (0.5), GDOUBLE_TO_BE (-0.5)
- };
-
- RUN_CONVERSION ("64 float LE to BE",
- le, get_float_caps (1, G_LITTLE_ENDIAN, 64),
- be, get_float_caps (1, G_BIG_ENDIAN, 64));
-
- RUN_CONVERSION ("64 float BE to LE",
- be, get_float_caps (1, G_BIG_ENDIAN, 64),
- le, get_float_caps (1, G_LITTLE_ENDIAN, 64));
- }
}
GST_END_TEST;
-
GST_START_TEST (test_multichannel_conversion)
{
{
@@ -1010,6 +1034,68 @@ GST_START_TEST (test_multichannel_conversion)
GST_END_TEST;
+GST_START_TEST (test_passthrough)
+{
+ /* int 8 bit */
+ {
+ gint8 data[] = { 0, 1, 2, 127, -127 };
+
+ RUN_CONVERSION ("int 8 bit passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE)
+ );
+ RUN_CONVERSION_NOT_INPLACE ("int 8 bit passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 8, 8, TRUE)
+ );
+ }
+ /* int 16 bit signed */
+ {
+ gint16 data[] = { 0, 256, 512, 32512, -32512 };
+
+ RUN_CONVERSION ("int 16 bit signed passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE)
+ );
+ RUN_CONVERSION_NOT_INPLACE ("int 16 bit signed passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 16, 16, TRUE)
+ );
+ }
+ /* int 32 bit signed */
+ {
+ gint32 data[] = { 0, G_MININT32, G_MAXINT32,
+ (32 << 16), (32 << 16) + (1 << 15), (32 << 16) - (1 << 15),
+ (32 << 16) + (2 << 15), (32 << 16) - (2 << 15),
+ (-32 << 16) + (1 << 15), (-32 << 16) - (1 << 15),
+ (-32 << 16) + (2 << 15), (-32 << 16) - (2 << 15),
+ (-32 << 16)
+ };
+ RUN_CONVERSION ("int 32 bit signed passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE)
+ );
+ RUN_CONVERSION_NOT_INPLACE ("int 32 bit signed passthrough",
+ data, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE),
+ data, get_int_caps (1, G_BYTE_ORDER, 32, 32, TRUE)
+ );
+ }
+
+ /* int 16 bit signed stereo */
+ {
+ gint16 data[] = { 0, 0, 1, 1, 2, 2, 3, 3 };
+
+ RUN_CONVERSION ("int 16 bit signed 2 channel passthrough",
+ data, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE),
+ data, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE));
+ RUN_CONVERSION_NOT_INPLACE ("int 16 bit signed 2 channel passthrough",
+ data, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE),
+ data, get_int_caps (2, G_BYTE_ORDER, 16, 16, TRUE));
+ }
+}
+
+GST_END_TEST;
+
GST_START_TEST (test_caps_negotiation)
{
GstElement *src, *ac1, *ac2, *ac3, *sink;
@@ -1500,11 +1586,14 @@ audioconvert_suite (void)
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_int_float_conversion);
tcase_add_test (tc_chain, test_multichannel_conversion);
+ tcase_add_test (tc_chain, test_passthrough);
tcase_add_test (tc_chain, test_caps_negotiation);
tcase_add_test (tc_chain, test_convert_undefined_multichannel);
tcase_add_test (tc_chain, test_preserve_width);
+
return s;
}