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