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>
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.
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.
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.
23 * SECTION:element-flacdec
24 * @see_also: #GstFlacEnc
26 * flacdec decodes FLAC streams.
27 * <ulink url="http://flac.sourceforge.net/">FLAC</ulink>
28 * is a Free Lossless Audio Codec.
31 * <title>Example launch line</title>
33 * gst-launch-1.0 filesrc location=media/small/dark.441-16-s.flac ! flacparse ! flacdec ! audioconvert ! audioresample ! autoaudiosink
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
47 #include "gstflacdec.h"
48 #include <gst/gst-i18n-plugin.h>
49 #include <gst/tag/tag.h>
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 */
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}
93 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
94 #define GST_CAT_DEFAULT flacdec_debug
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);
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);
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,
117 G_DEFINE_TYPE (GstFlacDec, gst_flac_dec, GST_TYPE_AUDIO_DECODER);
119 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
120 #define FORMATS "{ S8, S16LE, S24_32LE, S32LE } "
122 #define FORMATS "{ S8, S16BE, S24_32BE, S32BE } "
125 #define GST_FLAC_DEC_SRC_CAPS \
127 "format = (string) " FORMATS ", " \
128 "layout = (string) interleaved, " \
129 "rate = (int) [ 1, 655350 ], " \
130 "channels = (int) [ 1, 8 ]"
132 #define GST_FLAC_DEC_SINK_CAPS \
134 "framed = (boolean) true, " \
135 "rate = (int) [ 1, 655350 ], " \
136 "channels = (int) [ 1, 8 ]"
138 static GstStaticPadTemplate flac_dec_src_factory =
139 GST_STATIC_PAD_TEMPLATE ("src",
142 GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
143 static GstStaticPadTemplate flac_dec_sink_factory =
144 GST_STATIC_PAD_TEMPLATE ("sink",
147 GST_STATIC_CAPS (GST_FLAC_DEC_SINK_CAPS));
150 gst_flac_dec_class_init (GstFlacDecClass * klass)
152 GstAudioDecoderClass *audiodecoder_class;
153 GstElementClass *gstelement_class;
155 audiodecoder_class = (GstAudioDecoderClass *) klass;
156 gstelement_class = (GstElementClass *) klass;
158 GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
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);
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);
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>");
179 gst_flac_dec_init (GstFlacDec * flacdec)
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
185 GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (flacdec));
189 gst_flac_dec_start (GstAudioDecoder * audio_dec)
191 FLAC__StreamDecoderInitStatus s;
194 dec = GST_FLAC_DEC (audio_dec);
196 dec->adapter = gst_adapter_new ();
198 dec->decoder = FLAC__stream_decoder_new ();
200 gst_audio_info_init (&dec->info);
203 /* no point calculating MD5 since it's never checked here */
204 FLAC__stream_decoder_set_md5_checking (dec->decoder, false);
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);
212 if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
213 GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
217 dec->got_headers = FALSE;
223 gst_flac_dec_stop (GstAudioDecoder * dec)
225 GstFlacDec *flacdec = GST_FLAC_DEC (dec);
227 if (flacdec->decoder) {
228 FLAC__stream_decoder_delete (flacdec->decoder);
229 flacdec->decoder = NULL;
232 if (flacdec->adapter) {
233 gst_adapter_clear (flacdec->adapter);
234 g_object_unref (flacdec->adapter);
235 flacdec->adapter = NULL;
242 gst_flac_dec_get_latency (GstFlacDec * flacdec)
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 */
249 /* Make sure the rate is valid */
250 if (!flacdec->info.rate)
253 /* Calculate the latecy */
254 return (flacdec->max_blocksize * GST_SECOND) / flacdec->info.rate;
258 gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps)
260 const GValue *headers;
265 flacdec = GST_FLAC_DEC (dec);
267 GST_LOG_OBJECT (dec, "sink caps: %" GST_PTR_FORMAT, caps);
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");
277 if (gst_adapter_available (flacdec->adapter) > 0) {
278 GST_WARNING_OBJECT (dec, "unexpected data left in adapter");
279 gst_adapter_clear (flacdec->adapter);
282 FLAC__stream_decoder_reset (flacdec->decoder);
283 flacdec->got_headers = FALSE;
285 num = gst_value_array_get_size (headers);
286 for (i = 0; i < num; ++i) {
287 const GValue *header_val;
288 GstBuffer *header_buf;
290 header_val = gst_value_array_get_value (headers, i);
291 if (header_val == NULL || !GST_VALUE_HOLDS_BUFFER (header_val))
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);
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");
307 gst_adapter_clear (flacdec->adapter);
308 FLAC__stream_decoder_flush (flacdec->decoder);
309 gst_flac_dec_handle_decoder_error (flacdec, TRUE);
312 GST_INFO_OBJECT (dec, "headers and metadata are now processed");
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
354 gst_flac_calculate_crc8 (const guint8 * data, guint length)
359 crc = crc8_table[crc ^ *data];
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 */
369 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, const guint8 * data,
373 guint sr_from_end = 0; /* can be 0, 8 or 16 */
374 guint bs_from_end = 0; /* can be 0, 8 or 16 */
376 guint8 bs, sr, ca, ss, pb;
383 if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8)
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 */
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,
397 if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
401 /* read block size from end of header? */
407 /* read sample rate from end of header? */
410 else if (sr == 0x0D || sr == 0x0E)
414 /* This is slightly faster than a loop */
417 } else if ((val & 0xc0) && !(val & 0x20)) {
419 } else if ((val & 0xe0) && !(val & 0x10)) {
421 } else if ((val & 0xf0) && !(val & 0x08)) {
423 } else if ((val & 0xf8) && !(val & 0x04)) {
425 } else if ((val & 0xfc) && !(val & 0x02)) {
427 } else if ((val & 0xfe) && !(val & 0x01)) {
430 GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
435 headerlen = 4 + val + (bs_from_end / 8) + (sr_from_end / 8);
437 if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
438 GST_LOG_OBJECT (flacdec, "invalid checksum");
446 gst_flac_dec_handle_decoder_error (GstFlacDec * dec, gboolean msg)
451 if (dec->error_count > 10) {
453 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), (NULL));
454 dec->last_flow = GST_FLOW_ERROR;
457 GST_DEBUG_OBJECT (dec, "ignoring error for now at count %d",
466 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
467 const FLAC__StreamMetadata * metadata, void *client_data)
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);
474 GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
476 switch (metadata->type) {
477 case FLAC__METADATA_TYPE_STREAMINFO:{
479 guint depth, width, gdepth, channels;
481 samples = metadata->data.stream_info.total_samples;
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;
489 } else if (depth < 17) {
491 } else if (depth < 25) {
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);
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);
511 gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (flacdec),
514 gst_audio_decoder_negotiate (GST_AUDIO_DECODER (flacdec));
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);
523 GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
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);
537 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
538 FLAC__StreamDecoderErrorStatus status, void *client_data)
543 dec = GST_FLAC_DEC (client_data);
546 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
547 dec->do_resync = TRUE;
549 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
550 error = "bad header";
552 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
553 error = "CRC mismatch";
556 error = "unknown error";
560 if (gst_flac_dec_handle_decoder_error (dec, FALSE))
561 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
564 static FLAC__StreamDecoderReadStatus
565 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
566 FLAC__byte buffer[], size_t * bytes, void *client_data)
568 GstFlacDec *dec = GST_FLAC_DEC (client_data);
571 len = MIN (gst_adapter_available (dec->adapter), *bytes);
574 GST_LOG_OBJECT (dec, "0 bytes available at the moment");
575 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
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);
584 gst_adapter_flush (dec->adapter, len);
586 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
589 static FLAC__StreamDecoderWriteStatus
590 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
591 const FLAC__int32 * const buffer[])
593 GstFlowReturn ret = GST_FLOW_OK;
595 guint depth = frame->header.bits_per_sample;
597 guint sample_rate = frame->header.sample_rate;
598 guint channels = frame->header.channels;
599 guint samples = frame->header.blocksize;
602 gboolean caps_changed;
603 GstAudioChannelPosition chanpos[8];
605 GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
608 if (flacdec->depth < 4 || flacdec->depth > 32) {
609 GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
611 ret = GST_FLOW_ERROR;
615 depth = flacdec->depth;
635 GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
636 ret = GST_FLOW_ERROR;
640 if (sample_rate == 0) {
641 if (flacdec->info.rate != 0) {
642 sample_rate = flacdec->info.rate;
644 GST_ERROR_OBJECT (flacdec, "unknown sample rate");
645 ret = GST_FLOW_ERROR;
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));
656 || !gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (flacdec))) {
657 GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels", sample_rate,
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);
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);
671 flacdec->depth = depth;
673 gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (flacdec),
678 gst_buffer_new_allocate (NULL, samples * channels * (width / 8), NULL);
680 gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
682 gint8 *outbuffer = (gint8 *) map.data;
683 gint *reorder_map = flacdec->channel_reorder_map;
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];
691 } else if (width == 16) {
692 gint16 *outbuffer = (gint16 *) map.data;
693 gint *reorder_map = flacdec->channel_reorder_map;
695 if (gdepth != depth) {
696 for (i = 0; i < samples; i++) {
697 for (j = 0; j < channels; j++) {
699 (gint16) (buffer[reorder_map[j]][i] << (gdepth - depth));
703 for (i = 0; i < samples; i++) {
704 for (j = 0; j < channels; j++) {
705 *outbuffer++ = (gint16) buffer[reorder_map[j]][i];
709 } else if (width == 32) {
710 gint32 *outbuffer = (gint32 *) map.data;
711 gint *reorder_map = flacdec->channel_reorder_map;
713 if (gdepth != depth) {
714 for (i = 0; i < samples; i++) {
715 for (j = 0; j < channels; j++) {
717 (gint32) (buffer[reorder_map[j]][i] << (gdepth - depth));
721 for (i = 0; i < samples; i++) {
722 for (j = 0; j < channels; j++) {
723 *outbuffer++ = (gint32) buffer[reorder_map[j]][i];
728 g_assert_not_reached ();
730 gst_buffer_unmap (outbuf, &map);
732 GST_DEBUG_OBJECT (flacdec, "pushing %d samples", samples);
733 if (flacdec->error_count)
734 flacdec->error_count--;
736 ret = gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (flacdec), outbuf, 1);
738 if (G_UNLIKELY (ret != GST_FLOW_OK)) {
739 GST_DEBUG_OBJECT (flacdec, "finish_frame flow %s", gst_flow_get_name (ret));
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;
750 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
753 static FLAC__StreamDecoderWriteStatus
754 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
755 const FLAC__Frame * frame,
756 const FLAC__int32 * const buffer[], void *client_data)
758 return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
762 gst_flac_dec_flush (GstAudioDecoder * audio_dec, gboolean hard)
764 GstFlacDec *dec = GST_FLAC_DEC (audio_dec);
767 guint available = gst_adapter_available (dec->adapter);
770 GST_INFO_OBJECT (dec, "draining, %u bytes left in adapter", available);
771 FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
775 dec->do_resync = FALSE;
776 FLAC__stream_decoder_flush (dec->decoder);
777 gst_adapter_clear (dec->adapter);
781 gst_flac_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
785 dec = GST_FLAC_DEC (audio_dec);
787 /* drain remaining data? */
788 if (G_UNLIKELY (buf == NULL)) {
789 gst_flac_dec_flush (audio_dec, FALSE);
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;
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));
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;
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);
813 if (!got_audio_frame) {
814 GST_INFO_OBJECT (dec, "dropping in-stream header, %" G_GSIZE_FORMAT " "
816 gst_audio_decoder_finish_frame (audio_dec, NULL, 1);
820 GST_INFO_OBJECT (dec, "first audio frame, got all in-stream headers now");
821 dec->got_headers = TRUE;
824 gst_adapter_push (dec->adapter, gst_buffer_ref (buf));
827 dec->last_flow = GST_FLOW_OK;
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));
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");
839 gst_adapter_clear (dec->adapter);
840 FLAC__stream_decoder_flush (dec->decoder);
841 gst_flac_dec_handle_decoder_error (dec, TRUE);
845 return dec->last_flow;