From: Mark Nauwelaerts Date: Mon, 27 Feb 2012 22:46:15 +0000 (+0100) Subject: wavpackdec: adjust to audio format limitations X-Git-Tag: RELEASE-0.11.2~2^2~36 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a5144cbba0c11547a377a8eb8f5383ccf12d6d84;p=platform%2Fupstream%2Fgst-plugins-good.git wavpackdec: adjust to audio format limitations ... which does not allow expressing arbitrary depth in a GstAudioFormat. Also adjust unit test to modified behaviour. --- diff --git a/ext/wavpack/gstwavpackdec.c b/ext/wavpack/gstwavpackdec.c index 365544b..2be8149 100644 --- a/ext/wavpack/gstwavpackdec.c +++ b/ext/wavpack/gstwavpackdec.c @@ -71,11 +71,20 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " - "depth = (int) [ 1, 32 ], " + "width = (int) 8, depth = (int) 8, " "channels = (int) [ 1, 8 ], " "rate = (int) [ 6000, 192000 ], " - "endianness = (int) BYTE_ORDER, " "signed = (boolean) true") + "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; " + "audio/x-raw-int, " + "width = (int) 16, depth = (int) 16, " + "channels = (int) [ 1, 8 ], " + "rate = (int) [ 6000, 192000 ], " + "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; " + "audio/x-raw-int, " + "width = (int) 32, depth = (int) 32, " + "channels = (int) [ 1, 8 ], " + "rate = (int) [ 6000, 192000 ], " + "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; ") ); static gboolean gst_wavpack_dec_start (GstAudioDecoder * dec); @@ -186,11 +195,17 @@ gst_wavpack_dec_negotiate (GstWavpackDec * dec) { GstCaps *caps; + /* arrange for 1, 2 or 4-byte width == depth output */ + if (dec->depth == 24) + dec->width = 32; + else + dec->width = dec->depth; + caps = gst_caps_new_simple ("audio/x-raw-int", "rate", G_TYPE_INT, dec->sample_rate, "channels", G_TYPE_INT, dec->channels, - "depth", G_TYPE_INT, dec->depth, - "width", G_TYPE_INT, 32, + "depth", G_TYPE_INT, dec->width, + "width", G_TYPE_INT, dec->width, "endianness", G_TYPE_INT, G_BYTE_ORDER, "signed", G_TYPE_BOOLEAN, TRUE, NULL); @@ -279,6 +294,9 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf) WavpackHeader wph; int32_t decoded, unpacked_size; gboolean format_changed; + gint width, depth, i, max; + gint32 *dec_data = NULL; + guint8 *out_data; dec = GST_WAVPACK_DEC (bdec); @@ -354,7 +372,7 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf) } /* alloc output buffer */ - unpacked_size = 4 * wph.block_samples * dec->channels; + unpacked_size = (dec->width / 8) * wph.block_samples * dec->channels; ret = gst_pad_alloc_buffer (GST_AUDIO_DECODER_SRC_PAD (dec), GST_BUFFER_OFFSET (buf), unpacked_size, GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf); @@ -362,12 +380,47 @@ gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf) if (ret != GST_FLOW_OK) goto out; + dec_data = g_malloc (4 * wph.block_samples * dec->channels); + out_data = GST_BUFFER_DATA (outbuf); + /* decode */ - decoded = WavpackUnpackSamples (dec->context, - (int32_t *) GST_BUFFER_DATA (outbuf), wph.block_samples); + decoded = WavpackUnpackSamples (dec->context, dec_data, wph.block_samples); if (decoded != wph.block_samples) goto decode_error; + width = dec->width; + depth = dec->depth; + max = dec->channels * wph.block_samples; + if (width == 8) { + gint8 *outbuffer = (gint8 *) out_data; + + for (i = 0; i < max; i--) { + *outbuffer++ = (gint8) (dec_data[i]); + } + } else if (width == 16) { + gint16 *outbuffer = (gint16 *) out_data; + + for (i = 0; i < max; i++) { + *outbuffer++ = (gint8) (dec_data[i]); + } + } else if (dec->width == 32) { + gint32 *outbuffer = (gint32 *) out_data; + + if (width != depth) { + for (i = 0; i < max; i++) { + *outbuffer++ = (gint32) (dec_data[i] << (width - depth)); + } + } else { + for (i = 0; i < max; i++) { + *outbuffer++ = (gint32) dec_data[i]; + } + } + } else { + g_assert_not_reached (); + } + + g_free (dec_data); + ret = gst_audio_decoder_finish_frame (bdec, outbuf, 1); out: @@ -410,6 +463,7 @@ decode_error: } GST_AUDIO_DECODER_ERROR (bdec, 1, STREAM, DECODE, (NULL), ("decoding error: %s", reason), ret); + g_free (dec_data); if (outbuf) gst_buffer_unref (outbuf); if (ret == GST_FLOW_OK) diff --git a/ext/wavpack/gstwavpackdec.h b/ext/wavpack/gstwavpackdec.h index 4b8b057..68e8e33 100644 --- a/ext/wavpack/gstwavpackdec.h +++ b/ext/wavpack/gstwavpackdec.h @@ -57,6 +57,7 @@ struct _GstWavpackDec gint sample_rate; gint depth; + gint width; gint channels; gint channel_mask; }; diff --git a/tests/check/elements/wavpackdec.c b/tests/check/elements/wavpackdec.c index 0d17323..b1498e1 100644 --- a/tests/check/elements/wavpackdec.c +++ b/tests/check/elements/wavpackdec.c @@ -52,7 +52,7 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("audio/x-raw-int, " - "width = (int) 32, " + "width = (int) 16, " "depth = (int) 16, " "channels = (int) 1, " "rate = (int) 44100, " @@ -112,23 +112,20 @@ GST_START_TEST (test_decode_frame) memcpy (GST_BUFFER_DATA (inbuffer), test_frame, sizeof (test_frame)); ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); GST_BUFFER_TIMESTAMP (inbuffer) = 0; - gst_buffer_ref (inbuffer); gst_element_set_bus (wavpackdec, bus); /* should decode the buffer without problems */ fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL); /* uncompressed data should be 102400 bytes */ - fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), 102400); + fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), 51200); - /* and all 102400 bytes must be 0, i.e. silence */ - for (i = 0; i < 102400; i++) + /* and all bytes must be 0, i.e. silence */ + for (i = 0; i < 51200; i++) fail_unless_equals_int (GST_BUFFER_DATA (outbuffer)[i], 0); ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1); @@ -166,14 +163,11 @@ GST_START_TEST (test_decode_frame_with_broken_header) GST_BUFFER_DATA (inbuffer)[2] = 'e'; ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); GST_BUFFER_TIMESTAMP (inbuffer) = 0; - gst_buffer_ref (inbuffer); gst_element_set_bus (wavpackdec, bus); /* should fail gracefully */ fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_ERROR); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); fail_if ((message = gst_bus_pop (bus)) == NULL); fail_unless_message_error (message, STREAM, DECODE); @@ -204,14 +198,11 @@ GST_START_TEST (test_decode_frame_with_incomplete_frame) memcpy (GST_BUFFER_DATA (inbuffer), test_frame, sizeof (test_frame) - 2); ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); GST_BUFFER_TIMESTAMP (inbuffer) = 0; - gst_buffer_ref (inbuffer); gst_element_set_bus (wavpackdec, bus); /* should fail gracefully */ fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_ERROR); - ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); - gst_buffer_unref (inbuffer); fail_if ((message = gst_bus_pop (bus)) == NULL); fail_unless_message_error (message, STREAM, DECODE);