2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2006> 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., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, 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 filesrc location=media/small/dark.441-16-s.flac ! flacdec ! audioconvert ! audioresample ! autoaudiosink
36 * gst-launch gnomevfssrc location=http://gstreamer.freedesktop.org/media/small/dark.441-16-s.flac ! flacdec ! audioconvert ! audioresample ! queue min-threshold-buffers=10 ! autoaudiosink
41 /* TODO: add seeking when operating chain-based with unframed input */
42 /* FIXME: demote/remove granulepos handling and make more time-centric */
49 #include "gstflacdec.h"
50 #include <gst/gst-i18n-plugin.h>
51 #include <gst/gsttagsetter.h>
52 #include <gst/base/gsttypefindhelper.h>
53 #include <gst/audio/multichannel.h>
54 #include <gst/tag/tag.h>
56 /* Taken from http://flac.sourceforge.net/format.html#frame_header */
57 static const GstAudioChannelPosition channel_positions[8][8] = {
58 {GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
59 {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
60 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
61 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
62 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
63 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
64 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
65 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
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_REAR_LEFT,
72 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
73 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
74 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
75 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
76 GST_AUDIO_CHANNEL_POSITION_LFE,
77 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
78 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
79 /* FIXME: 7/8 channel layouts are not defined in the FLAC specs */
81 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
82 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
83 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
84 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
85 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
86 GST_AUDIO_CHANNEL_POSITION_LFE,
87 GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
88 GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
89 GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
90 GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
91 GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
92 GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
93 GST_AUDIO_CHANNEL_POSITION_LFE,
94 GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
95 GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
98 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
99 #define GST_CAT_DEFAULT flacdec_debug
101 static void gst_flac_dec_finalize (GObject * object);
102 static void gst_flac_dec_loop (GstPad * pad);
104 static GstStateChangeReturn gst_flac_dec_change_state (GstElement * element,
105 GstStateChange transition);
106 static const GstQueryType *gst_flac_dec_get_src_query_types (GstPad * pad);
107 static const GstQueryType *gst_flac_dec_get_sink_query_types (GstPad * pad);
108 static gboolean gst_flac_dec_sink_query (GstPad * pad, GstQuery * query);
109 static gboolean gst_flac_dec_src_query (GstPad * pad, GstQuery * query);
110 static gboolean gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format,
111 gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
112 static gboolean gst_flac_dec_src_event (GstPad * pad, GstEvent * event);
113 static gboolean gst_flac_dec_sink_activate (GstPad * sinkpad);
114 static gboolean gst_flac_dec_sink_activate_pull (GstPad * sinkpad,
116 static gboolean gst_flac_dec_sink_activate_push (GstPad * sinkpad,
118 static gboolean gst_flac_dec_sink_event (GstPad * pad, GstEvent * event);
119 static GstFlowReturn gst_flac_dec_chain (GstPad * pad, GstBuffer * buf);
121 static void gst_flac_dec_reset_decoders (GstFlacDec * flacdec);
122 static void gst_flac_dec_setup_decoder (GstFlacDec * flacdec);
124 static FLAC__StreamDecoderReadStatus
125 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
126 FLAC__byte buffer[], size_t * bytes, void *client_data);
127 static FLAC__StreamDecoderReadStatus
128 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
129 FLAC__byte buffer[], size_t * bytes, void *client_data);
130 static FLAC__StreamDecoderSeekStatus
131 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
132 FLAC__uint64 position, void *client_data);
133 static FLAC__StreamDecoderTellStatus
134 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
135 FLAC__uint64 * position, void *client_data);
136 static FLAC__StreamDecoderLengthStatus
137 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
138 FLAC__uint64 * length, void *client_data);
139 static FLAC__bool gst_flac_dec_eof (const FLAC__StreamDecoder * decoder,
141 static FLAC__StreamDecoderWriteStatus
142 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
143 const FLAC__Frame * frame,
144 const FLAC__int32 * const buffer[], void *client_data);
145 static void gst_flac_dec_metadata_cb (const FLAC__StreamDecoder *
146 decoder, const FLAC__StreamMetadata * metadata, void *client_data);
147 static void gst_flac_dec_error_cb (const FLAC__StreamDecoder *
148 decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
150 GST_BOILERPLATE (GstFlacDec, gst_flac_dec, GstElement, GST_TYPE_ELEMENT);
152 /* FIXME 0.11: Use width=32 for all depths and let audioconvert
153 * handle the conversions instead of doing it ourself.
155 #define GST_FLAC_DEC_SRC_CAPS \
156 "audio/x-raw-int, " \
157 "endianness = (int) BYTE_ORDER, " \
158 "signed = (boolean) true, " \
159 "width = (int) { 8, 16, 32 }, " \
160 "depth = (int) [ 4, 32 ], " \
161 "rate = (int) [ 1, 655350 ], " \
162 "channels = (int) [ 1, 8 ]"
164 static GstStaticPadTemplate flac_dec_src_factory =
165 GST_STATIC_PAD_TEMPLATE ("src",
168 GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
169 static GstStaticPadTemplate flac_dec_sink_factory =
170 GST_STATIC_PAD_TEMPLATE ("sink",
173 GST_STATIC_CAPS ("audio/x-flac")
177 gst_flac_dec_base_init (gpointer g_class)
179 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
181 gst_element_class_add_pad_template (element_class,
182 gst_static_pad_template_get (&flac_dec_src_factory));
183 gst_element_class_add_pad_template (element_class,
184 gst_static_pad_template_get (&flac_dec_sink_factory));
185 gst_element_class_set_details_simple (element_class, "FLAC audio decoder",
186 "Codec/Decoder/Audio",
187 "Decodes FLAC lossless audio streams", "Wim Taymans <wim@fluendo.com>");
189 GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
193 gst_flac_dec_class_init (GstFlacDecClass * klass)
195 GstElementClass *gstelement_class;
196 GObjectClass *gobject_class;
198 gstelement_class = (GstElementClass *) klass;
199 gobject_class = (GObjectClass *) klass;
201 gobject_class->finalize = gst_flac_dec_finalize;
203 gstelement_class->change_state =
204 GST_DEBUG_FUNCPTR (gst_flac_dec_change_state);
208 gst_flac_dec_init (GstFlacDec * flacdec, GstFlacDecClass * klass)
211 gst_pad_new_from_static_template (&flac_dec_sink_factory, "sink");
212 gst_pad_set_activate_function (flacdec->sinkpad,
213 GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate));
214 gst_pad_set_activatepull_function (flacdec->sinkpad,
215 GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_pull));
216 gst_pad_set_activatepush_function (flacdec->sinkpad,
217 GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_push));
218 gst_pad_set_query_type_function (flacdec->sinkpad,
219 GST_DEBUG_FUNCPTR (gst_flac_dec_get_sink_query_types));
220 gst_pad_set_query_function (flacdec->sinkpad,
221 GST_DEBUG_FUNCPTR (gst_flac_dec_sink_query));
222 gst_pad_set_event_function (flacdec->sinkpad,
223 GST_DEBUG_FUNCPTR (gst_flac_dec_sink_event));
224 gst_pad_set_chain_function (flacdec->sinkpad,
225 GST_DEBUG_FUNCPTR (gst_flac_dec_chain));
226 gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->sinkpad);
229 gst_pad_new_from_static_template (&flac_dec_src_factory, "src");
230 gst_pad_set_query_type_function (flacdec->srcpad,
231 GST_DEBUG_FUNCPTR (gst_flac_dec_get_src_query_types));
232 gst_pad_set_query_function (flacdec->srcpad,
233 GST_DEBUG_FUNCPTR (gst_flac_dec_src_query));
234 gst_pad_set_event_function (flacdec->srcpad,
235 GST_DEBUG_FUNCPTR (gst_flac_dec_src_event));
236 gst_pad_use_fixed_caps (flacdec->srcpad);
237 gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->srcpad);
239 gst_flac_dec_reset_decoders (flacdec);
243 gst_flac_dec_reset_decoders (GstFlacDec * flacdec)
245 /* Clean up the decoder */
246 if (flacdec->decoder) {
247 FLAC__stream_decoder_delete (flacdec->decoder);
248 flacdec->decoder = NULL;
251 if (flacdec->adapter) {
252 gst_adapter_clear (flacdec->adapter);
253 g_object_unref (flacdec->adapter);
254 flacdec->adapter = NULL;
257 if (flacdec->close_segment) {
258 gst_event_unref (flacdec->close_segment);
259 flacdec->close_segment = NULL;
261 if (flacdec->start_segment) {
262 gst_event_unref (flacdec->start_segment);
263 flacdec->start_segment = NULL;
266 gst_tag_list_free (flacdec->tags);
267 flacdec->tags = NULL;
269 if (flacdec->pending) {
270 gst_buffer_unref (flacdec->pending);
271 flacdec->pending = NULL;
274 flacdec->segment.last_stop = 0;
276 flacdec->init = TRUE;
280 gst_flac_dec_setup_decoder (GstFlacDec * dec)
282 gst_flac_dec_reset_decoders (dec);
284 dec->tags = gst_tag_list_new ();
285 gst_tag_list_add (dec->tags, GST_TAG_MERGE_REPLACE,
286 GST_TAG_AUDIO_CODEC, "FLAC", NULL);
288 dec->adapter = gst_adapter_new ();
290 dec->decoder = FLAC__stream_decoder_new ();
292 /* no point calculating since it's never checked here */
293 FLAC__stream_decoder_set_md5_checking (dec->decoder, false);
294 FLAC__stream_decoder_set_metadata_respond (dec->decoder,
295 FLAC__METADATA_TYPE_VORBIS_COMMENT);
296 FLAC__stream_decoder_set_metadata_respond (dec->decoder,
297 FLAC__METADATA_TYPE_PICTURE);
301 gst_flac_dec_finalize (GObject * object)
305 flacdec = GST_FLAC_DEC (object);
307 gst_flac_dec_reset_decoders (flacdec);
309 G_OBJECT_CLASS (parent_class)->finalize (object);
314 gst_flac_dec_update_metadata (GstFlacDec * flacdec,
315 const FLAC__StreamMetadata * metadata)
321 list = flacdec->tags;
323 flacdec->tags = list = gst_tag_list_new ();
325 num = metadata->data.vorbis_comment.num_comments;
326 GST_DEBUG_OBJECT (flacdec, "%u tag(s) found", num);
328 for (i = 0; i < num; ++i) {
329 gchar *vc, *name, *value;
331 vc = g_strndup ((gchar *) metadata->data.vorbis_comment.comments[i].entry,
332 metadata->data.vorbis_comment.comments[i].length);
334 if (gst_tag_parse_extended_comment (vc, &name, NULL, &value, TRUE)) {
335 GST_DEBUG_OBJECT (flacdec, "%s : %s", name, value);
336 if (value && strlen (value))
337 gst_vorbis_tag_add (list, name, value);
348 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
349 static const guint8 crc8_table[256] = {
350 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
351 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
352 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
353 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
354 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
355 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
356 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
357 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
358 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
359 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
360 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
361 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
362 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
363 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
364 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
365 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
366 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
367 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
368 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
369 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
370 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
371 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
372 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
373 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
374 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
375 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
376 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
377 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
378 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
379 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
380 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
381 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
385 gst_flac_calculate_crc8 (guint8 * data, guint length)
390 crc = crc8_table[crc ^ *data];
398 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
399 gint64 * last_sample_num)
402 guint sr_from_end = 0; /* can be 0, 8 or 16 */
403 guint bs_from_end = 0; /* can be 0, 8 or 16 */
405 guint8 bs, sr, ca, ss, pb;
411 if (data[0] != 0xFF || data[1] != 0xF8)
414 bs = (data[2] & 0xF0) >> 8; /* blocksize marker */
415 sr = (data[2] & 0x0F); /* samplerate marker */
416 ca = (data[3] & 0xF0) >> 8; /* channel assignment */
417 ss = (data[3] & 0x0F) >> 1; /* sample size marker */
418 pb = (data[3] & 0x01); /* padding bit */
420 GST_LOG_OBJECT (flacdec,
421 "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
423 if (sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
427 /* read block size from end of header? */
433 /* read sample rate from end of header? */
436 else if (sr == 0x0D || sr == 0x0E)
439 val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
441 if (val == (guint32) - 1 || val == (guint32) - 2) {
442 GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
446 headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
447 (bs_from_end / 8) + (sr_from_end / 8);
449 if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen])
452 if (flacdec->min_blocksize == flacdec->max_blocksize) {
453 *last_sample_num = (val + 1) * flacdec->min_blocksize;
455 *last_sample_num = val; /* FIXME: + length of last block in samples */
458 if (flacdec->sample_rate > 0) {
459 GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
460 GST_TIME_FORMAT, *last_sample_num,
461 GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->sample_rate));
467 #define SCANBLOCK_SIZE (64*1024)
470 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
472 GstFormat format = GST_FORMAT_BYTES;
474 gint64 file_size, offset;
476 GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
478 if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
479 GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
483 GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
485 offset = file_size - 1;
486 while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
488 GstBuffer *buf = NULL;
492 /* divide by 2 = not very sophisticated way to deal with overlapping */
493 offset -= SCANBLOCK_SIZE / 2;
494 GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
495 "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
497 flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
498 if (flow != GST_FLOW_OK) {
499 GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
503 size = GST_BUFFER_SIZE (buf);
504 data = GST_BUFFER_DATA (buf);
507 if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
508 GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
509 offset + GST_BUFFER_SIZE (buf) - size);
510 gst_buffer_unref (buf);
517 gst_buffer_unref (buf);
522 gst_flac_extract_picture_buffer (GstFlacDec * dec,
523 const FLAC__StreamMetadata * metadata)
525 FLAC__StreamMetadata_Picture picture;
528 g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
530 GST_LOG_OBJECT (dec, "Got PICTURE block");
531 picture = metadata->data.picture;
533 GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
534 GST_STR_NULL (picture.mime_type));
535 GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
537 tags = gst_tag_list_new ();
539 gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
540 picture.data_length, picture.type);
542 if (!gst_tag_list_is_empty (tags)) {
543 gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
545 GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
546 gst_tag_list_free (tags);
551 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
552 const FLAC__StreamMetadata * metadata, void *client_data)
554 GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
556 GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
558 switch (metadata->type) {
559 case FLAC__METADATA_TYPE_STREAMINFO:{
563 samples = metadata->data.stream_info.total_samples;
565 flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
566 flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
567 flacdec->sample_rate = metadata->data.stream_info.sample_rate;
568 flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
569 flacdec->channels = metadata->data.stream_info.channels;
578 GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
579 flacdec->min_blocksize, flacdec->max_blocksize);
580 GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
581 flacdec->sample_rate, flacdec->channels);
582 GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
585 /* Only scan for last block in pull-mode, since it uses pull_range() */
586 if (samples == 0 && !flacdec->streaming) {
587 gst_flac_dec_scan_for_last_block (flacdec, &samples);
590 GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
592 /* in framed mode the demuxer/parser upstream has already pushed a
593 * newsegment event in TIME format which we've passed on */
594 if (samples > 0 && !flacdec->framed) {
597 gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
600 /* convert duration to time */
601 duration = gst_util_uint64_scale_int (samples, GST_SECOND,
602 flacdec->sample_rate);
604 /* fixme, at this time we could seek to the queued seek event if we have
606 if (flacdec->start_segment)
607 gst_event_unref (flacdec->start_segment);
608 flacdec->start_segment =
609 gst_event_new_new_segment_full (FALSE,
610 flacdec->segment.rate, flacdec->segment.applied_rate,
611 GST_FORMAT_TIME, 0, duration, 0);
615 case FLAC__METADATA_TYPE_PICTURE:{
616 gst_flac_extract_picture_buffer (flacdec, metadata);
619 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
620 gst_flac_dec_update_metadata (flacdec, metadata);
628 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
629 FLAC__StreamDecoderErrorStatus status, void *client_data)
634 dec = GST_FLAC_DEC (client_data);
637 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
638 /* Ignore this error and keep processing */
640 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
641 error = "bad header";
643 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
644 error = "CRC mismatch";
647 error = "unknown error";
651 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
652 dec->last_flow = GST_FLOW_ERROR;
655 static FLAC__StreamDecoderSeekStatus
656 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
657 FLAC__uint64 position, void *client_data)
661 flacdec = GST_FLAC_DEC (client_data);
663 GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
664 flacdec->offset = position;
666 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
669 static FLAC__StreamDecoderTellStatus
670 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
671 FLAC__uint64 * position, void *client_data)
675 flacdec = GST_FLAC_DEC (client_data);
677 *position = flacdec->offset;
679 GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
681 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
684 static FLAC__StreamDecoderLengthStatus
685 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
686 FLAC__uint64 * length, void *client_data)
689 GstFormat fmt = GST_FORMAT_BYTES;
693 flacdec = GST_FLAC_DEC (client_data);
695 if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
696 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
698 gst_pad_query_duration (peer, &fmt, &len);
699 gst_object_unref (peer);
700 if (fmt != GST_FORMAT_BYTES || len == -1)
701 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
705 GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
708 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
712 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
717 gboolean ret = FALSE;
720 flacdec = GST_FLAC_DEC (client_data);
722 if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
723 GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
727 fmt = GST_FORMAT_BYTES;
728 if (gst_pad_query_duration (peer, &fmt, &len) && fmt == GST_FORMAT_BYTES &&
729 len != -1 && flacdec->offset >= len) {
730 GST_DEBUG_OBJECT (flacdec,
731 "offset=%" G_GINT64_FORMAT ", len=%" G_GINT64_FORMAT
732 ", returning EOF", flacdec->offset, len);
736 gst_object_unref (peer);
741 static FLAC__StreamDecoderReadStatus
742 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
743 FLAC__byte buffer[], size_t * bytes, void *client_data)
749 flacdec = GST_FLAC_DEC (client_data);
751 flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
753 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
754 flacdec->pull_flow = flow;
755 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
757 if (G_UNLIKELY (flow != GST_FLOW_OK)) {
758 GST_INFO_OBJECT (flacdec, "pull_range flow: %s", gst_flow_get_name (flow));
759 if (flow == GST_FLOW_UNEXPECTED)
760 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
762 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
765 GST_DEBUG_OBJECT (flacdec, "Read %d bytes at %" G_GUINT64_FORMAT,
766 GST_BUFFER_SIZE (buf), flacdec->offset);
767 memcpy (buffer, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
768 *bytes = GST_BUFFER_SIZE (buf);
769 gst_buffer_unref (buf);
770 flacdec->offset += *bytes;
772 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
775 static FLAC__StreamDecoderReadStatus
776 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
777 FLAC__byte buffer[], size_t * bytes, void *client_data)
779 GstFlacDec *dec = GST_FLAC_DEC (client_data);
782 len = MIN (gst_adapter_available (dec->adapter), *bytes);
785 GST_LOG_OBJECT (dec, "0 bytes available at the moment");
786 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
789 GST_LOG_OBJECT (dec, "feeding %u bytes to decoder (available=%u, bytes=%u)",
790 len, gst_adapter_available (dec->adapter), (guint) * bytes);
791 gst_adapter_copy (dec->adapter, buffer, 0, len);
794 gst_adapter_flush (dec->adapter, len);
796 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
799 static FLAC__StreamDecoderWriteStatus
800 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
801 const FLAC__int32 * const buffer[])
803 GstFlowReturn ret = GST_FLOW_OK;
805 guint depth = frame->header.bits_per_sample;
807 guint sample_rate = frame->header.sample_rate;
808 guint channels = frame->header.channels;
809 guint samples = frame->header.blocksize;
813 GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
815 /* if a DEFAULT segment is configured, don't send samples past the end
817 if (flacdec->segment.format == GST_FORMAT_DEFAULT &&
818 flacdec->segment.stop != -1 &&
819 flacdec->segment.last_stop >= 0 &&
820 flacdec->segment.last_stop + samples > flacdec->segment.stop) {
821 samples = flacdec->segment.stop - flacdec->segment.last_stop;
822 GST_DEBUG_OBJECT (flacdec,
823 "clipping last buffer to %d samples because of segment", samples);
840 if (flacdec->depth < 4 || flacdec->depth > 32) {
841 GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
843 ret = GST_FLOW_ERROR;
847 depth = flacdec->depth;
857 GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
858 ret = GST_FLOW_ERROR;
862 if (sample_rate == 0) {
863 if (flacdec->sample_rate != 0) {
864 sample_rate = flacdec->sample_rate;
866 GST_ERROR_OBJECT (flacdec, "unknown sample rate");
867 ret = GST_FLOW_ERROR;
872 if (!GST_PAD_CAPS (flacdec->srcpad)) {
875 GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
876 frame->header.sample_rate, channels);
878 caps = gst_caps_new_simple ("audio/x-raw-int",
879 "endianness", G_TYPE_INT, G_BYTE_ORDER,
880 "signed", G_TYPE_BOOLEAN, TRUE,
881 "width", G_TYPE_INT, width,
882 "depth", G_TYPE_INT, depth,
883 "rate", G_TYPE_INT, frame->header.sample_rate,
884 "channels", G_TYPE_INT, channels, NULL);
887 GstStructure *s = gst_caps_get_structure (caps, 0);
889 gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
892 flacdec->depth = depth;
893 flacdec->width = width;
894 flacdec->channels = channels;
895 flacdec->sample_rate = sample_rate;
897 gst_pad_set_caps (flacdec->srcpad, caps);
898 gst_caps_unref (caps);
901 if (flacdec->close_segment) {
902 GST_DEBUG_OBJECT (flacdec, "pushing close segment");
903 gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
904 flacdec->close_segment = NULL;
906 if (flacdec->start_segment) {
907 GST_DEBUG_OBJECT (flacdec, "pushing start segment");
908 gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
909 flacdec->start_segment = NULL;
913 gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
915 flacdec->tags = NULL;
918 if (flacdec->pending) {
919 GST_DEBUG_OBJECT (flacdec,
920 "pushing pending samples at offset %" G_GINT64_FORMAT " (%"
921 GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
922 GST_BUFFER_OFFSET (flacdec->pending),
923 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (flacdec->pending)),
924 GST_TIME_ARGS (GST_BUFFER_DURATION (flacdec->pending)));
925 /* Pending buffer was always allocated from the seeking thread,
926 * which means it wasn't gst_buffer_alloc'd. Do so now to let
927 * downstream negotiation work on older basetransform */
928 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
929 GST_BUFFER_OFFSET (flacdec->pending),
930 GST_BUFFER_SIZE (flacdec->pending),
931 GST_BUFFER_CAPS (flacdec->pending), &outbuf);
932 if (ret == GST_FLOW_OK) {
933 gst_pad_push (flacdec->srcpad, flacdec->pending);
934 gst_buffer_unref (outbuf);
937 outbuf = flacdec->pending = NULL;
938 flacdec->segment.last_stop += flacdec->pending_samples;
939 flacdec->pending_samples = 0;
942 if (flacdec->seeking) {
943 GST_DEBUG_OBJECT (flacdec, "a pad_alloc would block here, do normal alloc");
944 outbuf = gst_buffer_new_and_alloc (samples * channels * (width / 8));
945 gst_buffer_set_caps (outbuf, GST_PAD_CAPS (flacdec->srcpad));
946 GST_BUFFER_OFFSET (outbuf) = flacdec->segment.last_stop;
948 GST_LOG_OBJECT (flacdec, "alloc_buffer_and_set_caps");
949 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
950 flacdec->segment.last_stop, samples * channels * (width / 8),
951 GST_PAD_CAPS (flacdec->srcpad), &outbuf);
953 if (ret != GST_FLOW_OK) {
954 GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
955 gst_flow_get_name (ret));
960 if (flacdec->cur_granulepos != GST_BUFFER_OFFSET_NONE) {
961 /* this should be fine since it should be one flac frame per ogg packet */
962 flacdec->segment.last_stop = flacdec->cur_granulepos - samples;
963 GST_LOG_OBJECT (flacdec, "granulepos = %" G_GINT64_FORMAT ", samples = %u",
964 flacdec->cur_granulepos, samples);
967 GST_BUFFER_TIMESTAMP (outbuf) =
968 gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
969 frame->header.sample_rate);
971 /* get next timestamp to calculate the duration */
972 next = gst_util_uint64_scale_int (flacdec->segment.last_stop + samples,
973 GST_SECOND, frame->header.sample_rate);
975 GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
978 gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
980 for (i = 0; i < samples; i++) {
981 for (j = 0; j < channels; j++) {
982 *outbuffer++ = (gint8) buffer[j][i];
985 } else if (width == 16) {
986 gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
988 for (i = 0; i < samples; i++) {
989 for (j = 0; j < channels; j++) {
990 *outbuffer++ = (gint16) buffer[j][i];
993 } else if (width == 32) {
994 gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
996 for (i = 0; i < samples; i++) {
997 for (j = 0; j < channels; j++) {
998 *outbuffer++ = (gint32) buffer[j][i];
1002 g_assert_not_reached ();
1005 if (!flacdec->seeking) {
1006 GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
1007 " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
1008 samples, GST_BUFFER_OFFSET (outbuf),
1009 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1010 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1012 if (flacdec->discont) {
1013 GST_DEBUG_OBJECT (flacdec, "marking discont");
1014 outbuf = gst_buffer_make_metadata_writable (outbuf);
1015 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1016 flacdec->discont = FALSE;
1018 ret = gst_pad_push (flacdec->srcpad, outbuf);
1019 GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
1020 flacdec->segment.last_stop += samples;
1022 GST_DEBUG_OBJECT (flacdec,
1023 "not pushing %d samples at offset %" G_GINT64_FORMAT
1024 " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
1025 gst_buffer_replace (&flacdec->pending, outbuf);
1026 gst_buffer_unref (outbuf);
1027 flacdec->pending_samples = samples;
1031 if (ret != GST_FLOW_OK) {
1032 GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1033 gst_flow_get_name (ret));
1039 /* we act on the flow return value later in the loop function, as we don't
1040 * want to mess up the internal decoder state by returning ABORT when the
1041 * error is in fact non-fatal (like a pad in flushing mode) and we want
1042 * to continue later. So just pretend everything's dandy and act later. */
1043 flacdec->last_flow = ret;
1045 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1048 static FLAC__StreamDecoderWriteStatus
1049 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
1050 const FLAC__Frame * frame,
1051 const FLAC__int32 * const buffer[], void *client_data)
1053 return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1057 gst_flac_dec_loop (GstPad * sinkpad)
1059 GstFlacDec *flacdec;
1060 FLAC__StreamDecoderState s;
1061 FLAC__StreamDecoderInitStatus is;
1063 flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1065 GST_LOG_OBJECT (flacdec, "entering loop");
1067 if (flacdec->init) {
1068 GST_DEBUG_OBJECT (flacdec, "initializing new decoder");
1069 is = FLAC__stream_decoder_init_stream (flacdec->decoder,
1070 gst_flac_dec_read_seekable, gst_flac_dec_seek, gst_flac_dec_tell,
1071 gst_flac_dec_length, gst_flac_dec_eof, gst_flac_dec_write_stream,
1072 gst_flac_dec_metadata_cb, gst_flac_dec_error_cb, flacdec);
1073 if (is != FLAC__STREAM_DECODER_INIT_STATUS_OK)
1076 /* FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1077 flacdec->init = FALSE;
1080 flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1082 flacdec->last_flow = GST_FLOW_OK;
1084 GST_LOG_OBJECT (flacdec, "processing single");
1085 FLAC__stream_decoder_process_single (flacdec->decoder);
1089 GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1090 s = FLAC__stream_decoder_get_state (flacdec->decoder);
1092 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
1093 case FLAC__STREAM_DECODER_READ_METADATA:
1094 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
1095 case FLAC__STREAM_DECODER_READ_FRAME:
1097 GST_DEBUG_OBJECT (flacdec, "everything ok");
1099 if (GST_FLOW_IS_FATAL (flacdec->last_flow) ||
1100 flacdec->last_flow == GST_FLOW_NOT_LINKED) {
1101 GST_ELEMENT_ERROR (flacdec, STREAM, FAILED,
1102 (_("Internal data stream error.")),
1103 ("stream stopped, reason %s",
1104 gst_flow_get_name (flacdec->last_flow)));
1106 } else if (flacdec->last_flow != GST_FLOW_OK) {
1110 /* check if we're at the end of a configured segment */
1111 if (flacdec->segment.stop != -1 &&
1112 flacdec->segment.last_stop > 0 &&
1113 flacdec->segment.last_stop >= flacdec->segment.stop) {
1114 GST_DEBUG_OBJECT (flacdec, "reached end of the configured segment");
1116 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1119 goto segment_done_and_pause;
1122 g_assert_not_reached ();
1128 case FLAC__STREAM_DECODER_END_OF_STREAM:{
1129 GST_DEBUG_OBJECT (flacdec, "EOS");
1130 FLAC__stream_decoder_reset (flacdec->decoder);
1132 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1133 if (flacdec->segment.duration > 0) {
1134 flacdec->segment.stop = flacdec->segment.duration;
1136 flacdec->segment.stop = flacdec->segment.last_stop;
1138 goto segment_done_and_pause;
1144 /* gst_flac_dec_read_seekable() returned ABORTED */
1145 case FLAC__STREAM_DECODER_ABORTED:
1147 GST_INFO_OBJECT (flacdec, "read aborted: last pull_range flow = %s",
1148 gst_flow_get_name (flacdec->pull_flow));
1149 if (!GST_FLOW_IS_FATAL (flacdec->pull_flow)) {
1150 /* it seems we need to flush the decoder here to reset the decoder
1151 * state after the abort for FLAC__stream_decoder_seek_absolute()
1152 * to work properly */
1153 GST_DEBUG_OBJECT (flacdec, "flushing decoder to reset decoder state");
1154 FLAC__stream_decoder_flush (flacdec->decoder);
1159 case FLAC__STREAM_DECODER_OGG_ERROR:
1160 case FLAC__STREAM_DECODER_SEEK_ERROR:
1161 case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
1162 case FLAC__STREAM_DECODER_UNINITIALIZED:
1164 /* fixme: this error sucks -- should try to figure out when/if an more
1165 specific error was already sent via the callback */
1166 GST_ELEMENT_ERROR (flacdec, STREAM, DECODE, (NULL),
1167 ("%s", FLAC__StreamDecoderStateString[s]));
1174 segment_done_and_pause:
1178 stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1179 GST_SECOND, flacdec->sample_rate);
1181 GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1182 GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1184 gst_element_post_message (GST_ELEMENT (flacdec),
1185 gst_message_new_segment_done (GST_OBJECT (flacdec),
1186 GST_FORMAT_TIME, stop_time));
1192 GST_DEBUG_OBJECT (flacdec, "sending EOS event");
1193 flacdec->running = FALSE;
1194 gst_pad_push_event (flacdec->srcpad, gst_event_new_eos ());
1195 /* fall through to pause */
1199 GST_DEBUG_OBJECT (flacdec, "pausing");
1200 gst_pad_pause_task (sinkpad);
1206 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1211 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1213 switch (GST_EVENT_TYPE (event)) {
1214 case GST_EVENT_FLUSH_STOP:{
1215 if (dec->init == FALSE) {
1216 FLAC__stream_decoder_flush (dec->decoder);
1217 gst_adapter_clear (dec->adapter);
1219 res = gst_pad_push_event (dec->srcpad, event);
1222 case GST_EVENT_NEWSEGMENT:{
1225 gdouble rate, applied_rate;
1226 gint64 cur, stop, time;
1228 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1229 &fmt, &cur, &stop, &time);
1231 if (fmt == GST_FORMAT_TIME) {
1232 GstFormat dformat = GST_FORMAT_DEFAULT;
1234 GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1236 res = gst_pad_push_event (dec->srcpad, event);
1238 /* this won't work for the first newsegment event though ... */
1239 if (gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, cur,
1240 &dformat, &cur) && cur != -1 &&
1241 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, stop,
1242 &dformat, &stop) && stop != -1) {
1243 gst_segment_set_newsegment_full (&dec->segment, update, rate,
1244 applied_rate, dformat, cur, stop, time);
1245 GST_DEBUG_OBJECT (dec, "segment %" GST_SEGMENT_FORMAT, &dec->segment);
1247 GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1249 } else if (fmt == GST_FORMAT_BYTES || TRUE) {
1250 GST_DEBUG_OBJECT (dec, "newsegment event in %s format => not framed",
1251 gst_format_get_name (fmt));
1252 dec->framed = FALSE;
1254 /* prepare generic newsegment event, for some reason our metadata
1255 * callback where we usually set this up is not being called in
1257 dec->start_segment = gst_event_new_new_segment (FALSE, 1.0,
1258 GST_FORMAT_TIME, 0, -1, 0);
1260 gst_event_unref (event);
1265 case GST_EVENT_EOS:{
1266 GST_LOG_OBJECT (dec, "EOS, with %u bytes available in adapter",
1267 gst_adapter_available (dec->adapter));
1268 if (dec->init == FALSE) {
1269 if (gst_adapter_available (dec->adapter) > 0) {
1270 FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
1272 FLAC__stream_decoder_flush (dec->decoder);
1274 gst_adapter_clear (dec->adapter);
1275 res = gst_pad_push_event (dec->srcpad, event);
1279 res = gst_pad_event_default (pad, event);
1283 gst_object_unref (dec);
1288 static GstFlowReturn
1289 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1291 FLAC__StreamDecoderInitStatus s;
1293 gboolean got_audio_frame;
1295 dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1297 GST_LOG_OBJECT (dec, "buffer with ts=%" GST_TIME_FORMAT ", end_offset=%"
1298 G_GINT64_FORMAT ", size=%u", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1299 GST_BUFFER_OFFSET_END (buf), GST_BUFFER_SIZE (buf));
1302 GST_DEBUG_OBJECT (dec, "initializing decoder");
1303 s = FLAC__stream_decoder_init_stream (dec->decoder,
1304 gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
1305 gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
1306 gst_flac_dec_error_cb, dec);
1307 if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1308 GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
1309 return GST_FLOW_ERROR;
1311 GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1313 } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1314 /* Clear the adapter and the decoder */
1315 gst_adapter_clear (dec->adapter);
1316 FLAC__stream_decoder_flush (dec->decoder);
1322 /* check if this is a flac audio frame (rather than a header or junk) */
1323 got_audio_frame = gst_flac_dec_scan_got_frame (dec, GST_BUFFER_DATA (buf),
1324 GST_BUFFER_SIZE (buf), &unused);
1326 /* oggdemux will set granulepos in OFFSET_END instead of timestamp */
1327 if (G_LIKELY (got_audio_frame)) {
1328 /* old oggdemux for now */
1329 if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1330 dec->cur_granulepos = GST_BUFFER_OFFSET_END (buf);
1332 GstFormat dformat = GST_FORMAT_DEFAULT;
1334 /* upstream (e.g. demuxer) presents us time,
1335 * convert to default samples */
1336 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME,
1337 GST_BUFFER_TIMESTAMP (buf), &dformat, &dec->segment.last_stop);
1338 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1342 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1343 got_audio_frame = TRUE;
1346 gst_adapter_push (dec->adapter, buf);
1349 dec->last_flow = GST_FLOW_OK;
1352 /* wait until we have at least 64kB because libflac's StreamDecoder
1353 * interface is a bit dumb it seems (if we don't have as much data as
1354 * it wants it will call our read callback repeatedly and the only
1355 * way to stop that is to error out or EOS, which will affect the
1356 * decoder state). And the decoder seems to always ask for MAX_BLOCK_SIZE
1357 * bytes rather than the max. block size from the header). Requiring
1358 * MAX_BLOCK_SIZE bytes here should make sure it always gets enough data
1359 * to decode at least one block */
1360 while (gst_adapter_available (dec->adapter) >= FLAC__MAX_BLOCK_SIZE &&
1361 dec->last_flow == GST_FLOW_OK) {
1362 GST_LOG_OBJECT (dec, "%u bytes available",
1363 gst_adapter_available (dec->adapter));
1364 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1365 GST_DEBUG_OBJECT (dec, "process_single failed");
1369 if (FLAC__stream_decoder_get_state (dec->decoder) ==
1370 FLAC__STREAM_DECODER_ABORTED) {
1371 GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
1372 dec->last_flow = GST_FLOW_ERROR;
1376 } else if (dec->framed && got_audio_frame) {
1377 /* framed - there should always be enough data to decode something */
1378 GST_LOG_OBJECT (dec, "%u bytes available",
1379 gst_adapter_available (dec->adapter));
1380 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1381 GST_DEBUG_OBJECT (dec, "process_single failed");
1384 GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1387 return dec->last_flow;
1391 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1392 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1394 gboolean res = TRUE;
1396 if (dec->width == 0 || dec->channels == 0 || dec->sample_rate == 0) {
1397 /* no frame decoded yet */
1398 GST_DEBUG_OBJECT (dec, "cannot convert: not set up yet");
1402 switch (src_format) {
1403 case GST_FORMAT_BYTES:{
1407 case GST_FORMAT_DEFAULT:
1408 switch (*dest_format) {
1409 case GST_FORMAT_BYTES:
1412 case GST_FORMAT_TIME:
1413 /* granulepos = sample */
1414 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1422 case GST_FORMAT_TIME:
1423 switch (*dest_format) {
1424 case GST_FORMAT_BYTES:
1427 case GST_FORMAT_DEFAULT:
1428 *dest_value = gst_util_uint64_scale_int (src_value,
1429 dec->sample_rate, GST_SECOND);
1443 static const GstQueryType *
1444 gst_flac_dec_get_sink_query_types (GstPad * pad)
1446 static const GstQueryType types[] = {
1455 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1458 gboolean res = FALSE;
1460 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1462 GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1464 switch (GST_QUERY_TYPE (query)) {
1465 case GST_QUERY_CONVERT:{
1466 GstFormat src_fmt, dest_fmt;
1468 gint64 src_val, dest_val;
1470 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1472 res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1476 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1478 GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1483 res = gst_pad_query_default (pad, query);
1488 gst_object_unref (dec);
1493 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1494 GstFormat * dest_format, gint64 * dest_value)
1496 GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1497 gboolean res = TRUE;
1498 guint bytes_per_sample;
1501 if (flacdec->width == 0 || flacdec->channels == 0 ||
1502 flacdec->sample_rate == 0) {
1503 /* no frame decoded yet */
1504 GST_DEBUG_OBJECT (flacdec, "cannot convert: not set up yet");
1508 bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1510 switch (src_format) {
1511 case GST_FORMAT_BYTES:{
1512 switch (*dest_format) {
1513 case GST_FORMAT_DEFAULT:
1515 gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1517 case GST_FORMAT_TIME:
1519 gint byterate = bytes_per_sample * flacdec->sample_rate;
1521 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1530 case GST_FORMAT_DEFAULT:
1531 switch (*dest_format) {
1532 case GST_FORMAT_BYTES:
1533 *dest_value = src_value * bytes_per_sample;
1535 case GST_FORMAT_TIME:
1536 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1537 flacdec->sample_rate);
1543 case GST_FORMAT_TIME:
1544 switch (*dest_format) {
1545 case GST_FORMAT_BYTES:
1546 scale = bytes_per_sample;
1547 case GST_FORMAT_DEFAULT:
1548 *dest_value = gst_util_uint64_scale_int (src_value,
1549 scale * flacdec->sample_rate, GST_SECOND);
1561 static const GstQueryType *
1562 gst_flac_dec_get_src_query_types (GstPad * pad)
1564 static const GstQueryType types[] = {
1576 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1578 GstFlacDec *flacdec;
1579 gboolean res = TRUE;
1582 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1583 peer = gst_pad_get_peer (flacdec->sinkpad);
1585 switch (GST_QUERY_TYPE (query)) {
1586 case GST_QUERY_POSITION:{
1590 gst_query_parse_position (query, &fmt, NULL);
1592 /* there might be a demuxer in front of us who can handle this */
1593 if (fmt == GST_FORMAT_TIME && (res = gst_pad_query (peer, query)))
1596 if (fmt != GST_FORMAT_DEFAULT) {
1597 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1598 flacdec->segment.last_stop, &fmt, &pos)) {
1599 GST_DEBUG_OBJECT (flacdec, "failed to convert position into %s "
1600 "format", gst_format_get_name (fmt));
1605 pos = flacdec->segment.last_stop;
1608 gst_query_set_position (query, fmt, pos);
1610 GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1611 " (format: %s)", pos, gst_format_get_name (fmt));
1617 case GST_QUERY_DURATION:{
1621 gst_query_parse_duration (query, &fmt, NULL);
1623 /* try any demuxers before us first */
1624 if (fmt == GST_FORMAT_TIME && peer && gst_pad_query (peer, query)) {
1625 gst_query_parse_duration (query, NULL, &len);
1626 GST_DEBUG_OBJECT (flacdec, "peer returned duration %" GST_TIME_FORMAT,
1627 GST_TIME_ARGS (len));
1632 if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1633 GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1638 /* convert total number of samples to request format */
1639 if (fmt != GST_FORMAT_DEFAULT) {
1640 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1641 flacdec->segment.duration, &fmt, &len)) {
1642 GST_DEBUG_OBJECT (flacdec, "failed to convert duration into %s "
1643 "format", gst_format_get_name (fmt));
1648 len = flacdec->segment.duration;
1651 gst_query_set_duration (query, fmt, len);
1653 GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1654 " (format: %s)", len, gst_format_get_name (fmt));
1660 case GST_QUERY_CONVERT:{
1661 GstFormat src_fmt, dest_fmt;
1662 gint64 src_val, dest_val;
1664 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1666 res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1670 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1675 case GST_QUERY_SEEKING:{
1677 gboolean seekable = FALSE;
1680 /* If upstream can handle the query we're done */
1681 seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1683 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1687 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1688 if ((fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT) ||
1689 flacdec->streaming) {
1690 gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1692 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1698 res = gst_pad_query_default (pad, query);
1706 gst_object_unref (peer);
1708 gst_object_unref (flacdec);
1714 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1717 GstSeekFlags seek_flags;
1718 GstSeekType start_type;
1719 GstSeekType stop_type;
1721 GstFormat seek_format;
1722 gboolean only_update = FALSE;
1725 gint64 start, last_stop;
1728 if (flacdec->streaming) {
1729 GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1733 gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1734 &start, &stop_type, &stop);
1736 if (seek_format != GST_FORMAT_DEFAULT && seek_format != GST_FORMAT_TIME) {
1737 GST_DEBUG_OBJECT (flacdec,
1738 "seeking is only supported in TIME or DEFAULT format");
1743 GST_DEBUG_OBJECT (flacdec,
1744 "only forward playback supported, rate %f not allowed", rate);
1748 if (seek_format != GST_FORMAT_DEFAULT) {
1749 GstFormat target_format = GST_FORMAT_DEFAULT;
1751 if (start_type != GST_SEEK_TYPE_NONE &&
1752 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, start,
1753 &target_format, &start)) {
1754 GST_DEBUG_OBJECT (flacdec, "failed to convert start to DEFAULT format");
1758 if (stop_type != GST_SEEK_TYPE_NONE &&
1759 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, stop,
1760 &target_format, &stop)) {
1761 GST_DEBUG_OBJECT (flacdec, "failed to convert stop to DEFAULT format");
1766 flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1769 /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1771 GST_DEBUG_OBJECT (flacdec, "flushing");
1772 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_start ());
1773 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_start ());
1775 /* non flushing seek, pause the task */
1776 GST_DEBUG_OBJECT (flacdec, "stopping task");
1777 gst_pad_stop_task (flacdec->sinkpad);
1780 /* acquire the stream lock, this either happens when the streaming thread
1781 * stopped because of the flush or when the task is paused after the loop
1782 * function finished an iteration, which can never happen when it's blocked
1783 * downstream in PAUSED, for example */
1784 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
1786 /* start seek with clear state to avoid seeking thread pushing segments/data.
1787 * Note current state may have some pending,
1788 * e.g. multi-sink seek leads to immediate subsequent seek events */
1789 if (flacdec->start_segment) {
1790 gst_event_unref (flacdec->start_segment);
1791 flacdec->start_segment = NULL;
1793 gst_buffer_replace (&flacdec->pending, NULL);
1794 flacdec->pending_samples = 0;
1796 /* save a segment copy until we know the seek worked. The idea is that
1797 * when the seek fails, we want to restore with what we were doing. */
1798 segment = flacdec->segment;
1800 /* update the segment with the seek values, last_stop will contain the new
1801 * position we should seek to */
1802 gst_segment_set_seek (&flacdec->segment, rate, GST_FORMAT_DEFAULT,
1803 seek_flags, start_type, start, stop_type, stop, &only_update);
1805 GST_DEBUG_OBJECT (flacdec,
1806 "configured segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT
1807 "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]",
1808 flacdec->segment.start, flacdec->segment.stop,
1809 GST_TIME_ARGS (flacdec->segment.start * GST_SECOND /
1810 flacdec->sample_rate),
1811 GST_TIME_ARGS (flacdec->segment.stop * GST_SECOND /
1812 flacdec->sample_rate));
1814 GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1815 flacdec->segment.last_stop);
1817 /* flush sinkpad again because we need to pull and push buffers while doing
1820 GST_DEBUG_OBJECT (flacdec, "flushing stop");
1821 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_stop ());
1822 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_stop ());
1825 /* mark ourselves as seeking because the above lines will trigger some
1826 * callbacks that need to behave differently when seeking */
1827 flacdec->seeking = TRUE;
1829 GST_LOG_OBJECT (flacdec, "calling seek_absolute");
1830 seek_ok = FLAC__stream_decoder_seek_absolute (flacdec->decoder,
1831 flacdec->segment.last_stop);
1832 GST_LOG_OBJECT (flacdec, "done with seek_absolute, seek_ok=%d", seek_ok);
1834 flacdec->seeking = FALSE;
1836 GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1837 flacdec->segment.last_stop);
1841 GST_WARNING_OBJECT (flacdec, "seek failed");
1842 /* seek failed, restore the segment and start streaming again with
1843 * the previous segment values */
1844 flacdec->segment = segment;
1845 } else if (!flush && flacdec->running) {
1846 /* we are running the current segment and doing a non-flushing seek,
1847 * close the segment first based on the last_stop. */
1848 GST_DEBUG_OBJECT (flacdec, "closing running segment %" G_GINT64_FORMAT
1849 " to %" G_GINT64_FORMAT, segment.start, segment.last_stop);
1851 /* convert the old segment values to time to close the old segment */
1852 start = gst_util_uint64_scale_int (segment.start, GST_SECOND,
1853 flacdec->sample_rate);
1855 gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1856 flacdec->sample_rate);
1858 /* queue the segment for sending in the stream thread, start and time are
1859 * always the same. */
1860 if (flacdec->close_segment)
1861 gst_event_unref (flacdec->close_segment);
1862 flacdec->close_segment =
1863 gst_event_new_new_segment_full (TRUE,
1864 segment.rate, segment.applied_rate, GST_FORMAT_TIME,
1865 start, last_stop, start);
1869 /* seek succeeded, flacdec->segment contains the new positions */
1870 GST_DEBUG_OBJECT (flacdec, "seek successful");
1873 /* convert the (new) segment values to time, we will need them to generate the
1874 * new segment events. */
1875 start = gst_util_uint64_scale_int (flacdec->segment.start, GST_SECOND,
1876 flacdec->sample_rate);
1877 last_stop = gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
1878 flacdec->sample_rate);
1880 /* for deriving a stop position for the playback segment from the seek
1881 * segment, we must take the duration when the stop is not set */
1882 if (flacdec->segment.stop != -1)
1883 stop = gst_util_uint64_scale_int (flacdec->segment.stop, GST_SECOND,
1884 flacdec->sample_rate);
1886 stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
1887 flacdec->sample_rate);
1889 /* notify start of new segment when we were asked to do so. */
1890 if (flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1891 /* last_stop contains the position we start from */
1892 gst_element_post_message (GST_ELEMENT (flacdec),
1893 gst_message_new_segment_start (GST_OBJECT (flacdec),
1894 GST_FORMAT_TIME, last_stop));
1897 /* if the seek was ok or (when it failed) we are flushing, we need to send out
1898 * a new segment. If we did not flush and the seek failed, we simply do
1899 * nothing here and continue where we were. */
1900 if (seek_ok || flush) {
1901 GST_DEBUG_OBJECT (flacdec, "Creating newsegment from %" GST_TIME_FORMAT
1902 " to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop),
1903 GST_TIME_ARGS (stop));
1904 /* now replace the old segment so that we send it in the stream thread the
1905 * next time it is scheduled. */
1906 if (flacdec->start_segment)
1907 gst_event_unref (flacdec->start_segment);
1908 flacdec->start_segment =
1909 gst_event_new_new_segment_full (FALSE,
1910 flacdec->segment.rate, flacdec->segment.applied_rate, GST_FORMAT_TIME,
1911 last_stop, stop, last_stop);
1914 /* we'll generate a discont on the next buffer */
1915 flacdec->discont = TRUE;
1916 /* the task is running again now */
1917 flacdec->running = TRUE;
1918 gst_pad_start_task (flacdec->sinkpad,
1919 (GstTaskFunction) gst_flac_dec_loop, flacdec->sinkpad);
1921 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
1927 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
1929 gboolean res = TRUE;
1930 GstFlacDec *flacdec;
1932 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1934 switch (GST_EVENT_TYPE (event)) {
1935 case GST_EVENT_SEEK:{
1936 GST_DEBUG_OBJECT (flacdec, "received seek event %p", event);
1937 /* first, see if we're before a demuxer that
1938 * might handle the seek for us */
1939 gst_event_ref (event);
1940 res = gst_pad_event_default (pad, event);
1941 /* if not, try to handle it ourselves */
1943 GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
1944 res = gst_flac_dec_handle_seek_event (flacdec, event);
1946 gst_event_unref (event);
1950 res = gst_pad_event_default (pad, event);
1954 gst_object_unref (flacdec);
1960 gst_flac_dec_sink_activate (GstPad * sinkpad)
1962 if (gst_pad_check_pull_range (sinkpad))
1963 return gst_pad_activate_pull (sinkpad, TRUE);
1965 return gst_pad_activate_push (sinkpad, TRUE);
1969 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
1971 GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1974 gst_flac_dec_setup_decoder (dec);
1975 dec->streaming = TRUE;
1981 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
1986 GstFlacDec *flacdec;
1988 flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
1990 flacdec->offset = 0;
1991 gst_flac_dec_setup_decoder (flacdec);
1992 flacdec->running = TRUE;
1993 flacdec->streaming = FALSE;
1995 res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
1998 res = gst_pad_stop_task (sinkpad);
2003 static GstStateChangeReturn
2004 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2006 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2007 GstFlacDec *flacdec = GST_FLAC_DEC (element);
2009 switch (transition) {
2010 case GST_STATE_CHANGE_READY_TO_PAUSED:
2011 flacdec->seeking = FALSE;
2012 flacdec->channels = 0;
2015 flacdec->sample_rate = 0;
2016 gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2022 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2023 if (ret == GST_STATE_CHANGE_FAILURE)
2026 switch (transition) {
2027 case GST_STATE_CHANGE_PAUSED_TO_READY:
2028 gst_segment_init (&flacdec->segment, GST_FORMAT_UNDEFINED);
2029 gst_flac_dec_reset_decoders (flacdec);