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