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
gst_flac_dec_class_init(GstFlacDecClass * klass)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
gst_flac_dec_init(GstFlacDec * flacdec)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
gst_flac_dec_start(GstAudioDecoder * audio_dec)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
gst_flac_dec_stop(GstAudioDecoder * dec)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 gint64
gst_flac_dec_get_latency(GstFlacDec * flacdec)242 gst_flac_dec_get_latency (GstFlacDec * flacdec)
243 {
244   /* The FLAC specification states that the data is processed in blocks,
245    * regardless of the number of channels. Thus, The latency can be calculated
246    * using the blocksize and rate. For example a 1 second block sampled at
247    * 44.1KHz has a blocksize of 44100 */
248 
249   /* Make sure the rate is valid */
250   if (!flacdec->info.rate)
251     return 0;
252 
253   /* Calculate the latecy */
254   return (flacdec->max_blocksize * GST_SECOND) / flacdec->info.rate;
255 }
256 
257 static gboolean
gst_flac_dec_set_format(GstAudioDecoder * dec,GstCaps * caps)258 gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
259 {
260   const GValue *headers;
261   GstFlacDec *flacdec;
262   GstStructure *s;
263   guint i, num;
264 
265   flacdec = GST_FLAC_DEC (dec);
266 
267   GST_LOG_OBJECT (dec, "sink caps: %" GST_PTR_FORMAT, caps);
268 
269   s = gst_caps_get_structure (caps, 0);
270   headers = gst_structure_get_value (s, "streamheader");
271   if (headers == NULL || !GST_VALUE_HOLDS_ARRAY (headers)) {
272     GST_WARNING_OBJECT (dec, "no 'streamheader' field in input caps, try "
273         "adding a flacparse element upstream");
274     return FALSE;
275   }
276 
277   if (gst_adapter_available (flacdec->adapter) > 0) {
278     GST_WARNING_OBJECT (dec, "unexpected data left in adapter");
279     gst_adapter_clear (flacdec->adapter);
280   }
281 
282   FLAC__stream_decoder_reset (flacdec->decoder);
283   flacdec->got_headers = FALSE;
284 
285   num = gst_value_array_get_size (headers);
286   for (i = 0; i < num; ++i) {
287     const GValue *header_val;
288     GstBuffer *header_buf;
289 
290     header_val = gst_value_array_get_value (headers, i);
291     if (header_val == NULL || !GST_VALUE_HOLDS_BUFFER (header_val))
292       return FALSE;
293 
294     header_buf = g_value_dup_boxed (header_val);
295     GST_INFO_OBJECT (dec, "pushing header buffer of %" G_GSIZE_FORMAT " bytes "
296         "into adapter", gst_buffer_get_size (header_buf));
297     gst_adapter_push (flacdec->adapter, header_buf);
298   }
299 
300   GST_DEBUG_OBJECT (dec, "Processing headers and metadata");
301   if (!FLAC__stream_decoder_process_until_end_of_metadata (flacdec->decoder)) {
302     GST_WARNING_OBJECT (dec, "process_until_end_of_metadata failed");
303     if (FLAC__stream_decoder_get_state (flacdec->decoder) ==
304         FLAC__STREAM_DECODER_ABORTED) {
305       GST_WARNING_OBJECT (flacdec, "Read callback caused internal abort");
306       /* allow recovery */
307       gst_adapter_clear (flacdec->adapter);
308       FLAC__stream_decoder_flush (flacdec->decoder);
309       gst_flac_dec_handle_decoder_error (flacdec, TRUE);
310     }
311   }
312   GST_INFO_OBJECT (dec, "headers and metadata are now processed");
313 
314   return TRUE;
315 }
316 
317 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
318 static const guint8 crc8_table[256] = {
319   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
320   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
321   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
322   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
323   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
324   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
325   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
326   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
327   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
328   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
329   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
330   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
331   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
332   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
333   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
334   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
335   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
336   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
337   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
338   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
339   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
340   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
341   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
342   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
343   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
344   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
345   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
346   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
347   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
348   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
349   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
350   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
351 };
352 
353 static guint8
gst_flac_calculate_crc8(const guint8 * data,guint length)354 gst_flac_calculate_crc8 (const guint8 * data, guint length)
355 {
356   guint8 crc = 0;
357 
358   while (length--) {
359     crc = crc8_table[crc ^ *data];
360     ++data;
361   }
362 
363   return crc;
364 }
365 
366 /* FIXME: for our purposes it's probably enough to just check for the sync
367  * marker - we just want to know if it's a header frame or not */
368 static gboolean
gst_flac_dec_scan_got_frame(GstFlacDec * flacdec,const guint8 * data,guint size)369 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, const guint8 * data,
370     guint size)
371 {
372   guint headerlen;
373   guint sr_from_end = 0;        /* can be 0, 8 or 16 */
374   guint bs_from_end = 0;        /* can be 0, 8 or 16 */
375   guint32 val = 0;
376   guint8 bs, sr, ca, ss, pb;
377   gboolean vbs;
378 
379   if (size < 10)
380     return FALSE;
381 
382   /* sync */
383   if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8)
384     return FALSE;
385 
386   vbs = ! !(data[1] & 1);       /* variable blocksize */
387   bs = (data[2] & 0xF0) >> 4;   /* blocksize marker   */
388   sr = (data[2] & 0x0F);        /* samplerate marker  */
389   ca = (data[3] & 0xF0) >> 4;   /* channel assignment */
390   ss = (data[3] & 0x0F) >> 1;   /* sample size marker */
391   pb = (data[3] & 0x01);        /* padding bit        */
392 
393   GST_LOG_OBJECT (flacdec,
394       "got sync, vbs=%d,bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", vbs, bs, sr, ca, ss,
395       pb);
396 
397   if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
398     return FALSE;
399   }
400 
401   /* read block size from end of header? */
402   if (bs == 6)
403     bs_from_end = 8;
404   else if (bs == 7)
405     bs_from_end = 16;
406 
407   /* read sample rate from end of header? */
408   if (sr == 0x0C)
409     sr_from_end = 8;
410   else if (sr == 0x0D || sr == 0x0E)
411     sr_from_end = 16;
412 
413   val = data[4];
414   /* This is slightly faster than a loop */
415   if (!(val & 0x80)) {
416     val = 0;
417   } else if ((val & 0xc0) && !(val & 0x20)) {
418     val = 1;
419   } else if ((val & 0xe0) && !(val & 0x10)) {
420     val = 2;
421   } else if ((val & 0xf0) && !(val & 0x08)) {
422     val = 3;
423   } else if ((val & 0xf8) && !(val & 0x04)) {
424     val = 4;
425   } else if ((val & 0xfc) && !(val & 0x02)) {
426     val = 5;
427   } else if ((val & 0xfe) && !(val & 0x01)) {
428     val = 6;
429   } else {
430     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
431     return FALSE;
432   }
433 
434   val++;
435   headerlen = 4 + val + (bs_from_end / 8) + (sr_from_end / 8);
436 
437   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
438     GST_LOG_OBJECT (flacdec, "invalid checksum");
439     return FALSE;
440   }
441 
442   return TRUE;
443 }
444 
445 static gboolean
gst_flac_dec_handle_decoder_error(GstFlacDec * dec,gboolean msg)446 gst_flac_dec_handle_decoder_error (GstFlacDec * dec, gboolean msg)
447 {
448   gboolean ret;
449 
450   dec->error_count++;
451   if (dec->error_count > 10) {
452     if (msg)
453       GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), (NULL));
454     dec->last_flow = GST_FLOW_ERROR;
455     ret = TRUE;
456   } else {
457     GST_DEBUG_OBJECT (dec, "ignoring error for now at count %d",
458         dec->error_count);
459     ret = FALSE;
460   }
461 
462   return ret;
463 }
464 
465 static void
gst_flac_dec_metadata_cb(const FLAC__StreamDecoder * decoder,const FLAC__StreamMetadata * metadata,void * client_data)466 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
467     const FLAC__StreamMetadata * metadata, void *client_data)
468 {
469   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
470   GstAudioDecoder *dec = GST_AUDIO_DECODER (client_data);
471   GstAudioChannelPosition position[8];
472   guint64 curr_latency = 0, old_latency = gst_flac_dec_get_latency (flacdec);
473 
474   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
475 
476   switch (metadata->type) {
477     case FLAC__METADATA_TYPE_STREAMINFO:{
478       gint64 samples;
479       guint depth, width, gdepth, channels;
480 
481       samples = metadata->data.stream_info.total_samples;
482 
483       flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
484       flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
485       flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
486 
487       if (depth < 9) {
488         gdepth = width = 8;
489       } else if (depth < 17) {
490         gdepth = width = 16;
491       } else if (depth < 25) {
492         gdepth = 24;
493         width = 32;
494       } else {
495         gdepth = width = 32;
496       }
497 
498       channels = metadata->data.stream_info.channels;
499       memcpy (position, channel_positions[channels - 1], sizeof (position));
500       gst_audio_channel_positions_to_valid_order (position, channels);
501       /* Note: we create the inverse reordering map here */
502       gst_audio_get_channel_reorder_map (channels,
503           position, channel_positions[channels - 1],
504           flacdec->channel_reorder_map);
505 
506       gst_audio_info_set_format (&flacdec->info,
507           gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, width, gdepth),
508           metadata->data.stream_info.sample_rate,
509           metadata->data.stream_info.channels, position);
510 
511       gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (flacdec),
512           &flacdec->info);
513 
514       gst_audio_decoder_negotiate (GST_AUDIO_DECODER (flacdec));
515 
516       GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
517           flacdec->min_blocksize, flacdec->max_blocksize);
518       GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
519           flacdec->info.rate, flacdec->info.channels);
520       GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
521           flacdec->info.finfo->width);
522 
523       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
524       break;
525     }
526     default:
527       break;
528   }
529 
530   /* Update the latency if it has changed */
531   curr_latency = gst_flac_dec_get_latency (flacdec);
532   if (old_latency != curr_latency)
533     gst_audio_decoder_set_latency (dec, curr_latency, curr_latency);
534 }
535 
536 static void
gst_flac_dec_error_cb(const FLAC__StreamDecoder * d,FLAC__StreamDecoderErrorStatus status,void * client_data)537 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
538     FLAC__StreamDecoderErrorStatus status, void *client_data)
539 {
540   const gchar *error;
541   GstFlacDec *dec;
542 
543   dec = GST_FLAC_DEC (client_data);
544 
545   switch (status) {
546     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
547       dec->do_resync = TRUE;
548       return;
549     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
550       error = "bad header";
551       break;
552     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
553       error = "CRC mismatch";
554       break;
555     default:
556       error = "unknown error";
557       break;
558   }
559 
560   if (gst_flac_dec_handle_decoder_error (dec, FALSE))
561     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
562 }
563 
564 static FLAC__StreamDecoderReadStatus
gst_flac_dec_read_stream(const FLAC__StreamDecoder * decoder,FLAC__byte buffer[],size_t * bytes,void * client_data)565 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
566     FLAC__byte buffer[], size_t * bytes, void *client_data)
567 {
568   GstFlacDec *dec = GST_FLAC_DEC (client_data);
569   guint len;
570 
571   len = MIN (gst_adapter_available (dec->adapter), *bytes);
572 
573   if (len == 0) {
574     GST_LOG_OBJECT (dec, "0 bytes available at the moment");
575     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
576   }
577 
578   GST_LOG_OBJECT (dec, "feeding %u bytes to decoder "
579       "(available=%" G_GSIZE_FORMAT ", bytes=%u)",
580       len, gst_adapter_available (dec->adapter), (guint) * bytes);
581   gst_adapter_copy (dec->adapter, buffer, 0, len);
582   *bytes = len;
583 
584   gst_adapter_flush (dec->adapter, len);
585 
586   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
587 }
588 
589 static FLAC__StreamDecoderWriteStatus
gst_flac_dec_write(GstFlacDec * flacdec,const FLAC__Frame * frame,const FLAC__int32 * const buffer[])590 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
591     const FLAC__int32 * const buffer[])
592 {
593   GstFlowReturn ret = GST_FLOW_OK;
594   GstBuffer *outbuf;
595   guint depth = frame->header.bits_per_sample;
596   guint width, gdepth;
597   guint sample_rate = frame->header.sample_rate;
598   guint channels = frame->header.channels;
599   guint samples = frame->header.blocksize;
600   guint j, i;
601   GstMapInfo map;
602   gboolean caps_changed;
603   GstAudioChannelPosition chanpos[8];
604 
605   GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
606 
607   if (depth == 0) {
608     if (flacdec->depth < 4 || flacdec->depth > 32) {
609       GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
610           flacdec->depth);
611       ret = GST_FLOW_ERROR;
612       goto done;
613     }
614 
615     depth = flacdec->depth;
616   }
617 
618   switch (depth) {
619     case 8:
620       gdepth = width = 8;
621       break;
622     case 12:
623     case 16:
624       gdepth = width = 16;
625       break;
626     case 20:
627     case 24:
628       gdepth = 24;
629       width = 32;
630       break;
631     case 32:
632       gdepth = width = 32;
633       break;
634     default:
635       GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
636       ret = GST_FLOW_ERROR;
637       goto done;
638   }
639 
640   if (sample_rate == 0) {
641     if (flacdec->info.rate != 0) {
642       sample_rate = flacdec->info.rate;
643     } else {
644       GST_ERROR_OBJECT (flacdec, "unknown sample rate");
645       ret = GST_FLOW_ERROR;
646       goto done;
647     }
648   }
649 
650   caps_changed = (sample_rate != GST_AUDIO_INFO_RATE (&flacdec->info))
651       || (width != GST_AUDIO_INFO_WIDTH (&flacdec->info))
652       || (gdepth != GST_AUDIO_INFO_DEPTH (&flacdec->info))
653       || (channels != GST_AUDIO_INFO_CHANNELS (&flacdec->info));
654 
655   if (caps_changed
656       || !gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (flacdec))) {
657     GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels", sample_rate,
658         channels);
659 
660     memcpy (chanpos, channel_positions[channels - 1], sizeof (chanpos));
661     gst_audio_channel_positions_to_valid_order (chanpos, channels);
662     gst_audio_info_set_format (&flacdec->info,
663         gst_audio_format_build_integer (TRUE, G_BYTE_ORDER, width, gdepth),
664         sample_rate, channels, chanpos);
665 
666     /* Note: we create the inverse reordering map here */
667     gst_audio_get_channel_reorder_map (flacdec->info.channels,
668         flacdec->info.position, channel_positions[flacdec->info.channels - 1],
669         flacdec->channel_reorder_map);
670 
671     flacdec->depth = depth;
672 
673     gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (flacdec),
674         &flacdec->info);
675   }
676 
677   outbuf =
678       gst_buffer_new_allocate (NULL, samples * channels * (width / 8), NULL);
679 
680   gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
681   if (width == 8) {
682     gint8 *outbuffer = (gint8 *) map.data;
683     gint *reorder_map = flacdec->channel_reorder_map;
684 
685     g_assert (gdepth == 8 && depth == 8);
686     for (i = 0; i < samples; i++) {
687       for (j = 0; j < channels; j++) {
688         *outbuffer++ = (gint8) buffer[reorder_map[j]][i];
689       }
690     }
691   } else if (width == 16) {
692     gint16 *outbuffer = (gint16 *) map.data;
693     gint *reorder_map = flacdec->channel_reorder_map;
694 
695     if (gdepth != depth) {
696       for (i = 0; i < samples; i++) {
697         for (j = 0; j < channels; j++) {
698           *outbuffer++ =
699               (gint16) (buffer[reorder_map[j]][i] << (gdepth - depth));
700         }
701       }
702     } else {
703       for (i = 0; i < samples; i++) {
704         for (j = 0; j < channels; j++) {
705           *outbuffer++ = (gint16) buffer[reorder_map[j]][i];
706         }
707       }
708     }
709   } else if (width == 32) {
710     gint32 *outbuffer = (gint32 *) map.data;
711     gint *reorder_map = flacdec->channel_reorder_map;
712 
713     if (gdepth != depth) {
714       for (i = 0; i < samples; i++) {
715         for (j = 0; j < channels; j++) {
716           *outbuffer++ =
717               (gint32) (buffer[reorder_map[j]][i] << (gdepth - depth));
718         }
719       }
720     } else {
721       for (i = 0; i < samples; i++) {
722         for (j = 0; j < channels; j++) {
723           *outbuffer++ = (gint32) buffer[reorder_map[j]][i];
724         }
725       }
726     }
727   } else {
728     g_assert_not_reached ();
729   }
730   gst_buffer_unmap (outbuf, &map);
731 
732   GST_DEBUG_OBJECT (flacdec, "pushing %d samples", samples);
733   if (flacdec->error_count)
734     flacdec->error_count--;
735 
736   ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (flacdec), outbuf, 1);
737 
738   if (G_UNLIKELY (ret != GST_FLOW_OK)) {
739     GST_DEBUG_OBJECT (flacdec, "finish_frame flow %s", gst_flow_get_name (ret));
740   }
741 
742 done:
743 
744   /* we act on the flow return value later in the handle_frame function, as we
745    * don't want to mess up the internal decoder state by returning ABORT when
746    * the error is in fact non-fatal (like a pad in flushing mode) and we want
747    * to continue later. So just pretend everything's dandy and act later. */
748   flacdec->last_flow = ret;
749 
750   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
751 }
752 
753 static FLAC__StreamDecoderWriteStatus
gst_flac_dec_write_stream(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)754 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
755     const FLAC__Frame * frame,
756     const FLAC__int32 * const buffer[], void *client_data)
757 {
758   return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
759 }
760 
761 static void
gst_flac_dec_flush(GstAudioDecoder * audio_dec,gboolean hard)762 gst_flac_dec_flush (GstAudioDecoder * audio_dec, gboolean hard)
763 {
764   GstFlacDec *dec = GST_FLAC_DEC (audio_dec);
765 
766   if (!hard) {
767     guint available = gst_adapter_available (dec->adapter);
768 
769     if (available > 0) {
770       GST_INFO_OBJECT (dec, "draining, %u bytes left in adapter", available);
771       FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
772     }
773   }
774 
775   dec->do_resync = FALSE;
776   FLAC__stream_decoder_flush (dec->decoder);
777   gst_adapter_clear (dec->adapter);
778 }
779 
780 static GstFlowReturn
gst_flac_dec_handle_frame(GstAudioDecoder * audio_dec,GstBuffer * buf)781 gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
782 {
783   GstFlacDec *dec;
784 
785   dec = GST_FLAC_DEC (audio_dec);
786 
787   /* drain remaining data? */
788   if (G_UNLIKELY (buf == NULL)) {
789     gst_flac_dec_flush (audio_dec, FALSE);
790     return GST_FLOW_OK;
791   }
792 
793   if (dec->do_resync) {
794     GST_WARNING_OBJECT (dec, "Lost sync, flushing decoder");
795     FLAC__stream_decoder_flush (dec->decoder);
796     dec->do_resync = FALSE;
797   }
798 
799   GST_LOG_OBJECT (dec, "frame: ts %" GST_TIME_FORMAT ", flags 0x%04x, "
800       "%" G_GSIZE_FORMAT " bytes", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
801       GST_BUFFER_FLAGS (buf), gst_buffer_get_size (buf));
802 
803   /* drop any in-stream headers, we've processed those in set_format already */
804   if (G_UNLIKELY (!dec->got_headers)) {
805     gboolean got_audio_frame;
806     GstMapInfo map;
807 
808     /* check if this is a flac audio frame (rather than a header or junk) */
809     gst_buffer_map (buf, &map, GST_MAP_READ);
810     got_audio_frame = gst_flac_dec_scan_got_frame (dec, map.data, map.size);
811     gst_buffer_unmap (buf, &map);
812 
813     if (!got_audio_frame) {
814       GST_INFO_OBJECT (dec, "dropping in-stream header, %" G_GSIZE_FORMAT " "
815           "bytes", map.size);
816       gst_audio_decoder_finish_frame (audio_dec, NULL, 1);
817       return GST_FLOW_OK;
818     }
819 
820     GST_INFO_OBJECT (dec, "first audio frame, got all in-stream headers now");
821     dec->got_headers = TRUE;
822   }
823 
824   gst_adapter_push (dec->adapter, gst_buffer_ref (buf));
825   buf = NULL;
826 
827   dec->last_flow = GST_FLOW_OK;
828 
829   /* framed - there should always be enough data to decode something */
830   GST_LOG_OBJECT (dec, "%" G_GSIZE_FORMAT " bytes available",
831       gst_adapter_available (dec->adapter));
832 
833   if (!FLAC__stream_decoder_process_single (dec->decoder)) {
834     GST_INFO_OBJECT (dec, "process_single failed");
835     if (FLAC__stream_decoder_get_state (dec->decoder) ==
836         FLAC__STREAM_DECODER_ABORTED) {
837       GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
838       /* allow recovery */
839       gst_adapter_clear (dec->adapter);
840       FLAC__stream_decoder_flush (dec->decoder);
841       gst_flac_dec_handle_decoder_error (dec, TRUE);
842     }
843   }
844 
845   return dec->last_flow;
846 }
847