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 /* FIXME: This is can be 36 bit if variable block size is used,
440 * fortunately not encoder supports this yet and we check for that
443 val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
445 if (val == (guint32) - 1 || val == (guint32) - 2) {
446 GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
450 headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
451 (bs_from_end / 8) + (sr_from_end / 8);
453 if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
454 GST_LOG_OBJECT (flacdec, "invalid checksum");
458 if (flacdec->min_blocksize == flacdec->max_blocksize) {
459 *last_sample_num = (val + 1) * flacdec->min_blocksize;
461 *last_sample_num = 0; /* FIXME: + length of last block in samples */
464 /* FIXME: only valid for fixed block size streams */
465 GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
468 if (flacdec->sample_rate > 0 && *last_sample_num != 0) {
469 GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
470 GST_TIME_FORMAT, *last_sample_num,
471 GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->sample_rate));
477 #define SCANBLOCK_SIZE (64*1024)
480 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
482 GstFormat format = GST_FORMAT_BYTES;
483 gint64 file_size, offset;
485 GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
487 if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
488 GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
492 if (flacdec->min_blocksize != flacdec->max_blocksize) {
493 GST_WARNING_OBJECT (flacdec, "scanning for last sample only works "
494 "for FLAC files with constant blocksize");
498 GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
500 offset = file_size - 1;
501 while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
503 GstBuffer *buf = NULL;
507 /* divide by 2 = not very sophisticated way to deal with overlapping */
508 offset -= SCANBLOCK_SIZE / 2;
509 GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
510 "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
512 flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
513 if (flow != GST_FLOW_OK) {
514 GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
518 size = GST_BUFFER_SIZE (buf);
519 data = GST_BUFFER_DATA (buf);
522 if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
523 GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
524 offset + GST_BUFFER_SIZE (buf) - size);
525 gst_buffer_unref (buf);
532 gst_buffer_unref (buf);
537 gst_flac_extract_picture_buffer (GstFlacDec * dec,
538 const FLAC__StreamMetadata * metadata)
540 FLAC__StreamMetadata_Picture picture;
543 g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
545 GST_LOG_OBJECT (dec, "Got PICTURE block");
546 picture = metadata->data.picture;
548 GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
549 GST_STR_NULL (picture.mime_type));
550 GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
552 tags = gst_tag_list_new ();
554 gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
555 picture.data_length, picture.type);
557 if (!gst_tag_list_is_empty (tags)) {
558 gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
560 GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
561 gst_tag_list_free (tags);
566 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
567 const FLAC__StreamMetadata * metadata, void *client_data)
569 GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
571 GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
573 switch (metadata->type) {
574 case FLAC__METADATA_TYPE_STREAMINFO:{
578 samples = metadata->data.stream_info.total_samples;
580 flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
581 flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
582 flacdec->sample_rate = metadata->data.stream_info.sample_rate;
583 flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
584 flacdec->channels = metadata->data.stream_info.channels;
593 GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
594 flacdec->min_blocksize, flacdec->max_blocksize);
595 GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
596 flacdec->sample_rate, flacdec->channels);
597 GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
600 /* Only scan for last block in pull-mode, since it uses pull_range() */
601 if (samples == 0 && !flacdec->streaming) {
602 gst_flac_dec_scan_for_last_block (flacdec, &samples);
605 GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
607 /* in framed mode the demuxer/parser upstream has already pushed a
608 * newsegment event in TIME format which we've passed on */
609 if (samples > 0 && !flacdec->framed) {
612 gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
615 /* convert duration to time */
616 duration = gst_util_uint64_scale_int (samples, GST_SECOND,
617 flacdec->sample_rate);
619 /* fixme, at this time we could seek to the queued seek event if we have
621 if (flacdec->start_segment)
622 gst_event_unref (flacdec->start_segment);
623 flacdec->start_segment =
624 gst_event_new_new_segment_full (FALSE,
625 flacdec->segment.rate, flacdec->segment.applied_rate,
626 GST_FORMAT_TIME, 0, duration, 0);
630 case FLAC__METADATA_TYPE_PICTURE:{
631 gst_flac_extract_picture_buffer (flacdec, metadata);
634 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
635 gst_flac_dec_update_metadata (flacdec, metadata);
643 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
644 FLAC__StreamDecoderErrorStatus status, void *client_data)
649 dec = GST_FLAC_DEC (client_data);
652 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
653 /* Ignore this error and keep processing */
655 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
656 error = "bad header";
658 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
659 error = "CRC mismatch";
662 error = "unknown error";
666 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
667 dec->last_flow = GST_FLOW_ERROR;
670 static FLAC__StreamDecoderSeekStatus
671 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
672 FLAC__uint64 position, void *client_data)
676 flacdec = GST_FLAC_DEC (client_data);
678 GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
679 flacdec->offset = position;
681 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
684 static FLAC__StreamDecoderTellStatus
685 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
686 FLAC__uint64 * position, void *client_data)
690 flacdec = GST_FLAC_DEC (client_data);
692 *position = flacdec->offset;
694 GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
696 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
699 static FLAC__StreamDecoderLengthStatus
700 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
701 FLAC__uint64 * length, void *client_data)
704 GstFormat fmt = GST_FORMAT_BYTES;
708 flacdec = GST_FLAC_DEC (client_data);
710 if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
711 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
713 gst_pad_query_duration (peer, &fmt, &len);
714 gst_object_unref (peer);
715 if (fmt != GST_FORMAT_BYTES || len == -1)
716 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
720 GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
723 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
727 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
732 gboolean ret = FALSE;
735 flacdec = GST_FLAC_DEC (client_data);
737 if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
738 GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
742 fmt = GST_FORMAT_BYTES;
743 if (gst_pad_query_duration (peer, &fmt, &len) && fmt == GST_FORMAT_BYTES &&
744 len != -1 && flacdec->offset >= len) {
745 GST_DEBUG_OBJECT (flacdec,
746 "offset=%" G_GINT64_FORMAT ", len=%" G_GINT64_FORMAT
747 ", returning EOF", flacdec->offset, len);
751 gst_object_unref (peer);
756 static FLAC__StreamDecoderReadStatus
757 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
758 FLAC__byte buffer[], size_t * bytes, void *client_data)
764 flacdec = GST_FLAC_DEC (client_data);
766 flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
768 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
769 flacdec->pull_flow = flow;
770 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
772 if (G_UNLIKELY (flow != GST_FLOW_OK)) {
773 GST_INFO_OBJECT (flacdec, "pull_range flow: %s", gst_flow_get_name (flow));
774 if (flow == GST_FLOW_UNEXPECTED)
775 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
777 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
780 GST_DEBUG_OBJECT (flacdec, "Read %d bytes at %" G_GUINT64_FORMAT,
781 GST_BUFFER_SIZE (buf), flacdec->offset);
782 memcpy (buffer, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
783 *bytes = GST_BUFFER_SIZE (buf);
784 gst_buffer_unref (buf);
785 flacdec->offset += *bytes;
787 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
790 static FLAC__StreamDecoderReadStatus
791 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
792 FLAC__byte buffer[], size_t * bytes, void *client_data)
794 GstFlacDec *dec = GST_FLAC_DEC (client_data);
797 len = MIN (gst_adapter_available (dec->adapter), *bytes);
800 GST_LOG_OBJECT (dec, "0 bytes available at the moment");
801 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
804 GST_LOG_OBJECT (dec, "feeding %u bytes to decoder (available=%u, bytes=%u)",
805 len, gst_adapter_available (dec->adapter), (guint) * bytes);
806 gst_adapter_copy (dec->adapter, buffer, 0, len);
809 gst_adapter_flush (dec->adapter, len);
811 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
814 static FLAC__StreamDecoderWriteStatus
815 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
816 const FLAC__int32 * const buffer[])
818 GstFlowReturn ret = GST_FLOW_OK;
820 guint depth = frame->header.bits_per_sample;
822 guint sample_rate = frame->header.sample_rate;
823 guint channels = frame->header.channels;
824 guint samples = frame->header.blocksize;
828 GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
830 /* if a DEFAULT segment is configured, don't send samples past the end
832 if (flacdec->segment.format == GST_FORMAT_DEFAULT &&
833 flacdec->segment.stop != -1 &&
834 flacdec->segment.last_stop >= 0 &&
835 flacdec->segment.last_stop + samples > flacdec->segment.stop) {
836 samples = flacdec->segment.stop - flacdec->segment.last_stop;
837 GST_DEBUG_OBJECT (flacdec,
838 "clipping last buffer to %d samples because of segment", samples);
855 if (flacdec->depth < 4 || flacdec->depth > 32) {
856 GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
858 ret = GST_FLOW_ERROR;
862 depth = flacdec->depth;
872 GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
873 ret = GST_FLOW_ERROR;
877 if (sample_rate == 0) {
878 if (flacdec->sample_rate != 0) {
879 sample_rate = flacdec->sample_rate;
881 GST_ERROR_OBJECT (flacdec, "unknown sample rate");
882 ret = GST_FLOW_ERROR;
887 if (!GST_PAD_CAPS (flacdec->srcpad)) {
890 GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
891 frame->header.sample_rate, channels);
893 caps = gst_caps_new_simple ("audio/x-raw-int",
894 "endianness", G_TYPE_INT, G_BYTE_ORDER,
895 "signed", G_TYPE_BOOLEAN, TRUE,
896 "width", G_TYPE_INT, width,
897 "depth", G_TYPE_INT, depth,
898 "rate", G_TYPE_INT, frame->header.sample_rate,
899 "channels", G_TYPE_INT, channels, NULL);
902 GstStructure *s = gst_caps_get_structure (caps, 0);
904 gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
907 flacdec->depth = depth;
908 flacdec->width = width;
909 flacdec->channels = channels;
910 flacdec->sample_rate = sample_rate;
912 gst_pad_set_caps (flacdec->srcpad, caps);
913 gst_caps_unref (caps);
916 if (flacdec->close_segment) {
917 GST_DEBUG_OBJECT (flacdec, "pushing close segment");
918 gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
919 flacdec->close_segment = NULL;
921 if (flacdec->start_segment) {
922 GST_DEBUG_OBJECT (flacdec, "pushing start segment");
923 gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
924 flacdec->start_segment = NULL;
928 gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
930 flacdec->tags = NULL;
933 if (flacdec->pending) {
934 GST_DEBUG_OBJECT (flacdec,
935 "pushing pending samples at offset %" G_GINT64_FORMAT " (%"
936 GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
937 GST_BUFFER_OFFSET (flacdec->pending),
938 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (flacdec->pending)),
939 GST_TIME_ARGS (GST_BUFFER_DURATION (flacdec->pending)));
940 /* Pending buffer was always allocated from the seeking thread,
941 * which means it wasn't gst_buffer_alloc'd. Do so now to let
942 * downstream negotiation work on older basetransform */
943 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
944 GST_BUFFER_OFFSET (flacdec->pending),
945 GST_BUFFER_SIZE (flacdec->pending),
946 GST_BUFFER_CAPS (flacdec->pending), &outbuf);
947 if (ret == GST_FLOW_OK) {
948 gst_pad_push (flacdec->srcpad, flacdec->pending);
949 gst_buffer_unref (outbuf);
952 outbuf = flacdec->pending = NULL;
953 flacdec->segment.last_stop += flacdec->pending_samples;
954 flacdec->pending_samples = 0;
957 if (flacdec->seeking) {
958 GST_DEBUG_OBJECT (flacdec, "a pad_alloc would block here, do normal alloc");
959 outbuf = gst_buffer_new_and_alloc (samples * channels * (width / 8));
960 gst_buffer_set_caps (outbuf, GST_PAD_CAPS (flacdec->srcpad));
961 GST_BUFFER_OFFSET (outbuf) = flacdec->segment.last_stop;
963 GST_LOG_OBJECT (flacdec, "alloc_buffer_and_set_caps");
964 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
965 flacdec->segment.last_stop, samples * channels * (width / 8),
966 GST_PAD_CAPS (flacdec->srcpad), &outbuf);
968 if (ret != GST_FLOW_OK) {
969 GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
970 gst_flow_get_name (ret));
975 if (flacdec->cur_granulepos != GST_BUFFER_OFFSET_NONE) {
976 /* this should be fine since it should be one flac frame per ogg packet */
977 flacdec->segment.last_stop = flacdec->cur_granulepos - samples;
978 GST_LOG_OBJECT (flacdec, "granulepos = %" G_GINT64_FORMAT ", samples = %u",
979 flacdec->cur_granulepos, samples);
982 GST_BUFFER_TIMESTAMP (outbuf) =
983 gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
984 frame->header.sample_rate);
986 /* get next timestamp to calculate the duration */
987 next = gst_util_uint64_scale_int (flacdec->segment.last_stop + samples,
988 GST_SECOND, frame->header.sample_rate);
990 GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
993 gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
995 for (i = 0; i < samples; i++) {
996 for (j = 0; j < channels; j++) {
997 *outbuffer++ = (gint8) buffer[j][i];
1000 } else if (width == 16) {
1001 gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
1003 for (i = 0; i < samples; i++) {
1004 for (j = 0; j < channels; j++) {
1005 *outbuffer++ = (gint16) buffer[j][i];
1008 } else if (width == 32) {
1009 gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
1011 for (i = 0; i < samples; i++) {
1012 for (j = 0; j < channels; j++) {
1013 *outbuffer++ = (gint32) buffer[j][i];
1017 g_assert_not_reached ();
1020 if (!flacdec->seeking) {
1021 GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
1022 " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
1023 samples, GST_BUFFER_OFFSET (outbuf),
1024 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1025 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1027 if (flacdec->discont) {
1028 GST_DEBUG_OBJECT (flacdec, "marking discont");
1029 outbuf = gst_buffer_make_metadata_writable (outbuf);
1030 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1031 flacdec->discont = FALSE;
1033 ret = gst_pad_push (flacdec->srcpad, outbuf);
1034 GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
1035 flacdec->segment.last_stop += samples;
1037 GST_DEBUG_OBJECT (flacdec,
1038 "not pushing %d samples at offset %" G_GINT64_FORMAT
1039 " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
1040 gst_buffer_replace (&flacdec->pending, outbuf);
1041 gst_buffer_unref (outbuf);
1042 flacdec->pending_samples = samples;
1046 if (ret != GST_FLOW_OK) {
1047 GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1048 gst_flow_get_name (ret));
1054 /* we act on the flow return value later in the loop function, as we don't
1055 * want to mess up the internal decoder state by returning ABORT when the
1056 * error is in fact non-fatal (like a pad in flushing mode) and we want
1057 * to continue later. So just pretend everything's dandy and act later. */
1058 flacdec->last_flow = ret;
1060 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1063 static FLAC__StreamDecoderWriteStatus
1064 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
1065 const FLAC__Frame * frame,
1066 const FLAC__int32 * const buffer[], void *client_data)
1068 return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1072 gst_flac_dec_loop (GstPad * sinkpad)
1074 GstFlacDec *flacdec;
1075 FLAC__StreamDecoderState s;
1076 FLAC__StreamDecoderInitStatus is;
1078 flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1080 GST_LOG_OBJECT (flacdec, "entering loop");
1083 GST_DEBUG_OBJECT (flacdec, "Seeked after end of file");
1085 if (flacdec->close_segment) {
1086 GST_DEBUG_OBJECT (flacdec, "pushing close segment");
1087 gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
1088 flacdec->close_segment = NULL;
1090 if (flacdec->start_segment) {
1091 GST_DEBUG_OBJECT (flacdec, "pushing start segment");
1092 gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
1093 flacdec->start_segment = NULL;
1096 if (flacdec->tags) {
1097 gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
1099 flacdec->tags = NULL;
1102 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1105 goto segment_done_and_pause;
1109 if (flacdec->init) {
1110 GST_DEBUG_OBJECT (flacdec, "initializing new decoder");
1111 is = FLAC__stream_decoder_init_stream (flacdec->decoder,
1112 gst_flac_dec_read_seekable, gst_flac_dec_seek, gst_flac_dec_tell,
1113 gst_flac_dec_length, gst_flac_dec_eof, gst_flac_dec_write_stream,
1114 gst_flac_dec_metadata_cb, gst_flac_dec_error_cb, flacdec);
1115 if (is != FLAC__STREAM_DECODER_INIT_STATUS_OK)
1118 /* FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1119 flacdec->init = FALSE;
1122 flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1124 flacdec->last_flow = GST_FLOW_OK;
1126 GST_LOG_OBJECT (flacdec, "processing single");
1127 FLAC__stream_decoder_process_single (flacdec->decoder);
1131 GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1132 s = FLAC__stream_decoder_get_state (flacdec->decoder);
1134 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
1135 case FLAC__STREAM_DECODER_READ_METADATA:
1136 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
1137 case FLAC__STREAM_DECODER_READ_FRAME:
1139 GST_DEBUG_OBJECT (flacdec, "everything ok");
1141 if (flacdec->last_flow < GST_FLOW_UNEXPECTED ||
1142 flacdec->last_flow == GST_FLOW_NOT_LINKED) {
1143 GST_ELEMENT_ERROR (flacdec, STREAM, FAILED,
1144 (_("Internal data stream error.")),
1145 ("stream stopped, reason %s",
1146 gst_flow_get_name (flacdec->last_flow)));
1148 } else if (flacdec->last_flow == GST_FLOW_UNEXPECTED) {
1150 } else if (flacdec->last_flow != GST_FLOW_OK) {
1154 /* check if we're at the end of a configured segment */
1155 if (flacdec->segment.stop != -1 &&
1156 flacdec->segment.last_stop > 0 &&
1157 flacdec->segment.last_stop >= flacdec->segment.stop) {
1158 GST_DEBUG_OBJECT (flacdec, "reached end of the configured segment");
1160 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1163 goto segment_done_and_pause;
1166 g_assert_not_reached ();
1172 case FLAC__STREAM_DECODER_END_OF_STREAM:{
1173 GST_DEBUG_OBJECT (flacdec, "EOS");
1174 FLAC__stream_decoder_reset (flacdec->decoder);
1176 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1177 if (flacdec->segment.duration > 0) {
1178 flacdec->segment.stop = flacdec->segment.duration;
1180 flacdec->segment.stop = flacdec->segment.last_stop;
1182 goto segment_done_and_pause;
1188 /* gst_flac_dec_read_seekable() returned ABORTED */
1189 case FLAC__STREAM_DECODER_ABORTED:
1191 GST_INFO_OBJECT (flacdec, "read aborted: last pull_range flow = %s",
1192 gst_flow_get_name (flacdec->pull_flow));
1193 if (flacdec->pull_flow == GST_FLOW_WRONG_STATE) {
1194 /* it seems we need to flush the decoder here to reset the decoder
1195 * state after the abort for FLAC__stream_decoder_seek_absolute()
1196 * to work properly */
1197 GST_DEBUG_OBJECT (flacdec, "flushing decoder to reset decoder state");
1198 FLAC__stream_decoder_flush (flacdec->decoder);
1203 case FLAC__STREAM_DECODER_OGG_ERROR:
1204 case FLAC__STREAM_DECODER_SEEK_ERROR:
1205 case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
1206 case FLAC__STREAM_DECODER_UNINITIALIZED:
1208 /* fixme: this error sucks -- should try to figure out when/if an more
1209 specific error was already sent via the callback */
1210 GST_ELEMENT_ERROR (flacdec, STREAM, DECODE, (NULL),
1211 ("%s", FLAC__StreamDecoderStateString[s]));
1218 segment_done_and_pause:
1222 stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1223 GST_SECOND, flacdec->sample_rate);
1225 GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1226 GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1228 gst_element_post_message (GST_ELEMENT (flacdec),
1229 gst_message_new_segment_done (GST_OBJECT (flacdec),
1230 GST_FORMAT_TIME, stop_time));
1236 GST_DEBUG_OBJECT (flacdec, "sending EOS event");
1237 flacdec->running = FALSE;
1238 gst_pad_push_event (flacdec->srcpad, gst_event_new_eos ());
1239 /* fall through to pause */
1243 GST_DEBUG_OBJECT (flacdec, "pausing");
1244 gst_pad_pause_task (sinkpad);
1250 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1255 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1257 switch (GST_EVENT_TYPE (event)) {
1258 case GST_EVENT_FLUSH_STOP:{
1259 if (dec->init == FALSE) {
1260 FLAC__stream_decoder_flush (dec->decoder);
1261 gst_adapter_clear (dec->adapter);
1263 res = gst_pad_push_event (dec->srcpad, event);
1266 case GST_EVENT_NEWSEGMENT:{
1269 gdouble rate, applied_rate;
1270 gint64 cur, stop, time;
1272 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1273 &fmt, &cur, &stop, &time);
1275 if (fmt == GST_FORMAT_TIME) {
1276 GstFormat dformat = GST_FORMAT_DEFAULT;
1278 GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1280 res = gst_pad_push_event (dec->srcpad, event);
1282 /* this won't work for the first newsegment event though ... */
1283 if (gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, cur,
1284 &dformat, &cur) && cur != -1 &&
1285 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, stop,
1286 &dformat, &stop) && stop != -1) {
1287 gst_segment_set_newsegment_full (&dec->segment, update, rate,
1288 applied_rate, dformat, cur, stop, time);
1289 GST_DEBUG_OBJECT (dec, "segment %" GST_SEGMENT_FORMAT, &dec->segment);
1291 GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1293 } else if (fmt == GST_FORMAT_BYTES || TRUE) {
1294 GST_DEBUG_OBJECT (dec, "newsegment event in %s format => not framed",
1295 gst_format_get_name (fmt));
1296 dec->framed = FALSE;
1298 /* prepare generic newsegment event, for some reason our metadata
1299 * callback where we usually set this up is not being called in
1301 if (dec->start_segment)
1302 gst_event_unref (dec->start_segment);
1303 dec->start_segment = gst_event_new_new_segment (FALSE, 1.0,
1304 GST_FORMAT_TIME, 0, -1, 0);
1306 gst_event_unref (event);
1311 case GST_EVENT_EOS:{
1312 GST_LOG_OBJECT (dec, "EOS, with %u bytes available in adapter",
1313 gst_adapter_available (dec->adapter));
1314 if (dec->init == FALSE) {
1315 if (gst_adapter_available (dec->adapter) > 0) {
1316 FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
1318 FLAC__stream_decoder_flush (dec->decoder);
1320 gst_adapter_clear (dec->adapter);
1321 res = gst_pad_push_event (dec->srcpad, event);
1325 res = gst_pad_event_default (pad, event);
1329 gst_object_unref (dec);
1335 gst_flac_dec_chain_parse_headers (GstFlacDec * dec)
1340 avail = gst_adapter_available (dec->adapter);
1344 gst_adapter_copy (dec->adapter, marker, 0, 4);
1345 if (strncmp ((const gchar *) marker, "fLaC", 4) != 0) {
1346 GST_ERROR_OBJECT (dec, "Unexpected header, expected fLaC header");
1347 return TRUE; /* abort header parsing */
1350 GST_DEBUG_OBJECT (dec, "fLaC header : len 4 @ %7u", 0);
1353 while (avail > (off + 1 + 3)) {
1356 guint len, block_type;
1358 gst_adapter_copy (dec->adapter, mb_hdr, off, 4);
1360 is_last = ((mb_hdr[0] & 0x80) == 0x80);
1361 block_type = mb_hdr[0] & 0x7f;
1362 len = GST_READ_UINT24_BE (mb_hdr + 1);
1363 GST_DEBUG_OBJECT (dec, "Metadata block type %u: len %7u + 4 @ %7u%s",
1364 block_type, len, off, (is_last) ? " (last)" : "");
1371 GST_LOG_OBJECT (dec, "Need more data: next offset %u > avail %u", off,
1377 /* want metadata blocks plus at least one frame */
1378 return (off + FLAC__MAX_BLOCK_SIZE >= avail);
1381 static GstFlowReturn
1382 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1384 FLAC__StreamDecoderInitStatus s;
1386 gboolean got_audio_frame;
1388 dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1390 GST_LOG_OBJECT (dec, "buffer with ts=%" GST_TIME_FORMAT ", end_offset=%"
1391 G_GINT64_FORMAT ", size=%u", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1392 GST_BUFFER_OFFSET_END (buf), GST_BUFFER_SIZE (buf));
1395 GST_DEBUG_OBJECT (dec, "initializing decoder");
1396 s = FLAC__stream_decoder_init_stream (dec->decoder,
1397 gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
1398 gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
1399 gst_flac_dec_error_cb, dec);
1400 if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1401 GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
1402 return GST_FLOW_ERROR;
1404 GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1406 } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1407 /* Clear the adapter and the decoder */
1408 gst_adapter_clear (dec->adapter);
1409 FLAC__stream_decoder_flush (dec->decoder);
1415 /* check if this is a flac audio frame (rather than a header or junk) */
1416 got_audio_frame = gst_flac_dec_scan_got_frame (dec, GST_BUFFER_DATA (buf),
1417 GST_BUFFER_SIZE (buf), &unused);
1419 /* oggdemux will set granulepos in OFFSET_END instead of timestamp */
1420 if (G_LIKELY (got_audio_frame)) {
1421 /* old oggdemux for now */
1422 if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1423 dec->cur_granulepos = GST_BUFFER_OFFSET_END (buf);
1425 GstFormat dformat = GST_FORMAT_DEFAULT;
1427 /* upstream (e.g. demuxer) presents us time,
1428 * convert to default samples */
1429 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME,
1430 GST_BUFFER_TIMESTAMP (buf), &dformat, &dec->segment.last_stop);
1431 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1435 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1436 got_audio_frame = TRUE;
1439 gst_adapter_push (dec->adapter, buf);
1442 dec->last_flow = GST_FLOW_OK;
1445 if (G_UNLIKELY (!dec->got_headers)) {
1446 if (!gst_flac_dec_chain_parse_headers (dec)) {
1447 GST_LOG_OBJECT (dec, "don't have metadata blocks yet, need more data");
1450 GST_INFO_OBJECT (dec, "have all metadata blocks now");
1451 dec->got_headers = TRUE;
1454 /* wait until we have at least 64kB because libflac's StreamDecoder
1455 * interface is a bit dumb it seems (if we don't have as much data as
1456 * it wants it will call our read callback repeatedly and the only
1457 * way to stop that is to error out or EOS, which will affect the
1458 * decoder state). And the decoder seems to always ask for MAX_BLOCK_SIZE
1459 * bytes rather than the max. block size from the header). Requiring
1460 * MAX_BLOCK_SIZE bytes here should make sure it always gets enough data
1461 * to decode at least one block */
1462 while (gst_adapter_available (dec->adapter) >= FLAC__MAX_BLOCK_SIZE &&
1463 dec->last_flow == GST_FLOW_OK) {
1464 GST_LOG_OBJECT (dec, "%u bytes available",
1465 gst_adapter_available (dec->adapter));
1466 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1467 GST_DEBUG_OBJECT (dec, "process_single failed");
1471 if (FLAC__stream_decoder_get_state (dec->decoder) ==
1472 FLAC__STREAM_DECODER_ABORTED) {
1473 GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
1474 dec->last_flow = GST_FLOW_ERROR;
1478 } else if (dec->framed && got_audio_frame) {
1479 /* framed - there should always be enough data to decode something */
1480 GST_LOG_OBJECT (dec, "%u bytes available",
1481 gst_adapter_available (dec->adapter));
1482 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1483 GST_DEBUG_OBJECT (dec, "process_single failed");
1486 GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1491 return dec->last_flow;
1495 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1496 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1498 gboolean res = TRUE;
1500 if (dec->width == 0 || dec->channels == 0 || dec->sample_rate == 0) {
1501 /* no frame decoded yet */
1502 GST_DEBUG_OBJECT (dec, "cannot convert: not set up yet");
1506 switch (src_format) {
1507 case GST_FORMAT_BYTES:{
1511 case GST_FORMAT_DEFAULT:
1512 switch (*dest_format) {
1513 case GST_FORMAT_BYTES:
1516 case GST_FORMAT_TIME:
1517 /* granulepos = sample */
1518 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1526 case GST_FORMAT_TIME:
1527 switch (*dest_format) {
1528 case GST_FORMAT_BYTES:
1531 case GST_FORMAT_DEFAULT:
1532 *dest_value = gst_util_uint64_scale_int (src_value,
1533 dec->sample_rate, GST_SECOND);
1547 static const GstQueryType *
1548 gst_flac_dec_get_sink_query_types (GstPad * pad)
1550 static const GstQueryType types[] = {
1559 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1562 gboolean res = FALSE;
1564 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1566 GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1568 switch (GST_QUERY_TYPE (query)) {
1569 case GST_QUERY_CONVERT:{
1570 GstFormat src_fmt, dest_fmt;
1572 gint64 src_val, dest_val;
1574 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1576 res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1580 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1582 GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1587 res = gst_pad_query_default (pad, query);
1592 gst_object_unref (dec);
1597 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1598 GstFormat * dest_format, gint64 * dest_value)
1600 GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1601 gboolean res = TRUE;
1602 guint bytes_per_sample;
1605 if (flacdec->width == 0 || flacdec->channels == 0 ||
1606 flacdec->sample_rate == 0) {
1607 /* no frame decoded yet */
1608 GST_DEBUG_OBJECT (flacdec, "cannot convert: not set up yet");
1612 bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1614 switch (src_format) {
1615 case GST_FORMAT_BYTES:{
1616 switch (*dest_format) {
1617 case GST_FORMAT_DEFAULT:
1619 gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1621 case GST_FORMAT_TIME:
1623 gint byterate = bytes_per_sample * flacdec->sample_rate;
1625 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1634 case GST_FORMAT_DEFAULT:
1635 switch (*dest_format) {
1636 case GST_FORMAT_BYTES:
1637 *dest_value = src_value * bytes_per_sample;
1639 case GST_FORMAT_TIME:
1640 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1641 flacdec->sample_rate);
1647 case GST_FORMAT_TIME:
1648 switch (*dest_format) {
1649 case GST_FORMAT_BYTES:
1650 scale = bytes_per_sample;
1651 case GST_FORMAT_DEFAULT:
1652 *dest_value = gst_util_uint64_scale_int (src_value,
1653 scale * flacdec->sample_rate, GST_SECOND);
1665 static const GstQueryType *
1666 gst_flac_dec_get_src_query_types (GstPad * pad)
1668 static const GstQueryType types[] = {
1680 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1682 GstFlacDec *flacdec;
1683 gboolean res = TRUE;
1686 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1687 peer = gst_pad_get_peer (flacdec->sinkpad);
1689 switch (GST_QUERY_TYPE (query)) {
1690 case GST_QUERY_POSITION:{
1694 gst_query_parse_position (query, &fmt, NULL);
1696 /* there might be a demuxer in front of us who can handle this */
1697 if (fmt == GST_FORMAT_TIME && (res = gst_pad_query (peer, query)))
1700 if (fmt != GST_FORMAT_DEFAULT) {
1701 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1702 flacdec->segment.last_stop, &fmt, &pos)) {
1703 GST_DEBUG_OBJECT (flacdec, "failed to convert position into %s "
1704 "format", gst_format_get_name (fmt));
1709 pos = flacdec->segment.last_stop;
1712 gst_query_set_position (query, fmt, pos);
1714 GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1715 " (format: %s)", pos, gst_format_get_name (fmt));
1721 case GST_QUERY_DURATION:{
1725 gst_query_parse_duration (query, &fmt, NULL);
1727 /* try any demuxers before us first */
1728 if (fmt == GST_FORMAT_TIME && peer && gst_pad_query (peer, query)) {
1729 gst_query_parse_duration (query, NULL, &len);
1730 GST_DEBUG_OBJECT (flacdec, "peer returned duration %" GST_TIME_FORMAT,
1731 GST_TIME_ARGS (len));
1736 if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1737 GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1742 /* convert total number of samples to request format */
1743 if (fmt != GST_FORMAT_DEFAULT) {
1744 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1745 flacdec->segment.duration, &fmt, &len)) {
1746 GST_DEBUG_OBJECT (flacdec, "failed to convert duration into %s "
1747 "format", gst_format_get_name (fmt));
1752 len = flacdec->segment.duration;
1755 gst_query_set_duration (query, fmt, len);
1757 GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1758 " (format: %s)", len, gst_format_get_name (fmt));
1764 case GST_QUERY_CONVERT:{
1765 GstFormat src_fmt, dest_fmt;
1766 gint64 src_val, dest_val;
1768 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1770 res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1774 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1779 case GST_QUERY_SEEKING:{
1781 gboolean seekable = FALSE;
1784 /* If upstream can handle the query we're done */
1785 seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1787 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1791 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1792 if ((fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT) ||
1793 flacdec->streaming) {
1794 gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1796 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1802 res = gst_pad_query_default (pad, query);
1810 gst_object_unref (peer);
1812 gst_object_unref (flacdec);
1818 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1821 GstSeekFlags seek_flags;
1822 GstSeekType start_type;
1823 GstSeekType stop_type;
1825 GstFormat seek_format;
1826 gboolean only_update = FALSE;
1829 gint64 start, last_stop;
1832 if (flacdec->streaming) {
1833 GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1837 gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1838 &start, &stop_type, &stop);
1840 if (seek_format != GST_FORMAT_DEFAULT && seek_format != GST_FORMAT_TIME) {
1841 GST_DEBUG_OBJECT (flacdec,
1842 "seeking is only supported in TIME or DEFAULT format");
1847 GST_DEBUG_OBJECT (flacdec,
1848 "only forward playback supported, rate %f not allowed", rate);
1852 if (seek_format != GST_FORMAT_DEFAULT) {
1853 GstFormat target_format = GST_FORMAT_DEFAULT;
1855 if (start_type != GST_SEEK_TYPE_NONE &&
1856 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, start,
1857 &target_format, &start)) {
1858 GST_DEBUG_OBJECT (flacdec, "failed to convert start to DEFAULT format");
1862 if (stop_type != GST_SEEK_TYPE_NONE &&
1863 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, stop,
1864 &target_format, &stop)) {
1865 GST_DEBUG_OBJECT (flacdec, "failed to convert stop to DEFAULT format");
1870 /* Check if we seeked after the end of file */
1871 if (start_type != GST_SEEK_TYPE_NONE && flacdec->segment.duration > 0 &&
1872 start >= flacdec->segment.duration) {
1873 flacdec->eos = TRUE;
1875 flacdec->eos = FALSE;
1878 flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1881 /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1883 GST_DEBUG_OBJECT (flacdec, "flushing");
1884 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_start ());
1885 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_start ());
1887 /* non flushing seek, pause the task */
1888 GST_DEBUG_OBJECT (flacdec, "stopping task");
1889 gst_pad_stop_task (flacdec->sinkpad);
1892 /* acquire the stream lock, this either happens when the streaming thread
1893 * stopped because of the flush or when the task is paused after the loop
1894 * function finished an iteration, which can never happen when it's blocked
1895 * downstream in PAUSED, for example */
1896 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
1898 /* start seek with clear state to avoid seeking thread pushing segments/data.
1899 * Note current state may have some pending,
1900 * e.g. multi-sink seek leads to immediate subsequent seek events */
1901 if (flacdec->start_segment) {
1902 gst_event_unref (flacdec->start_segment);
1903 flacdec->start_segment = NULL;
1905 gst_buffer_replace (&flacdec->pending, NULL);
1906 flacdec->pending_samples = 0;
1908 /* save a segment copy until we know the seek worked. The idea is that
1909 * when the seek fails, we want to restore with what we were doing. */
1910 segment = flacdec->segment;
1912 /* update the segment with the seek values, last_stop will contain the new
1913 * position we should seek to */
1914 gst_segment_set_seek (&flacdec->segment, rate, GST_FORMAT_DEFAULT,
1915 seek_flags, start_type, start, stop_type, stop, &only_update);
1917 GST_DEBUG_OBJECT (flacdec,
1918 "configured segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT
1919 "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]",
1920 flacdec->segment.start, flacdec->segment.stop,
1921 GST_TIME_ARGS (flacdec->segment.start * GST_SECOND /
1922 flacdec->sample_rate),
1923 GST_TIME_ARGS (flacdec->segment.stop * GST_SECOND /
1924 flacdec->sample_rate));
1926 GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1927 flacdec->segment.last_stop);
1929 /* flush sinkpad again because we need to pull and push buffers while doing
1932 GST_DEBUG_OBJECT (flacdec, "flushing stop");
1933 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_stop ());
1934 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_stop ());
1937 /* mark ourselves as seeking because the above lines will trigger some
1938 * callbacks that need to behave differently when seeking */
1939 flacdec->seeking = TRUE;
1941 if (!flacdec->eos) {
1942 GST_LOG_OBJECT (flacdec, "calling seek_absolute");
1943 seek_ok = FLAC__stream_decoder_seek_absolute (flacdec->decoder,
1944 flacdec->segment.last_stop);
1945 GST_LOG_OBJECT (flacdec, "done with seek_absolute, seek_ok=%d", seek_ok);
1947 GST_LOG_OBJECT (flacdec, "not seeking, seeked after end of file");
1951 flacdec->seeking = FALSE;
1953 GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1954 flacdec->segment.last_stop);
1957 GST_WARNING_OBJECT (flacdec, "seek failed");
1958 /* seek failed, restore the segment and start streaming again with
1959 * the previous segment values */
1960 flacdec->segment = segment;
1961 } else if (!flush && flacdec->running) {
1962 /* we are running the current segment and doing a non-flushing seek,
1963 * close the segment first based on the last_stop. */
1964 GST_DEBUG_OBJECT (flacdec, "closing running segment %" G_GINT64_FORMAT
1965 " to %" G_GINT64_FORMAT, segment.start, segment.last_stop);
1967 /* convert the old segment values to time to close the old segment */
1968 start = gst_util_uint64_scale_int (segment.start, GST_SECOND,
1969 flacdec->sample_rate);
1971 gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1972 flacdec->sample_rate);
1974 /* queue the segment for sending in the stream thread, start and time are
1975 * always the same. */
1976 if (flacdec->close_segment)
1977 gst_event_unref (flacdec->close_segment);
1978 flacdec->close_segment =
1979 gst_event_new_new_segment_full (TRUE,
1980 segment.rate, segment.applied_rate, GST_FORMAT_TIME,
1981 start, last_stop, start);
1985 /* seek succeeded, flacdec->segment contains the new positions */
1986 GST_DEBUG_OBJECT (flacdec, "seek successful");
1989 /* convert the (new) segment values to time, we will need them to generate the
1990 * new segment events. */
1991 start = gst_util_uint64_scale_int (flacdec->segment.start, GST_SECOND,
1992 flacdec->sample_rate);
1993 last_stop = gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
1994 flacdec->sample_rate);
1996 /* for deriving a stop position for the playback segment from the seek
1997 * segment, we must take the duration when the stop is not set */
1998 if (flacdec->segment.stop != -1)
1999 stop = gst_util_uint64_scale_int (flacdec->segment.stop, GST_SECOND,
2000 flacdec->sample_rate);
2002 stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
2003 flacdec->sample_rate);
2005 /* notify start of new segment when we were asked to do so. */
2006 if (flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2007 /* last_stop contains the position we start from */
2008 gst_element_post_message (GST_ELEMENT (flacdec),
2009 gst_message_new_segment_start (GST_OBJECT (flacdec),
2010 GST_FORMAT_TIME, last_stop));
2013 /* if the seek was ok or (when it failed) we are flushing, we need to send out
2014 * a new segment. If we did not flush and the seek failed, we simply do
2015 * nothing here and continue where we were. */
2016 if (seek_ok || flush) {
2017 GST_DEBUG_OBJECT (flacdec, "Creating newsegment from %" GST_TIME_FORMAT
2018 " to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop),
2019 GST_TIME_ARGS (stop));
2020 /* now replace the old segment so that we send it in the stream thread the
2021 * next time it is scheduled. */
2022 if (flacdec->start_segment)
2023 gst_event_unref (flacdec->start_segment);
2024 flacdec->start_segment =
2025 gst_event_new_new_segment_full (FALSE,
2026 flacdec->segment.rate, flacdec->segment.applied_rate, GST_FORMAT_TIME,
2027 last_stop, stop, last_stop);
2030 /* we'll generate a discont on the next buffer */
2031 flacdec->discont = TRUE;
2032 /* the task is running again now */
2033 flacdec->running = TRUE;
2034 gst_pad_start_task (flacdec->sinkpad,
2035 (GstTaskFunction) gst_flac_dec_loop, flacdec->sinkpad);
2037 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
2043 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
2045 gboolean res = TRUE;
2046 GstFlacDec *flacdec;
2048 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
2050 switch (GST_EVENT_TYPE (event)) {
2051 case GST_EVENT_SEEK:{
2052 GST_DEBUG_OBJECT (flacdec, "received seek event %p", event);
2053 /* first, see if we're before a demuxer that
2054 * might handle the seek for us */
2055 gst_event_ref (event);
2056 res = gst_pad_event_default (pad, event);
2057 /* if not, try to handle it ourselves */
2059 GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
2060 res = gst_flac_dec_handle_seek_event (flacdec, event);
2062 gst_event_unref (event);
2066 res = gst_pad_event_default (pad, event);
2070 gst_object_unref (flacdec);
2076 gst_flac_dec_sink_activate (GstPad * sinkpad)
2078 if (gst_pad_check_pull_range (sinkpad))
2079 return gst_pad_activate_pull (sinkpad, TRUE);
2081 return gst_pad_activate_push (sinkpad, TRUE);
2085 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
2087 GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
2090 gst_flac_dec_setup_decoder (dec);
2091 dec->streaming = TRUE;
2092 dec->got_headers = FALSE;
2098 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
2103 GstFlacDec *flacdec;
2105 flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
2107 flacdec->offset = 0;
2108 gst_flac_dec_setup_decoder (flacdec);
2109 flacdec->running = TRUE;
2110 flacdec->streaming = FALSE;
2112 res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
2115 res = gst_pad_stop_task (sinkpad);
2120 static GstStateChangeReturn
2121 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2123 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2124 GstFlacDec *flacdec = GST_FLAC_DEC (element);
2126 switch (transition) {
2127 case GST_STATE_CHANGE_READY_TO_PAUSED:
2128 flacdec->eos = FALSE;
2129 flacdec->seeking = FALSE;
2130 flacdec->channels = 0;
2133 flacdec->sample_rate = 0;
2134 gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2140 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2141 if (ret == GST_STATE_CHANGE_FAILURE)
2144 switch (transition) {
2145 case GST_STATE_CHANGE_PAUSED_TO_READY:
2146 gst_segment_init (&flacdec->segment, GST_FORMAT_UNDEFINED);
2147 gst_flac_dec_reset_decoders (flacdec);