ext: Update for GstAudioEncoder API changes
[platform/upstream/gstreamer.git] / ext / flac / gstflacdec.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) <2006,2011> Tim-Philipp Müller <tim centricular net>
4  * Copyright (C) <2006> Jan Schmidt <thaytan at mad scientist com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:element-flacdec
24  * @see_also: #GstFlacEnc
25  *
26  * flacdec decodes FLAC streams.
27  * <ulink url="http://flac.sourceforge.net/">FLAC</ulink>
28  * is a Free Lossless Audio Codec.
29  *
30  * <refsect2>
31  * <title>Example launch line</title>
32  * |[
33  * gst-launch-0.11 filesrc location=media/small/dark.441-16-s.flac ! flacparse ! flacdec ! audioconvert ! audioresample ! autoaudiosink
34  * ]|
35  * |[
36  * gst-launch-0.11 souphttpsrc location=http://gstreamer.freedesktop.org/media/small/dark.441-16-s.flac ! flacparse ! flacdec ! audioconvert ! audioresample ! queue min-threshold-buffers=10 ! autoaudiosink
37  * ]|
38  * </refsect2>
39  */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include <string.h>
46
47 #include "gstflacdec.h"
48 #include <gst/gst-i18n-plugin.h>
49 #include <gst/tag/tag.h>
50
51 /* Taken from http://flac.sourceforge.net/format.html#frame_header */
52 static const GstAudioChannelPosition channel_positions[8][8] = {
53   {GST_AUDIO_CHANNEL_POSITION_MONO},
54   {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
55       GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
56         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
57         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
58       GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
59         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
60         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
61         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
62       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
63         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
64         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
65         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
66         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
67       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
68         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
69         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
70         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
71         GST_AUDIO_CHANNEL_POSITION_LFE1,
72         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
73       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
74   /* FIXME: 7/8 channel layouts are not defined in the FLAC specs */
75   {
76         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
77         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
78         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
79         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
80         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
81         GST_AUDIO_CHANNEL_POSITION_LFE1,
82       GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
83         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
84         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
85         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
86         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
87         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
88         GST_AUDIO_CHANNEL_POSITION_LFE1,
89         GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
90       GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
91 };
92
93 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
94 #define GST_CAT_DEFAULT flacdec_debug
95
96 static FLAC__StreamDecoderReadStatus
97 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
98     FLAC__byte buffer[], size_t * bytes, void *client_data);
99 static FLAC__StreamDecoderWriteStatus
100 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
101     const FLAC__Frame * frame,
102     const FLAC__int32 * const buffer[], void *client_data);
103 static void gst_flac_dec_metadata_cb (const FLAC__StreamDecoder *
104     decoder, const FLAC__StreamMetadata * metadata, void *client_data);
105 static void gst_flac_dec_error_cb (const FLAC__StreamDecoder *
106     decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
107
108 static void gst_flac_dec_flush (GstAudioDecoder * audio_dec, gboolean hard);
109 static gboolean gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps);
110 static gboolean gst_flac_dec_start (GstAudioDecoder * dec);
111 static gboolean gst_flac_dec_stop (GstAudioDecoder * dec);
112 static GstFlowReturn gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec,
113     GstBuffer * buf);
114
115 G_DEFINE_TYPE (GstFlacDec, gst_flac_dec, GST_TYPE_AUDIO_DECODER);
116
117 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
118 #define FORMATS "{ S8LE, S16LE, S32LE } "
119 #else
120 #define FORMATS "{ S8BE, S16BE, S32BE } "
121 #endif
122
123 #define GST_FLAC_DEC_SRC_CAPS                             \
124     "audio/x-raw, "                                       \
125     "format = (string) " FORMATS ", "                     \
126     "layout = (string) interleaved, "                     \
127     "rate = (int) [ 1, 655350 ], "                        \
128     "channels = (int) [ 1, 8 ]"
129
130 #define GST_FLAC_DEC_SINK_CAPS                            \
131     "audio/x-flac, "                                      \
132     "framed = (boolean) true, "                           \
133     "rate = (int) [ 1, 655350 ], "                        \
134     "channels = (int) [ 1, 8 ]"
135
136 static GstStaticPadTemplate flac_dec_src_factory =
137 GST_STATIC_PAD_TEMPLATE ("src",
138     GST_PAD_SRC,
139     GST_PAD_ALWAYS,
140     GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
141 static GstStaticPadTemplate flac_dec_sink_factory =
142 GST_STATIC_PAD_TEMPLATE ("sink",
143     GST_PAD_SINK,
144     GST_PAD_ALWAYS,
145     GST_STATIC_CAPS (GST_FLAC_DEC_SINK_CAPS));
146
147 static void
148 gst_flac_dec_class_init (GstFlacDecClass * klass)
149 {
150   GstAudioDecoderClass *audiodecoder_class;
151   GstElementClass *gstelement_class;
152
153   audiodecoder_class = (GstAudioDecoderClass *) klass;
154   gstelement_class = (GstElementClass *) klass;
155
156   GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
157
158   audiodecoder_class->stop = GST_DEBUG_FUNCPTR (gst_flac_dec_stop);
159   audiodecoder_class->start = GST_DEBUG_FUNCPTR (gst_flac_dec_start);
160   audiodecoder_class->flush = GST_DEBUG_FUNCPTR (gst_flac_dec_flush);
161   audiodecoder_class->set_format = GST_DEBUG_FUNCPTR (gst_flac_dec_set_format);
162   audiodecoder_class->handle_frame =
163       GST_DEBUG_FUNCPTR (gst_flac_dec_handle_frame);
164
165   gst_element_class_add_pad_template (gstelement_class,
166       gst_static_pad_template_get (&flac_dec_src_factory));
167   gst_element_class_add_pad_template (gstelement_class,
168       gst_static_pad_template_get (&flac_dec_sink_factory));
169
170   gst_element_class_set_details_simple (gstelement_class, "FLAC audio decoder",
171       "Codec/Decoder/Audio", "Decodes FLAC lossless audio streams",
172       "Tim-Philipp Müller <tim@centricular.net>, "
173       "Wim Taymans <wim.taymans@gmail.com>");
174 }
175
176 static void
177 gst_flac_dec_init (GstFlacDec * flacdec)
178 {
179   /* nothing to do here */
180 }
181
182 static gboolean
183 gst_flac_dec_start (GstAudioDecoder * audio_dec)
184 {
185   FLAC__StreamDecoderInitStatus s;
186   GstFlacDec *dec;
187
188   dec = GST_FLAC_DEC (audio_dec);
189
190   dec->adapter = gst_adapter_new ();
191
192   dec->decoder = FLAC__stream_decoder_new ();
193
194   gst_audio_info_init (&dec->info);
195   dec->depth = 0;
196
197   /* no point calculating MD5 since it's never checked here */
198   FLAC__stream_decoder_set_md5_checking (dec->decoder, false);
199
200   GST_DEBUG_OBJECT (dec, "initializing decoder");
201   s = FLAC__stream_decoder_init_stream (dec->decoder,
202       gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
203       gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
204       gst_flac_dec_error_cb, dec);
205
206   if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
207     GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
208     return FALSE;
209   }
210
211   dec->got_headers = FALSE;
212
213   return TRUE;
214 }
215
216 static gboolean
217 gst_flac_dec_stop (GstAudioDecoder * dec)
218 {
219   GstFlacDec *flacdec = GST_FLAC_DEC (dec);
220
221   if (flacdec->decoder) {
222     FLAC__stream_decoder_delete (flacdec->decoder);
223     flacdec->decoder = NULL;
224   }
225
226   if (flacdec->adapter) {
227     gst_adapter_clear (flacdec->adapter);
228     g_object_unref (flacdec->adapter);
229     flacdec->adapter = NULL;
230   }
231
232   return TRUE;
233 }
234
235 static gboolean
236 gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
237 {
238   const GValue *headers;
239   GstFlacDec *flacdec;
240   GstStructure *s;
241   guint i, num;
242
243   flacdec = GST_FLAC_DEC (dec);
244
245   GST_LOG_OBJECT (dec, "sink caps: %" GST_PTR_FORMAT, caps);
246
247   s = gst_caps_get_structure (caps, 0);
248   headers = gst_structure_get_value (s, "streamheader");
249   if (headers == NULL || !GST_VALUE_HOLDS_ARRAY (headers)) {
250     GST_WARNING_OBJECT (dec, "no 'streamheader' field in input caps, try "
251         "adding a flacparse element upstream");
252     return FALSE;
253   }
254
255   if (gst_adapter_available (flacdec->adapter) > 0) {
256     GST_WARNING_OBJECT (dec, "unexpected data left in adapter");
257     gst_adapter_clear (flacdec->adapter);
258   }
259
260   num = gst_value_array_get_size (headers);
261   for (i = 0; i < num; ++i) {
262     const GValue *header_val;
263     GstBuffer *header_buf;
264
265     header_val = gst_value_array_get_value (headers, i);
266     if (header_val == NULL || !GST_VALUE_HOLDS_BUFFER (header_val))
267       return FALSE;
268
269     header_buf = g_value_dup_boxed (header_val);
270     GST_INFO_OBJECT (dec, "pushing header buffer of %" G_GSIZE_FORMAT " bytes "
271         "into adapter", gst_buffer_get_size (header_buf));
272     gst_adapter_push (flacdec->adapter, header_buf);
273   }
274
275   GST_DEBUG_OBJECT (dec, "Processing headers and metadata");
276   if (!FLAC__stream_decoder_process_until_end_of_metadata (flacdec->decoder)) {
277     GST_WARNING_OBJECT (dec, "process_until_end_of_metadata failed");
278   }
279   GST_INFO_OBJECT (dec, "headers and metadata are now processed");
280   return TRUE;
281 }
282
283 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
284 static const guint8 crc8_table[256] = {
285   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
286   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
287   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
288   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
289   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
290   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
291   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
292   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
293   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
294   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
295   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
296   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
297   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
298   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
299   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
300   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
301   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
302   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
303   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
304   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
305   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
306   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
307   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
308   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
309   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
310   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
311   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
312   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
313   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
314   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
315   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
316   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
317 };
318
319 static guint8
320 gst_flac_calculate_crc8 (guint8 * data, guint length)
321 {
322   guint8 crc = 0;
323
324   while (length--) {
325     crc = crc8_table[crc ^ *data];
326     ++data;
327   }
328
329   return crc;
330 }
331
332 /* FIXME: for our purposes it's probably enough to just check for the sync
333  * marker - we just want to know if it's a header frame or not */
334 static gboolean
335 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
336     gint64 * last_sample_num)
337 {
338   guint headerlen;
339   guint sr_from_end = 0;        /* can be 0, 8 or 16 */
340   guint bs_from_end = 0;        /* can be 0, 8 or 16 */
341   guint32 val = 0;
342   guint8 bs, sr, ca, ss, pb;
343
344   if (size < 10)
345     return FALSE;
346
347   /* sync */
348   if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8)
349     return FALSE;
350   if (data[1] & 1) {
351     GST_WARNING_OBJECT (flacdec, "Variable block size FLAC unsupported");
352     return FALSE;
353   }
354
355   bs = (data[2] & 0xF0) >> 4;   /* blocksize marker   */
356   sr = (data[2] & 0x0F);        /* samplerate marker  */
357   ca = (data[3] & 0xF0) >> 4;   /* channel assignment */
358   ss = (data[3] & 0x0F) >> 1;   /* sample size marker */
359   pb = (data[3] & 0x01);        /* padding bit        */
360
361   GST_LOG_OBJECT (flacdec,
362       "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
363
364   if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
365     return FALSE;
366   }
367
368   /* read block size from end of header? */
369   if (bs == 6)
370     bs_from_end = 8;
371   else if (bs == 7)
372     bs_from_end = 16;
373
374   /* read sample rate from end of header? */
375   if (sr == 0x0C)
376     sr_from_end = 8;
377   else if (sr == 0x0D || sr == 0x0E)
378     sr_from_end = 16;
379
380   /* FIXME: This is can be 36 bit if variable block size is used,
381    * fortunately not encoder supports this yet and we check for that
382    * above.
383    */
384   val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
385
386   if (val == (guint32) - 1 || val == (guint32) - 2) {
387     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
388     return FALSE;
389   }
390
391   headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
392       (bs_from_end / 8) + (sr_from_end / 8);
393
394   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
395     GST_LOG_OBJECT (flacdec, "invalid checksum");
396     return FALSE;
397   }
398
399   if (flacdec->min_blocksize == flacdec->max_blocksize) {
400     *last_sample_num = (val + 1) * flacdec->min_blocksize;
401   } else {
402     *last_sample_num = 0;       /* FIXME: + length of last block in samples */
403   }
404
405   /* FIXME: only valid for fixed block size streams */
406   GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
407       *last_sample_num);
408
409   if (flacdec->info.rate > 0 && *last_sample_num != 0) {
410     GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
411         GST_TIME_FORMAT, *last_sample_num,
412         GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->info.rate));
413   }
414
415   return TRUE;
416 }
417
418 static gboolean
419 gst_flac_dec_handle_decoder_error (GstFlacDec * dec, gboolean msg)
420 {
421   gboolean ret;
422
423   dec->error_count++;
424   if (dec->error_count > 10) {
425     if (msg)
426       GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), (NULL));
427     dec->last_flow = GST_FLOW_ERROR;
428     ret = TRUE;
429   } else {
430     GST_DEBUG_OBJECT (dec, "ignoring error for now at count %d",
431         dec->error_count);
432     ret = FALSE;
433   }
434
435   return ret;
436 }
437
438 static void
439 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
440     const FLAC__StreamMetadata * metadata, void *client_data)
441 {
442   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
443
444   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
445
446   switch (metadata->type) {
447     case FLAC__METADATA_TYPE_STREAMINFO:{
448       gint64 samples;
449       guint depth, width;
450
451       samples = metadata->data.stream_info.total_samples;
452
453       flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
454       flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
455       flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
456
457       if (depth < 9)
458         width = 8;
459       else if (depth < 17)
460         width = 16;
461       else
462         width = 32;
463
464       gst_audio_info_set_format (&flacdec->info,
465           gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, width, width),
466           metadata->data.stream_info.sample_rate,
467           metadata->data.stream_info.channels, NULL);
468
469       memcpy (flacdec->info.position,
470           channel_positions[flacdec->info.channels - 1],
471           sizeof (GstAudioChannelPosition) * flacdec->info.channels);
472       gst_audio_channel_positions_to_valid_order (flacdec->info.position,
473           flacdec->info.channels);
474       /* Note: we create the inverse reordering map here */
475       gst_audio_get_channel_reorder_map (flacdec->info.channels,
476           flacdec->info.position, channel_positions[flacdec->info.channels - 1],
477           flacdec->channel_reorder_map);
478
479       GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
480           flacdec->min_blocksize, flacdec->max_blocksize);
481       GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
482           flacdec->info.rate, flacdec->info.channels);
483       GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
484           flacdec->info.finfo->width);
485
486       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
487       break;
488     }
489     default:
490       break;
491   }
492 }
493
494 static void
495 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
496     FLAC__StreamDecoderErrorStatus status, void *client_data)
497 {
498   const gchar *error;
499   GstFlacDec *dec;
500
501   dec = GST_FLAC_DEC (client_data);
502
503   switch (status) {
504     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
505       /* Ignore this error and keep processing */
506       return;
507     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
508       error = "bad header";
509       break;
510     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
511       error = "CRC mismatch";
512       break;
513     default:
514       error = "unknown error";
515       break;
516   }
517
518   if (gst_flac_dec_handle_decoder_error (dec, FALSE))
519     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
520 }
521
522 static FLAC__StreamDecoderReadStatus
523 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
524     FLAC__byte buffer[], size_t * bytes, void *client_data)
525 {
526   GstFlacDec *dec = GST_FLAC_DEC (client_data);
527   guint len;
528
529   len = MIN (gst_adapter_available (dec->adapter), *bytes);
530
531   if (len == 0) {
532     GST_LOG_OBJECT (dec, "0 bytes available at the moment");
533     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
534   }
535
536   GST_LOG_OBJECT (dec, "feeding %u bytes to decoder "
537       "(available=%" G_GSIZE_FORMAT ", bytes=%u)",
538       len, gst_adapter_available (dec->adapter), (guint) * bytes);
539   gst_adapter_copy (dec->adapter, buffer, 0, len);
540   *bytes = len;
541
542   gst_adapter_flush (dec->adapter, len);
543
544   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
545 }
546
547 static FLAC__StreamDecoderWriteStatus
548 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
549     const FLAC__int32 * const buffer[])
550 {
551   GstFlowReturn ret = GST_FLOW_OK;
552   GstBuffer *outbuf;
553   guint depth = frame->header.bits_per_sample;
554   guint width;
555   guint sample_rate = frame->header.sample_rate;
556   guint channels = frame->header.channels;
557   guint samples = frame->header.blocksize;
558   guint j, i;
559   GstMapInfo map;
560   gboolean caps_changed;
561
562   GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
563
564   if (depth == 0) {
565     if (flacdec->depth < 4 || flacdec->depth > 32) {
566       GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
567           flacdec->depth);
568       ret = GST_FLOW_ERROR;
569       goto done;
570     }
571
572     depth = flacdec->depth;
573   }
574
575   switch (depth) {
576     case 8:
577       width = 8;
578       break;
579     case 12:
580     case 16:
581       width = 16;
582       break;
583     case 20:
584     case 24:
585     case 32:
586       width = 32;
587       break;
588     default:
589       GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
590       ret = GST_FLOW_ERROR;
591       goto done;
592   }
593
594   if (sample_rate == 0) {
595     if (flacdec->info.rate != 0) {
596       sample_rate = flacdec->info.rate;
597     } else {
598       GST_ERROR_OBJECT (flacdec, "unknown sample rate");
599       ret = GST_FLOW_ERROR;
600       goto done;
601     }
602   }
603
604   caps_changed = (sample_rate != flacdec->info.rate)
605       || (width != flacdec->info.finfo->width)
606       || (channels != flacdec->info.channels);
607
608   if (caps_changed
609       || !gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (flacdec))) {
610     GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels", sample_rate,
611         channels);
612
613     gst_audio_info_set_format (&flacdec->info,
614         gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, width, width),
615         sample_rate, channels, NULL);
616
617     memcpy (flacdec->info.position,
618         channel_positions[flacdec->info.channels - 1],
619         sizeof (GstAudioChannelPosition) * flacdec->info.channels);
620     gst_audio_channel_positions_to_valid_order (flacdec->info.position,
621         flacdec->info.channels);
622     /* Note: we create the inverse reordering map here */
623     gst_audio_get_channel_reorder_map (flacdec->info.channels,
624         flacdec->info.position, channel_positions[flacdec->info.channels - 1],
625         flacdec->channel_reorder_map);
626
627     flacdec->depth = depth;
628
629     gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (flacdec),
630         &flacdec->info);
631   }
632
633   outbuf =
634       gst_buffer_new_allocate (NULL, samples * channels * (width / 8), NULL);
635
636   gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
637   if (width == 8) {
638     gint8 *outbuffer = (gint8 *) map.data;
639     gint *reorder_map = flacdec->channel_reorder_map;
640
641     if (width != depth) {
642       for (i = 0; i < samples; i++) {
643         for (j = 0; j < channels; j++) {
644           *outbuffer++ = (gint8) (buffer[reorder_map[j]][i] << (width - depth));
645         }
646       }
647     } else {
648       for (i = 0; i < samples; i++) {
649         for (j = 0; j < channels; j++) {
650           *outbuffer++ = (gint8) buffer[reorder_map[j]][i];
651         }
652       }
653     }
654   } else if (width == 16) {
655     gint16 *outbuffer = (gint16 *) map.data;
656     gint *reorder_map = flacdec->channel_reorder_map;
657
658     if (width != depth) {
659       for (i = 0; i < samples; i++) {
660         for (j = 0; j < channels; j++) {
661           *outbuffer++ =
662               (gint16) (buffer[reorder_map[j]][i] << (width - depth));
663         }
664       }
665     } else {
666       for (i = 0; i < samples; i++) {
667         for (j = 0; j < channels; j++) {
668           *outbuffer++ = (gint16) buffer[reorder_map[j]][i];
669         }
670       }
671     }
672   } else if (width == 32) {
673     gint32 *outbuffer = (gint32 *) map.data;
674     gint *reorder_map = flacdec->channel_reorder_map;
675
676     if (width != depth) {
677       for (i = 0; i < samples; i++) {
678         for (j = 0; j < channels; j++) {
679           *outbuffer++ =
680               (gint32) (buffer[reorder_map[j]][i] << (width - depth));
681         }
682       }
683     } else {
684       for (i = 0; i < samples; i++) {
685         for (j = 0; j < channels; j++) {
686           *outbuffer++ = (gint32) buffer[reorder_map[j]][i];
687         }
688       }
689     }
690   } else {
691     g_assert_not_reached ();
692   }
693   gst_buffer_unmap (outbuf, &map);
694
695   GST_DEBUG_OBJECT (flacdec, "pushing %d samples", samples);
696   if (flacdec->error_count)
697     flacdec->error_count--;
698
699   ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (flacdec), outbuf, 1);
700
701   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
702     GST_DEBUG_OBJECT (flacdec, "finish_frame flow %s", gst_flow_get_name (ret));
703   }
704
705 done:
706
707   /* we act on the flow return value later in the handle_frame function, as we
708    * don't want to mess up the internal decoder state by returning ABORT when
709    * the error is in fact non-fatal (like a pad in flushing mode) and we want
710    * to continue later. So just pretend everything's dandy and act later. */
711   flacdec->last_flow = ret;
712
713   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
714 }
715
716 static FLAC__StreamDecoderWriteStatus
717 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
718     const FLAC__Frame * frame,
719     const FLAC__int32 * const buffer[], void *client_data)
720 {
721   return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
722 }
723
724 static void
725 gst_flac_dec_flush (GstAudioDecoder * audio_dec, gboolean hard)
726 {
727   GstFlacDec *dec = GST_FLAC_DEC (audio_dec);
728
729   if (!hard) {
730     guint available = gst_adapter_available (dec->adapter);
731
732     if (available > 0) {
733       GST_INFO_OBJECT (dec, "draining, %u bytes left in adapter", available);
734       FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
735     }
736   }
737
738   FLAC__stream_decoder_flush (dec->decoder);
739   gst_adapter_clear (dec->adapter);
740 }
741
742 static GstFlowReturn
743 gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
744 {
745   GstFlacDec *dec;
746
747   dec = GST_FLAC_DEC (audio_dec);
748
749   /* drain remaining data? */
750   if (G_UNLIKELY (buf == NULL)) {
751     gst_flac_dec_flush (audio_dec, FALSE);
752     return GST_FLOW_OK;
753   }
754
755   GST_LOG_OBJECT (dec, "frame: ts %" GST_TIME_FORMAT ", flags 0x%04x, "
756       "%" G_GSIZE_FORMAT " bytes", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
757       GST_BUFFER_FLAGS (buf), gst_buffer_get_size (buf));
758
759   /* drop any in-stream headers, we've processed those in set_format already */
760   if (G_UNLIKELY (!dec->got_headers)) {
761     gboolean got_audio_frame;
762     gint64 unused;
763     GstMapInfo map;
764
765     /* check if this is a flac audio frame (rather than a header or junk) */
766     gst_buffer_map (buf, &map, GST_MAP_READ);
767     got_audio_frame =
768         gst_flac_dec_scan_got_frame (dec, map.data, map.size, &unused);
769     gst_buffer_unmap (buf, &map);
770
771     if (!got_audio_frame) {
772       GST_INFO_OBJECT (dec, "dropping in-stream header, %" G_GSIZE_FORMAT " "
773           "bytes", map.size);
774       gst_audio_decoder_finish_frame (audio_dec, NULL, 1);
775       return GST_FLOW_OK;
776     }
777
778     GST_INFO_OBJECT (dec, "first audio frame, got all in-stream headers now");
779     dec->got_headers = TRUE;
780   }
781
782   gst_adapter_push (dec->adapter, gst_buffer_ref (buf));
783   buf = NULL;
784
785   dec->last_flow = GST_FLOW_OK;
786
787   /* framed - there should always be enough data to decode something */
788   GST_LOG_OBJECT (dec, "%" G_GSIZE_FORMAT " bytes available",
789       gst_adapter_available (dec->adapter));
790
791   if (!FLAC__stream_decoder_process_single (dec->decoder)) {
792     GST_INFO_OBJECT (dec, "process_single failed");
793   }
794
795   return dec->last_flow;
796 }