Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / ext / wavpack / gstwavpackdec.c
1 /* GStreamer Wavpack plugin
2  * Copyright (c) 2005 Arwed v. Merkatz <v.merkatz@gmx.net>
3  * Copyright (c) 2006 Edward Hervey <bilboed@gmail.com>
4  * Copyright (c) 2006 Sebastian Dröge <slomo@circular-chaos.org>
5  *
6  * gstwavpackdec.c: raw Wavpack bitstream decoder
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /**
25  * SECTION:element-wavpackdec
26  *
27  * WavpackDec decodes framed (for example by the WavpackParse element)
28  * Wavpack streams and decodes them to raw audio.
29  * <ulink url="http://www.wavpack.com/">Wavpack</ulink> is an open-source
30  * audio codec that features both lossless and lossy encoding.
31  *
32  * <refsect2>
33  * <title>Example launch line</title>
34  * |[
35  * gst-launch filesrc location=test.wv ! wavpackparse ! wavpackdec ! audioconvert ! audioresample ! autoaudiosink
36  * ]| This pipeline decodes the Wavpack file test.wv into raw audio buffers and
37  * tries to play it back using an automatically found audio sink.
38  * </refsect2>
39  */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include <gst/gst.h>
46 #include <gst/audio/audio.h>
47 #include <gst/audio/multichannel.h>
48
49 #include <math.h>
50 #include <string.h>
51
52 #include <wavpack/wavpack.h>
53 #include "gstwavpackdec.h"
54 #include "gstwavpackcommon.h"
55 #include "gstwavpackstreamreader.h"
56
57
58 GST_DEBUG_CATEGORY_STATIC (gst_wavpack_dec_debug);
59 #define GST_CAT_DEFAULT gst_wavpack_dec_debug
60
61 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
62     GST_PAD_SINK,
63     GST_PAD_ALWAYS,
64     GST_STATIC_CAPS ("audio/x-wavpack, "
65         "width = (int) [ 1, 32 ], "
66         "channels = (int) [ 1, 8 ], "
67         "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true")
68     );
69
70 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
71     GST_PAD_SRC,
72     GST_PAD_ALWAYS,
73     GST_STATIC_CAPS ("audio/x-raw-int, "
74         "width = (int) 8, depth = (int) 8, "
75         "channels = (int) [ 1, 8 ], "
76         "rate = (int) [ 6000, 192000 ], "
77         "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; "
78         "audio/x-raw-int, "
79         "width = (int) 16, depth = (int) 16, "
80         "channels = (int) [ 1, 8 ], "
81         "rate = (int) [ 6000, 192000 ], "
82         "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; "
83         "audio/x-raw-int, "
84         "width = (int) 32, depth = (int) 32, "
85         "channels = (int) [ 1, 8 ], "
86         "rate = (int) [ 6000, 192000 ], "
87         "endianness = (int) BYTE_ORDER, " "signed = (boolean) true; ")
88     );
89
90 static gboolean gst_wavpack_dec_start (GstAudioDecoder * dec);
91 static gboolean gst_wavpack_dec_stop (GstAudioDecoder * dec);
92 static gboolean gst_wavpack_dec_set_format (GstAudioDecoder * dec,
93     GstCaps * caps);
94 static GstFlowReturn gst_wavpack_dec_handle_frame (GstAudioDecoder * dec,
95     GstBuffer * buffer);
96
97 static void gst_wavpack_dec_finalize (GObject * object);
98 static void gst_wavpack_dec_post_tags (GstWavpackDec * dec);
99
100 GST_BOILERPLATE (GstWavpackDec, gst_wavpack_dec, GstAudioDecoder,
101     GST_TYPE_AUDIO_DECODER);
102
103 static void
104 gst_wavpack_dec_base_init (gpointer klass)
105 {
106   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
107
108   gst_element_class_add_pad_template (element_class,
109       gst_static_pad_template_get (&src_factory));
110   gst_element_class_add_pad_template (element_class,
111       gst_static_pad_template_get (&sink_factory));
112   gst_element_class_set_details_simple (element_class, "Wavpack audio decoder",
113       "Codec/Decoder/Audio",
114       "Decodes Wavpack audio data",
115       "Arwed v. Merkatz <v.merkatz@gmx.net>, "
116       "Sebastian Dröge <slomo@circular-chaos.org>");
117 }
118
119 static void
120 gst_wavpack_dec_class_init (GstWavpackDecClass * klass)
121 {
122   GObjectClass *gobject_class = (GObjectClass *) klass;
123   GstAudioDecoderClass *base_class = (GstAudioDecoderClass *) (klass);
124
125   gobject_class->finalize = gst_wavpack_dec_finalize;
126
127   base_class->start = GST_DEBUG_FUNCPTR (gst_wavpack_dec_start);
128   base_class->stop = GST_DEBUG_FUNCPTR (gst_wavpack_dec_stop);
129   base_class->set_format = GST_DEBUG_FUNCPTR (gst_wavpack_dec_set_format);
130   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_wavpack_dec_handle_frame);
131 }
132
133 static void
134 gst_wavpack_dec_reset (GstWavpackDec * dec)
135 {
136   dec->wv_id.buffer = NULL;
137   dec->wv_id.position = dec->wv_id.length = 0;
138
139   dec->channels = 0;
140   dec->channel_mask = 0;
141   dec->sample_rate = 0;
142   dec->depth = 0;
143 }
144
145 static void
146 gst_wavpack_dec_init (GstWavpackDec * dec, GstWavpackDecClass * gklass)
147 {
148   dec->context = NULL;
149   dec->stream_reader = gst_wavpack_stream_reader_new ();
150
151   gst_wavpack_dec_reset (dec);
152 }
153
154 static void
155 gst_wavpack_dec_finalize (GObject * object)
156 {
157   GstWavpackDec *dec = GST_WAVPACK_DEC (object);
158
159   g_free (dec->stream_reader);
160   dec->stream_reader = NULL;
161
162   G_OBJECT_CLASS (parent_class)->finalize (object);
163 }
164
165 static gboolean
166 gst_wavpack_dec_start (GstAudioDecoder * dec)
167 {
168   GST_DEBUG_OBJECT (dec, "start");
169
170   /* never mind a few errors */
171   gst_audio_decoder_set_max_errors (dec, 16);
172   /* don't bother us with flushing */
173   gst_audio_decoder_set_drainable (dec, FALSE);
174
175   return TRUE;
176 }
177
178 static gboolean
179 gst_wavpack_dec_stop (GstAudioDecoder * dec)
180 {
181   GstWavpackDec *wpdec = GST_WAVPACK_DEC (dec);
182
183   GST_DEBUG_OBJECT (dec, "stop");
184
185   if (wpdec->context) {
186     WavpackCloseFile (wpdec->context);
187     wpdec->context = NULL;
188   }
189
190   gst_wavpack_dec_reset (wpdec);
191
192   return TRUE;
193 }
194
195 static void
196 gst_wavpack_dec_negotiate (GstWavpackDec * dec)
197 {
198   GstCaps *caps;
199
200   /* arrange for 1, 2 or 4-byte width == depth output */
201   if (dec->depth == 24)
202     dec->width = 32;
203   else
204     dec->width = dec->depth;
205
206   caps = gst_caps_new_simple ("audio/x-raw-int",
207       "rate", G_TYPE_INT, dec->sample_rate,
208       "channels", G_TYPE_INT, dec->channels,
209       "depth", G_TYPE_INT, dec->width,
210       "width", G_TYPE_INT, dec->width,
211       "endianness", G_TYPE_INT, G_BYTE_ORDER,
212       "signed", G_TYPE_BOOLEAN, TRUE, NULL);
213
214   /* Only set the channel layout for more than two channels
215    * otherwise things break unfortunately */
216   if (dec->channel_mask != 0 && dec->channels > 2)
217     if (!gst_wavpack_set_channel_layout (caps, dec->channel_mask))
218       GST_WARNING_OBJECT (dec, "Failed to set channel layout");
219
220   GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
221
222   /* should always succeed */
223   gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), caps);
224   gst_caps_unref (caps);
225 }
226
227 static gboolean
228 gst_wavpack_dec_set_format (GstAudioDecoder * bdec, GstCaps * caps)
229 {
230   GstWavpackDec *dec = GST_WAVPACK_DEC (bdec);
231   GstStructure *structure = gst_caps_get_structure (caps, 0);
232
233   /* Check if we can set the caps here already */
234   if (gst_structure_get_int (structure, "channels", &dec->channels) &&
235       gst_structure_get_int (structure, "rate", &dec->sample_rate) &&
236       gst_structure_get_int (structure, "width", &dec->depth)) {
237     GstAudioChannelPosition *pos;
238
239     /* If we already have the channel layout set from upstream
240      * take this */
241     if (gst_structure_has_field (structure, "channel-positions")) {
242       pos = gst_audio_get_channel_positions (structure);
243       if (pos != NULL && dec->channels > 2) {
244         GstStructure *new_str = gst_caps_get_structure (caps, 0);
245
246         gst_audio_set_channel_positions (new_str, pos);
247         dec->channel_mask =
248             gst_wavpack_get_channel_mask_from_positions (pos, dec->channels);
249       }
250
251       if (pos != NULL)
252         g_free (pos);
253     }
254
255     gst_wavpack_dec_negotiate (dec);
256
257     /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something
258      * is decoded or after the format has changed */
259     gst_wavpack_dec_post_tags (dec);
260   }
261
262   return TRUE;
263 }
264
265 static void
266 gst_wavpack_dec_post_tags (GstWavpackDec * dec)
267 {
268   GstTagList *list;
269   GstFormat format_time = GST_FORMAT_TIME, format_bytes = GST_FORMAT_BYTES;
270   gint64 duration, size;
271
272   /* try to estimate the average bitrate */
273   if (gst_pad_query_peer_duration (GST_AUDIO_DECODER_SINK_PAD (dec),
274           &format_bytes, &size) &&
275       gst_pad_query_peer_duration (GST_AUDIO_DECODER_SINK_PAD (dec),
276           &format_time, &duration) && size > 0 && duration > 0) {
277     guint64 bitrate;
278
279     list = gst_tag_list_new ();
280
281     bitrate = gst_util_uint64_scale (size, 8 * GST_SECOND, duration);
282     gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE,
283         (guint) bitrate, NULL);
284
285     gst_element_post_message (GST_ELEMENT (dec),
286         gst_message_new_tag (GST_OBJECT (dec), list));
287   }
288 }
289
290 static GstFlowReturn
291 gst_wavpack_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
292 {
293   GstWavpackDec *dec;
294   GstBuffer *outbuf = NULL;
295   GstFlowReturn ret = GST_FLOW_OK;
296   WavpackHeader wph;
297   int32_t decoded, unpacked_size;
298   gboolean format_changed;
299   gint width, depth, i, max;
300   gint32 *dec_data = NULL;
301   guint8 *out_data;
302
303   dec = GST_WAVPACK_DEC (bdec);
304
305   g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
306
307   /* check input, we only accept framed input with complete chunks */
308   if (GST_BUFFER_SIZE (buf) < sizeof (WavpackHeader))
309     goto input_not_framed;
310
311   if (!gst_wavpack_read_header (&wph, GST_BUFFER_DATA (buf)))
312     goto invalid_header;
313
314   if (GST_BUFFER_SIZE (buf) < wph.ckSize + 4 * 1 + 4)
315     goto input_not_framed;
316
317   if (!(wph.flags & INITIAL_BLOCK))
318     goto input_not_framed;
319
320   dec->wv_id.buffer = GST_BUFFER_DATA (buf);
321   dec->wv_id.length = GST_BUFFER_SIZE (buf);
322   dec->wv_id.position = 0;
323
324   /* create a new wavpack context if there is none yet but if there
325    * was already one (i.e. caps were set on the srcpad) check whether
326    * the new one has the same caps */
327   if (!dec->context) {
328     gchar error_msg[80];
329
330     dec->context = WavpackOpenFileInputEx (dec->stream_reader,
331         &dec->wv_id, NULL, error_msg, OPEN_STREAMING, 0);
332
333     /* expect this to work */
334     if (!dec->context) {
335       GST_WARNING_OBJECT (dec, "Couldn't decode buffer: %s", error_msg);
336       goto context_failed;
337     }
338   }
339
340   g_assert (dec->context != NULL);
341
342   format_changed =
343       (dec->sample_rate != WavpackGetSampleRate (dec->context)) ||
344       (dec->channels != WavpackGetNumChannels (dec->context)) ||
345       (dec->depth != WavpackGetBytesPerSample (dec->context) * 8) ||
346 #ifdef WAVPACK_OLD_API
347       (dec->channel_mask != dec->context->config.channel_mask);
348 #else
349       (dec->channel_mask != WavpackGetChannelMask (dec->context));
350 #endif
351
352   if (!GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)) || format_changed) {
353     gint channel_mask;
354
355     dec->sample_rate = WavpackGetSampleRate (dec->context);
356     dec->channels = WavpackGetNumChannels (dec->context);
357     dec->depth = WavpackGetBytesPerSample (dec->context) * 8;
358
359 #ifdef WAVPACK_OLD_API
360     channel_mask = dec->context->config.channel_mask;
361 #else
362     channel_mask = WavpackGetChannelMask (dec->context);
363 #endif
364     if (channel_mask == 0)
365       channel_mask = gst_wavpack_get_default_channel_mask (dec->channels);
366
367     dec->channel_mask = channel_mask;
368
369     gst_wavpack_dec_negotiate (dec);
370
371     /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something
372      * is decoded or after the format has changed */
373     gst_wavpack_dec_post_tags (dec);
374   }
375
376   /* alloc output buffer */
377   unpacked_size = (dec->width / 8) * wph.block_samples * dec->channels;
378   ret = gst_pad_alloc_buffer (GST_AUDIO_DECODER_SRC_PAD (dec),
379       GST_BUFFER_OFFSET (buf), unpacked_size,
380       GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf);
381
382   if (ret != GST_FLOW_OK)
383     goto out;
384
385   dec_data = g_malloc (4 * wph.block_samples * dec->channels);
386   out_data = GST_BUFFER_DATA (outbuf);
387
388   /* decode */
389   decoded = WavpackUnpackSamples (dec->context, dec_data, wph.block_samples);
390   if (decoded != wph.block_samples)
391     goto decode_error;
392
393   width = dec->width;
394   depth = dec->depth;
395   max = dec->channels * wph.block_samples;
396   if (width == 8) {
397     gint8 *outbuffer = (gint8 *) out_data;
398
399     for (i = 0; i < max; i--) {
400       *outbuffer++ = (gint8) (dec_data[i]);
401     }
402   } else if (width == 16) {
403     gint16 *outbuffer = (gint16 *) out_data;
404
405     for (i = 0; i < max; i++) {
406       *outbuffer++ = (gint8) (dec_data[i]);
407     }
408   } else if (dec->width == 32) {
409     gint32 *outbuffer = (gint32 *) out_data;
410
411     if (width != depth) {
412       for (i = 0; i < max; i++) {
413         *outbuffer++ = (gint32) (dec_data[i] << (width - depth));
414       }
415     } else {
416       for (i = 0; i < max; i++) {
417         *outbuffer++ = (gint32) dec_data[i];
418       }
419     }
420   } else {
421     g_assert_not_reached ();
422   }
423
424   g_free (dec_data);
425
426   ret = gst_audio_decoder_finish_frame (bdec, outbuf, 1);
427
428 out:
429
430   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
431     GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (ret));
432   }
433
434   return ret;
435
436 /* ERRORS */
437 input_not_framed:
438   {
439     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Expected framed input"));
440     return GST_FLOW_ERROR;
441   }
442 invalid_header:
443   {
444     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("Invalid wavpack header"));
445     return GST_FLOW_ERROR;
446   }
447 context_failed:
448   {
449     GST_AUDIO_DECODER_ERROR (bdec, 1, LIBRARY, INIT, (NULL),
450         ("error creating Wavpack context"), ret);
451     goto out;
452   }
453 decode_error:
454   {
455     const gchar *reason = "unknown";
456
457     if (dec->context) {
458 #ifdef WAVPACK_OLD_API
459       reason = dec->context->error_message;
460 #else
461       reason = WavpackGetErrorMessage (dec->context);
462 #endif
463     } else {
464       reason = "couldn't create decoder context";
465     }
466     GST_AUDIO_DECODER_ERROR (bdec, 1, STREAM, DECODE, (NULL),
467         ("decoding error: %s", reason), ret);
468     g_free (dec_data);
469     if (outbuf)
470       gst_buffer_unref (outbuf);
471     if (ret == GST_FLOW_OK)
472       gst_audio_decoder_finish_frame (bdec, NULL, 1);
473     return ret;
474   }
475 }
476
477 gboolean
478 gst_wavpack_dec_plugin_init (GstPlugin * plugin)
479 {
480   if (!gst_element_register (plugin, "wavpackdec",
481           GST_RANK_PRIMARY, GST_TYPE_WAVPACK_DEC))
482     return FALSE;
483   GST_DEBUG_CATEGORY_INIT (gst_wavpack_dec_debug, "wavpack_dec", 0,
484       "Wavpack decoder");
485   return TRUE;
486 }