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