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