diff options
author | Stefan Sauer <ensonic@users.sf.net> | 2015-12-29 14:23:59 +0100 |
---|---|---|
committer | Stefan Sauer <ensonic@users.sf.net> | 2015-12-29 14:40:32 +0100 |
commit | 7bbfa39ada905b44743170f6c29d13e5fefb5888 (patch) | |
tree | ce44304097041991d3eb9cf5ba76aae432401fff | |
parent | f2ecf85103444563aed640402f08975de6e7f1f7 (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.c | 8 | ||||
-rw-r--r-- | tests/check/elements/audioconvert.c | 219 |
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; } |