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] & 0xFC) != 0xF8)
414 GST_WARNING_OBJECT (flacdec, "Variable block size FLAC unsupported");
418 bs = (data[2] & 0xF0) >> 4; /* blocksize marker */
419 sr = (data[2] & 0x0F); /* samplerate marker */
420 ca = (data[3] & 0xF0) >> 4; /* channel assignment */
421 ss = (data[3] & 0x0F) >> 1; /* sample size marker */
422 pb = (data[3] & 0x01); /* padding bit */
424 GST_LOG_OBJECT (flacdec,
425 "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
427 if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
431 /* read block size from end of header? */
437 /* read sample rate from end of header? */
440 else if (sr == 0x0D || sr == 0x0E)
443 /* FIXME: This is can be 36 bit if variable block size is used,
444 * fortunately not encoder supports this yet and we check for that
447 val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
449 if (val == (guint32) - 1 || val == (guint32) - 2) {
450 GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
454 headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
455 (bs_from_end / 8) + (sr_from_end / 8);
457 if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
458 GST_LOG_OBJECT (flacdec, "invalid checksum");
462 if (flacdec->min_blocksize == flacdec->max_blocksize) {
463 *last_sample_num = (val + 1) * flacdec->min_blocksize;
465 *last_sample_num = 0; /* FIXME: + length of last block in samples */
468 /* FIXME: only valid for fixed block size streams */
469 GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
472 if (flacdec->sample_rate > 0 && *last_sample_num != 0) {
473 GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
474 GST_TIME_FORMAT, *last_sample_num,
475 GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->sample_rate));
481 #define SCANBLOCK_SIZE (64*1024)
484 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
486 GstFormat format = GST_FORMAT_BYTES;
487 gint64 file_size, offset;
489 GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
491 if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
492 GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
496 if (flacdec->min_blocksize != flacdec->max_blocksize) {
497 GST_WARNING_OBJECT (flacdec, "scanning for last sample only works "
498 "for FLAC files with constant blocksize");
502 GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
504 offset = file_size - 1;
505 while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
507 GstBuffer *buf = NULL;
511 /* divide by 2 = not very sophisticated way to deal with overlapping */
512 offset -= SCANBLOCK_SIZE / 2;
513 GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
514 "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
516 flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
517 if (flow != GST_FLOW_OK) {
518 GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
522 size = GST_BUFFER_SIZE (buf);
523 data = GST_BUFFER_DATA (buf);
526 if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
527 GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
528 offset + GST_BUFFER_SIZE (buf) - size);
529 gst_buffer_unref (buf);
536 gst_buffer_unref (buf);
541 gst_flac_extract_picture_buffer (GstFlacDec * dec,
542 const FLAC__StreamMetadata * metadata)
544 FLAC__StreamMetadata_Picture picture;
547 g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
549 GST_LOG_OBJECT (dec, "Got PICTURE block");
550 picture = metadata->data.picture;
552 GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
553 GST_STR_NULL (picture.mime_type));
554 GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
556 tags = gst_tag_list_new ();
558 gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
559 picture.data_length, picture.type);
561 if (!gst_tag_list_is_empty (tags)) {
562 gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
564 GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
565 gst_tag_list_free (tags);
570 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
571 const FLAC__StreamMetadata * metadata, void *client_data)
573 GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
575 GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
577 switch (metadata->type) {
578 case FLAC__METADATA_TYPE_STREAMINFO:{
582 samples = metadata->data.stream_info.total_samples;
584 flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
585 flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
586 flacdec->sample_rate = metadata->data.stream_info.sample_rate;
587 flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
588 flacdec->channels = metadata->data.stream_info.channels;
597 GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
598 flacdec->min_blocksize, flacdec->max_blocksize);
599 GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
600 flacdec->sample_rate, flacdec->channels);
601 GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
604 /* Only scan for last block in pull-mode, since it uses pull_range() */
605 if (samples == 0 && !flacdec->streaming) {
606 gst_flac_dec_scan_for_last_block (flacdec, &samples);
609 GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
611 /* in framed mode the demuxer/parser upstream has already pushed a
612 * newsegment event in TIME format which we've passed on */
613 if (samples > 0 && !flacdec->framed) {
616 gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
619 /* convert duration to time */
620 duration = gst_util_uint64_scale_int (samples, GST_SECOND,
621 flacdec->sample_rate);
623 /* fixme, at this time we could seek to the queued seek event if we have
625 if (flacdec->start_segment)
626 gst_event_unref (flacdec->start_segment);
627 flacdec->start_segment =
628 gst_event_new_new_segment_full (FALSE,
629 flacdec->segment.rate, flacdec->segment.applied_rate,
630 GST_FORMAT_TIME, 0, duration, 0);
634 case FLAC__METADATA_TYPE_PICTURE:{
635 gst_flac_extract_picture_buffer (flacdec, metadata);
638 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
639 gst_flac_dec_update_metadata (flacdec, metadata);
647 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
648 FLAC__StreamDecoderErrorStatus status, void *client_data)
653 dec = GST_FLAC_DEC (client_data);
656 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
657 /* Ignore this error and keep processing */
659 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
660 error = "bad header";
662 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
663 error = "CRC mismatch";
666 error = "unknown error";
670 GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
671 dec->last_flow = GST_FLOW_ERROR;
674 static FLAC__StreamDecoderSeekStatus
675 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
676 FLAC__uint64 position, void *client_data)
680 flacdec = GST_FLAC_DEC (client_data);
682 GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
683 flacdec->offset = position;
685 return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
688 static FLAC__StreamDecoderTellStatus
689 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
690 FLAC__uint64 * position, void *client_data)
694 flacdec = GST_FLAC_DEC (client_data);
696 *position = flacdec->offset;
698 GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
700 return FLAC__STREAM_DECODER_TELL_STATUS_OK;
703 static FLAC__StreamDecoderLengthStatus
704 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
705 FLAC__uint64 * length, void *client_data)
708 GstFormat fmt = GST_FORMAT_BYTES;
712 flacdec = GST_FLAC_DEC (client_data);
714 if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
715 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
717 gst_pad_query_duration (peer, &fmt, &len);
718 gst_object_unref (peer);
719 if (fmt != GST_FORMAT_BYTES || len == -1)
720 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
724 GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
727 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
731 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
736 gboolean ret = FALSE;
739 flacdec = GST_FLAC_DEC (client_data);
741 if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
742 GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
746 fmt = GST_FORMAT_BYTES;
747 if (gst_pad_query_duration (peer, &fmt, &len) && fmt == GST_FORMAT_BYTES &&
748 len != -1 && flacdec->offset >= len) {
749 GST_DEBUG_OBJECT (flacdec,
750 "offset=%" G_GINT64_FORMAT ", len=%" G_GINT64_FORMAT
751 ", returning EOF", flacdec->offset, len);
755 gst_object_unref (peer);
760 static FLAC__StreamDecoderReadStatus
761 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
762 FLAC__byte buffer[], size_t * bytes, void *client_data)
768 flacdec = GST_FLAC_DEC (client_data);
770 flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
772 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
773 flacdec->pull_flow = flow;
774 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
776 if (G_UNLIKELY (flow != GST_FLOW_OK)) {
777 GST_INFO_OBJECT (flacdec, "pull_range flow: %s", gst_flow_get_name (flow));
778 if (flow == GST_FLOW_UNEXPECTED)
779 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
781 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
784 GST_DEBUG_OBJECT (flacdec, "Read %d bytes at %" G_GUINT64_FORMAT,
785 GST_BUFFER_SIZE (buf), flacdec->offset);
786 memcpy (buffer, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
787 *bytes = GST_BUFFER_SIZE (buf);
788 gst_buffer_unref (buf);
789 flacdec->offset += *bytes;
791 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
794 static FLAC__StreamDecoderReadStatus
795 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
796 FLAC__byte buffer[], size_t * bytes, void *client_data)
798 GstFlacDec *dec = GST_FLAC_DEC (client_data);
801 len = MIN (gst_adapter_available (dec->adapter), *bytes);
804 GST_LOG_OBJECT (dec, "0 bytes available at the moment");
805 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
808 GST_LOG_OBJECT (dec, "feeding %u bytes to decoder (available=%u, bytes=%u)",
809 len, gst_adapter_available (dec->adapter), (guint) * bytes);
810 gst_adapter_copy (dec->adapter, buffer, 0, len);
813 gst_adapter_flush (dec->adapter, len);
815 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
818 static FLAC__StreamDecoderWriteStatus
819 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
820 const FLAC__int32 * const buffer[])
822 GstFlowReturn ret = GST_FLOW_OK;
824 guint depth = frame->header.bits_per_sample;
826 guint sample_rate = frame->header.sample_rate;
827 guint channels = frame->header.channels;
828 guint samples = frame->header.blocksize;
832 GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
834 /* if a DEFAULT segment is configured, don't send samples past the end
836 if (flacdec->segment.format == GST_FORMAT_DEFAULT &&
837 flacdec->segment.stop != -1 &&
838 flacdec->segment.last_stop >= 0 &&
839 flacdec->segment.last_stop + samples > flacdec->segment.stop) {
840 samples = flacdec->segment.stop - flacdec->segment.last_stop;
841 GST_DEBUG_OBJECT (flacdec,
842 "clipping last buffer to %d samples because of segment", samples);
859 if (flacdec->depth < 4 || flacdec->depth > 32) {
860 GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
862 ret = GST_FLOW_ERROR;
866 depth = flacdec->depth;
876 GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
877 ret = GST_FLOW_ERROR;
881 if (sample_rate == 0) {
882 if (flacdec->sample_rate != 0) {
883 sample_rate = flacdec->sample_rate;
885 GST_ERROR_OBJECT (flacdec, "unknown sample rate");
886 ret = GST_FLOW_ERROR;
891 if (!GST_PAD_CAPS (flacdec->srcpad)) {
894 GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
895 frame->header.sample_rate, channels);
897 caps = gst_caps_new_simple ("audio/x-raw-int",
898 "endianness", G_TYPE_INT, G_BYTE_ORDER,
899 "signed", G_TYPE_BOOLEAN, TRUE,
900 "width", G_TYPE_INT, width,
901 "depth", G_TYPE_INT, depth,
902 "rate", G_TYPE_INT, frame->header.sample_rate,
903 "channels", G_TYPE_INT, channels, NULL);
906 GstStructure *s = gst_caps_get_structure (caps, 0);
908 gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
911 flacdec->depth = depth;
912 flacdec->width = width;
913 flacdec->channels = channels;
914 flacdec->sample_rate = sample_rate;
916 gst_pad_set_caps (flacdec->srcpad, caps);
917 gst_caps_unref (caps);
920 if (flacdec->close_segment) {
921 GST_DEBUG_OBJECT (flacdec, "pushing close segment");
922 gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
923 flacdec->close_segment = NULL;
925 if (flacdec->start_segment) {
926 GST_DEBUG_OBJECT (flacdec, "pushing start segment");
927 gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
928 flacdec->start_segment = NULL;
932 gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
934 flacdec->tags = NULL;
937 if (flacdec->pending) {
938 GST_DEBUG_OBJECT (flacdec,
939 "pushing pending samples at offset %" G_GINT64_FORMAT " (%"
940 GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
941 GST_BUFFER_OFFSET (flacdec->pending),
942 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (flacdec->pending)),
943 GST_TIME_ARGS (GST_BUFFER_DURATION (flacdec->pending)));
944 /* Pending buffer was always allocated from the seeking thread,
945 * which means it wasn't gst_buffer_alloc'd. Do so now to let
946 * downstream negotiation work on older basetransform */
947 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
948 GST_BUFFER_OFFSET (flacdec->pending),
949 GST_BUFFER_SIZE (flacdec->pending),
950 GST_BUFFER_CAPS (flacdec->pending), &outbuf);
951 if (ret == GST_FLOW_OK) {
952 gst_pad_push (flacdec->srcpad, flacdec->pending);
953 gst_buffer_unref (outbuf);
956 outbuf = flacdec->pending = NULL;
957 flacdec->segment.last_stop += flacdec->pending_samples;
958 flacdec->pending_samples = 0;
961 if (flacdec->seeking) {
962 GST_DEBUG_OBJECT (flacdec, "a pad_alloc would block here, do normal alloc");
963 outbuf = gst_buffer_new_and_alloc (samples * channels * (width / 8));
964 gst_buffer_set_caps (outbuf, GST_PAD_CAPS (flacdec->srcpad));
965 GST_BUFFER_OFFSET (outbuf) = flacdec->segment.last_stop;
967 GST_LOG_OBJECT (flacdec, "alloc_buffer_and_set_caps");
968 ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
969 flacdec->segment.last_stop, samples * channels * (width / 8),
970 GST_PAD_CAPS (flacdec->srcpad), &outbuf);
972 if (ret != GST_FLOW_OK) {
973 GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
974 gst_flow_get_name (ret));
979 if (flacdec->cur_granulepos != GST_BUFFER_OFFSET_NONE) {
980 /* this should be fine since it should be one flac frame per ogg packet */
981 flacdec->segment.last_stop = flacdec->cur_granulepos - samples;
982 GST_LOG_OBJECT (flacdec, "granulepos = %" G_GINT64_FORMAT ", samples = %u",
983 flacdec->cur_granulepos, samples);
986 GST_BUFFER_TIMESTAMP (outbuf) =
987 gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
988 frame->header.sample_rate);
990 /* get next timestamp to calculate the duration */
991 next = gst_util_uint64_scale_int (flacdec->segment.last_stop + samples,
992 GST_SECOND, frame->header.sample_rate);
994 GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
997 gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
999 for (i = 0; i < samples; i++) {
1000 for (j = 0; j < channels; j++) {
1001 *outbuffer++ = (gint8) buffer[j][i];
1004 } else if (width == 16) {
1005 gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
1007 for (i = 0; i < samples; i++) {
1008 for (j = 0; j < channels; j++) {
1009 *outbuffer++ = (gint16) buffer[j][i];
1012 } else if (width == 32) {
1013 gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
1015 for (i = 0; i < samples; i++) {
1016 for (j = 0; j < channels; j++) {
1017 *outbuffer++ = (gint32) buffer[j][i];
1021 g_assert_not_reached ();
1024 if (!flacdec->seeking) {
1025 GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
1026 " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
1027 samples, GST_BUFFER_OFFSET (outbuf),
1028 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1029 GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1031 if (flacdec->discont) {
1032 GST_DEBUG_OBJECT (flacdec, "marking discont");
1033 outbuf = gst_buffer_make_metadata_writable (outbuf);
1034 GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1035 flacdec->discont = FALSE;
1037 ret = gst_pad_push (flacdec->srcpad, outbuf);
1038 GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
1039 flacdec->segment.last_stop += samples;
1041 GST_DEBUG_OBJECT (flacdec,
1042 "not pushing %d samples at offset %" G_GINT64_FORMAT
1043 " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
1044 gst_buffer_replace (&flacdec->pending, outbuf);
1045 gst_buffer_unref (outbuf);
1046 flacdec->pending_samples = samples;
1050 if (ret != GST_FLOW_OK) {
1051 GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1052 gst_flow_get_name (ret));
1058 /* we act on the flow return value later in the loop function, as we don't
1059 * want to mess up the internal decoder state by returning ABORT when the
1060 * error is in fact non-fatal (like a pad in flushing mode) and we want
1061 * to continue later. So just pretend everything's dandy and act later. */
1062 flacdec->last_flow = ret;
1064 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1067 static FLAC__StreamDecoderWriteStatus
1068 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
1069 const FLAC__Frame * frame,
1070 const FLAC__int32 * const buffer[], void *client_data)
1072 return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1076 gst_flac_dec_loop (GstPad * sinkpad)
1078 GstFlacDec *flacdec;
1079 FLAC__StreamDecoderState s;
1080 FLAC__StreamDecoderInitStatus is;
1082 flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1084 GST_LOG_OBJECT (flacdec, "entering loop");
1087 GST_DEBUG_OBJECT (flacdec, "Seeked after end of file");
1089 if (flacdec->close_segment) {
1090 GST_DEBUG_OBJECT (flacdec, "pushing close segment");
1091 gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
1092 flacdec->close_segment = NULL;
1094 if (flacdec->start_segment) {
1095 GST_DEBUG_OBJECT (flacdec, "pushing start segment");
1096 gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
1097 flacdec->start_segment = NULL;
1100 if (flacdec->tags) {
1101 gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
1103 flacdec->tags = NULL;
1106 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1109 goto segment_done_and_pause;
1113 if (flacdec->init) {
1114 GST_DEBUG_OBJECT (flacdec, "initializing new decoder");
1115 is = FLAC__stream_decoder_init_stream (flacdec->decoder,
1116 gst_flac_dec_read_seekable, gst_flac_dec_seek, gst_flac_dec_tell,
1117 gst_flac_dec_length, gst_flac_dec_eof, gst_flac_dec_write_stream,
1118 gst_flac_dec_metadata_cb, gst_flac_dec_error_cb, flacdec);
1119 if (is != FLAC__STREAM_DECODER_INIT_STATUS_OK)
1122 /* FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1123 flacdec->init = FALSE;
1126 flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1128 flacdec->last_flow = GST_FLOW_OK;
1130 GST_LOG_OBJECT (flacdec, "processing single");
1131 FLAC__stream_decoder_process_single (flacdec->decoder);
1135 GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1136 s = FLAC__stream_decoder_get_state (flacdec->decoder);
1138 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
1139 case FLAC__STREAM_DECODER_READ_METADATA:
1140 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
1141 case FLAC__STREAM_DECODER_READ_FRAME:
1143 GST_DEBUG_OBJECT (flacdec, "everything ok");
1145 if (flacdec->last_flow < GST_FLOW_UNEXPECTED ||
1146 flacdec->last_flow == GST_FLOW_NOT_LINKED) {
1147 GST_ELEMENT_ERROR (flacdec, STREAM, FAILED,
1148 (_("Internal data stream error.")),
1149 ("stream stopped, reason %s",
1150 gst_flow_get_name (flacdec->last_flow)));
1152 } else if (flacdec->last_flow == GST_FLOW_UNEXPECTED) {
1154 } else if (flacdec->last_flow != GST_FLOW_OK) {
1158 /* check if we're at the end of a configured segment */
1159 if (flacdec->segment.stop != -1 &&
1160 flacdec->segment.last_stop > 0 &&
1161 flacdec->segment.last_stop >= flacdec->segment.stop) {
1162 GST_DEBUG_OBJECT (flacdec, "reached end of the configured segment");
1164 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1167 goto segment_done_and_pause;
1170 g_assert_not_reached ();
1176 case FLAC__STREAM_DECODER_END_OF_STREAM:{
1177 GST_DEBUG_OBJECT (flacdec, "EOS");
1178 FLAC__stream_decoder_reset (flacdec->decoder);
1180 if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1181 if (flacdec->segment.duration > 0) {
1182 flacdec->segment.stop = flacdec->segment.duration;
1184 flacdec->segment.stop = flacdec->segment.last_stop;
1186 goto segment_done_and_pause;
1192 /* gst_flac_dec_read_seekable() returned ABORTED */
1193 case FLAC__STREAM_DECODER_ABORTED:
1195 GST_INFO_OBJECT (flacdec, "read aborted: last pull_range flow = %s",
1196 gst_flow_get_name (flacdec->pull_flow));
1197 if (flacdec->pull_flow == GST_FLOW_WRONG_STATE) {
1198 /* it seems we need to flush the decoder here to reset the decoder
1199 * state after the abort for FLAC__stream_decoder_seek_absolute()
1200 * to work properly */
1201 GST_DEBUG_OBJECT (flacdec, "flushing decoder to reset decoder state");
1202 FLAC__stream_decoder_flush (flacdec->decoder);
1207 case FLAC__STREAM_DECODER_OGG_ERROR:
1208 case FLAC__STREAM_DECODER_SEEK_ERROR:
1209 case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
1210 case FLAC__STREAM_DECODER_UNINITIALIZED:
1212 /* fixme: this error sucks -- should try to figure out when/if an more
1213 specific error was already sent via the callback */
1214 GST_ELEMENT_ERROR (flacdec, STREAM, DECODE, (NULL),
1215 ("%s", FLAC__StreamDecoderStateString[s]));
1222 segment_done_and_pause:
1226 stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1227 GST_SECOND, flacdec->sample_rate);
1229 GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1230 GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1232 gst_element_post_message (GST_ELEMENT (flacdec),
1233 gst_message_new_segment_done (GST_OBJECT (flacdec),
1234 GST_FORMAT_TIME, stop_time));
1240 GST_DEBUG_OBJECT (flacdec, "sending EOS event");
1241 flacdec->running = FALSE;
1242 gst_pad_push_event (flacdec->srcpad, gst_event_new_eos ());
1243 /* fall through to pause */
1247 GST_DEBUG_OBJECT (flacdec, "pausing");
1248 gst_pad_pause_task (sinkpad);
1254 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1259 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1261 switch (GST_EVENT_TYPE (event)) {
1262 case GST_EVENT_FLUSH_STOP:{
1263 if (dec->init == FALSE) {
1264 FLAC__stream_decoder_flush (dec->decoder);
1265 gst_adapter_clear (dec->adapter);
1267 res = gst_pad_push_event (dec->srcpad, event);
1270 case GST_EVENT_NEWSEGMENT:{
1273 gdouble rate, applied_rate;
1274 gint64 cur, stop, time;
1276 gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1277 &fmt, &cur, &stop, &time);
1279 if (fmt == GST_FORMAT_TIME) {
1280 GstFormat dformat = GST_FORMAT_DEFAULT;
1282 GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1284 res = gst_pad_push_event (dec->srcpad, event);
1286 /* this won't work for the first newsegment event though ... */
1287 if (gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, cur,
1288 &dformat, &cur) && cur != -1 &&
1289 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, stop,
1290 &dformat, &stop) && stop != -1) {
1291 gst_segment_set_newsegment_full (&dec->segment, update, rate,
1292 applied_rate, dformat, cur, stop, time);
1293 GST_DEBUG_OBJECT (dec, "segment %" GST_SEGMENT_FORMAT, &dec->segment);
1295 GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1297 } else if (fmt == GST_FORMAT_BYTES || TRUE) {
1298 GST_DEBUG_OBJECT (dec, "newsegment event in %s format => not framed",
1299 gst_format_get_name (fmt));
1300 dec->framed = FALSE;
1302 /* prepare generic newsegment event, for some reason our metadata
1303 * callback where we usually set this up is not being called in
1305 if (dec->start_segment)
1306 gst_event_unref (dec->start_segment);
1307 dec->start_segment = gst_event_new_new_segment (FALSE, 1.0,
1308 GST_FORMAT_TIME, 0, -1, 0);
1310 gst_event_unref (event);
1315 case GST_EVENT_EOS:{
1316 GST_LOG_OBJECT (dec, "EOS, with %u bytes available in adapter",
1317 gst_adapter_available (dec->adapter));
1318 if (dec->init == FALSE) {
1319 if (gst_adapter_available (dec->adapter) > 0) {
1320 FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
1322 FLAC__stream_decoder_flush (dec->decoder);
1324 gst_adapter_clear (dec->adapter);
1325 res = gst_pad_push_event (dec->srcpad, event);
1329 res = gst_pad_event_default (pad, event);
1333 gst_object_unref (dec);
1339 gst_flac_dec_chain_parse_headers (GstFlacDec * dec)
1344 avail = gst_adapter_available (dec->adapter);
1348 gst_adapter_copy (dec->adapter, marker, 0, 4);
1349 if (strncmp ((const gchar *) marker, "fLaC", 4) != 0) {
1350 GST_ERROR_OBJECT (dec, "Unexpected header, expected fLaC header");
1351 return TRUE; /* abort header parsing */
1354 GST_DEBUG_OBJECT (dec, "fLaC header : len 4 @ %7u", 0);
1357 while (avail > (off + 1 + 3)) {
1360 guint len, block_type;
1362 gst_adapter_copy (dec->adapter, mb_hdr, off, 4);
1364 is_last = ((mb_hdr[0] & 0x80) == 0x80);
1365 block_type = mb_hdr[0] & 0x7f;
1366 len = GST_READ_UINT24_BE (mb_hdr + 1);
1367 GST_DEBUG_OBJECT (dec, "Metadata block type %u: len %7u + 4 @ %7u%s",
1368 block_type, len, off, (is_last) ? " (last)" : "");
1375 GST_LOG_OBJECT (dec, "Need more data: next offset %u > avail %u", off,
1381 /* want metadata blocks plus at least one frame */
1382 return (off + FLAC__MAX_BLOCK_SIZE >= avail);
1385 static GstFlowReturn
1386 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1388 FLAC__StreamDecoderInitStatus s;
1390 gboolean got_audio_frame;
1392 dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1394 GST_LOG_OBJECT (dec,
1395 "buffer with ts=%" GST_TIME_FORMAT ", offset=%" G_GINT64_FORMAT
1396 ", end_offset=%" G_GINT64_FORMAT ", size=%u",
1397 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_OFFSET (buf),
1398 GST_BUFFER_OFFSET_END (buf), GST_BUFFER_SIZE (buf));
1401 GST_DEBUG_OBJECT (dec, "initializing decoder");
1402 s = FLAC__stream_decoder_init_stream (dec->decoder,
1403 gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
1404 gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
1405 gst_flac_dec_error_cb, dec);
1406 if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1407 GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
1408 return GST_FLOW_ERROR;
1410 GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1412 } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1413 /* Clear the adapter and the decoder */
1414 gst_adapter_clear (dec->adapter);
1415 FLAC__stream_decoder_flush (dec->decoder);
1421 /* check if this is a flac audio frame (rather than a header or junk) */
1422 got_audio_frame = gst_flac_dec_scan_got_frame (dec, GST_BUFFER_DATA (buf),
1423 GST_BUFFER_SIZE (buf), &unused);
1425 /* oggdemux will set granulepos in OFFSET_END instead of timestamp */
1426 if (G_LIKELY (got_audio_frame)) {
1427 /* old oggdemux for now */
1428 if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1429 dec->cur_granulepos = GST_BUFFER_OFFSET_END (buf);
1431 GstFormat dformat = GST_FORMAT_DEFAULT;
1433 /* upstream (e.g. demuxer) presents us time,
1434 * convert to default samples */
1435 gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME,
1436 GST_BUFFER_TIMESTAMP (buf), &dformat, &dec->segment.last_stop);
1437 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1441 dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1442 got_audio_frame = TRUE;
1445 gst_adapter_push (dec->adapter, buf);
1448 dec->last_flow = GST_FLOW_OK;
1451 if (G_UNLIKELY (!dec->got_headers)) {
1452 if (!gst_flac_dec_chain_parse_headers (dec)) {
1453 GST_LOG_OBJECT (dec, "don't have metadata blocks yet, need more data");
1456 GST_INFO_OBJECT (dec, "have all metadata blocks now");
1457 dec->got_headers = TRUE;
1460 /* wait until we have at least 64kB because libflac's StreamDecoder
1461 * interface is a bit dumb it seems (if we don't have as much data as
1462 * it wants it will call our read callback repeatedly and the only
1463 * way to stop that is to error out or EOS, which will affect the
1464 * decoder state). And the decoder seems to always ask for MAX_BLOCK_SIZE
1465 * bytes rather than the max. block size from the header). Requiring
1466 * MAX_BLOCK_SIZE bytes here should make sure it always gets enough data
1467 * to decode at least one block */
1468 while (gst_adapter_available (dec->adapter) >= FLAC__MAX_BLOCK_SIZE &&
1469 dec->last_flow == GST_FLOW_OK) {
1470 GST_LOG_OBJECT (dec, "%u bytes available",
1471 gst_adapter_available (dec->adapter));
1472 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1473 GST_DEBUG_OBJECT (dec, "process_single failed");
1477 if (FLAC__stream_decoder_get_state (dec->decoder) ==
1478 FLAC__STREAM_DECODER_ABORTED) {
1479 GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
1480 dec->last_flow = GST_FLOW_ERROR;
1484 } else if (dec->framed && got_audio_frame) {
1485 /* framed - there should always be enough data to decode something */
1486 GST_LOG_OBJECT (dec, "%u bytes available",
1487 gst_adapter_available (dec->adapter));
1488 if (G_UNLIKELY (!dec->got_headers)) {
1489 /* The first time we get audio data, we know we got all the headers.
1490 * We then loop until all the metadata is processed, then do an extra
1491 * "process_single" step for the audio frame. */
1492 GST_DEBUG_OBJECT (dec,
1493 "First audio frame, ensuring all metadata is processed");
1494 if (!FLAC__stream_decoder_process_until_end_of_metadata (dec->decoder)) {
1495 GST_DEBUG_OBJECT (dec, "process_until_end_of_metadata failed");
1497 GST_DEBUG_OBJECT (dec,
1498 "All metadata is now processed, reading to process audio data");
1499 dec->got_headers = TRUE;
1501 if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1502 GST_DEBUG_OBJECT (dec, "process_single failed");
1505 GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1510 return dec->last_flow;
1514 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1515 gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1517 gboolean res = TRUE;
1519 if (dec->width == 0 || dec->channels == 0 || dec->sample_rate == 0) {
1520 /* no frame decoded yet */
1521 GST_DEBUG_OBJECT (dec, "cannot convert: not set up yet");
1525 switch (src_format) {
1526 case GST_FORMAT_BYTES:{
1530 case GST_FORMAT_DEFAULT:
1531 switch (*dest_format) {
1532 case GST_FORMAT_BYTES:
1535 case GST_FORMAT_TIME:
1536 /* granulepos = sample */
1537 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1545 case GST_FORMAT_TIME:
1546 switch (*dest_format) {
1547 case GST_FORMAT_BYTES:
1550 case GST_FORMAT_DEFAULT:
1551 *dest_value = gst_util_uint64_scale_int (src_value,
1552 dec->sample_rate, GST_SECOND);
1566 static const GstQueryType *
1567 gst_flac_dec_get_sink_query_types (GstPad * pad)
1569 static const GstQueryType types[] = {
1578 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1581 gboolean res = FALSE;
1583 dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1585 GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1587 switch (GST_QUERY_TYPE (query)) {
1588 case GST_QUERY_CONVERT:{
1589 GstFormat src_fmt, dest_fmt;
1591 gint64 src_val, dest_val;
1593 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1595 res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1599 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1601 GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1606 res = gst_pad_query_default (pad, query);
1611 gst_object_unref (dec);
1616 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1617 GstFormat * dest_format, gint64 * dest_value)
1619 GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1620 gboolean res = TRUE;
1621 guint bytes_per_sample;
1624 if (flacdec->width == 0 || flacdec->channels == 0 ||
1625 flacdec->sample_rate == 0) {
1626 /* no frame decoded yet */
1627 GST_DEBUG_OBJECT (flacdec, "cannot convert: not set up yet");
1631 bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1633 switch (src_format) {
1634 case GST_FORMAT_BYTES:{
1635 switch (*dest_format) {
1636 case GST_FORMAT_DEFAULT:
1638 gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1640 case GST_FORMAT_TIME:
1642 gint byterate = bytes_per_sample * flacdec->sample_rate;
1644 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1653 case GST_FORMAT_DEFAULT:
1654 switch (*dest_format) {
1655 case GST_FORMAT_BYTES:
1656 *dest_value = src_value * bytes_per_sample;
1658 case GST_FORMAT_TIME:
1659 *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1660 flacdec->sample_rate);
1666 case GST_FORMAT_TIME:
1667 switch (*dest_format) {
1668 case GST_FORMAT_BYTES:
1669 scale = bytes_per_sample;
1670 case GST_FORMAT_DEFAULT:
1671 *dest_value = gst_util_uint64_scale_int_round (src_value,
1672 scale * flacdec->sample_rate, GST_SECOND);
1684 static const GstQueryType *
1685 gst_flac_dec_get_src_query_types (GstPad * pad)
1687 static const GstQueryType types[] = {
1699 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1701 GstFlacDec *flacdec;
1702 gboolean res = TRUE;
1705 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1706 peer = gst_pad_get_peer (flacdec->sinkpad);
1708 switch (GST_QUERY_TYPE (query)) {
1709 case GST_QUERY_POSITION:{
1713 gst_query_parse_position (query, &fmt, NULL);
1715 /* there might be a demuxer in front of us who can handle this */
1716 if (fmt == GST_FORMAT_TIME && (res = gst_pad_query (peer, query)))
1719 if (fmt != GST_FORMAT_DEFAULT) {
1720 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1721 flacdec->segment.last_stop, &fmt, &pos)) {
1722 GST_DEBUG_OBJECT (flacdec, "failed to convert position into %s "
1723 "format", gst_format_get_name (fmt));
1728 pos = flacdec->segment.last_stop;
1731 gst_query_set_position (query, fmt, pos);
1733 GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1734 " (format: %s)", pos, gst_format_get_name (fmt));
1740 case GST_QUERY_DURATION:{
1744 gst_query_parse_duration (query, &fmt, NULL);
1746 /* try any demuxers or parsers before us first */
1747 if ((fmt == GST_FORMAT_TIME || fmt == GST_FORMAT_DEFAULT) &&
1748 peer != NULL && gst_pad_query (peer, query)) {
1749 gst_query_parse_duration (query, NULL, &len);
1750 GST_DEBUG_OBJECT (flacdec, "peer returned duration %" GST_TIME_FORMAT,
1751 GST_TIME_ARGS (len));
1756 if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1757 GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1762 /* convert total number of samples to request format */
1763 if (fmt != GST_FORMAT_DEFAULT) {
1764 if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1765 flacdec->segment.duration, &fmt, &len)) {
1766 GST_DEBUG_OBJECT (flacdec, "failed to convert duration into %s "
1767 "format", gst_format_get_name (fmt));
1772 len = flacdec->segment.duration;
1775 gst_query_set_duration (query, fmt, len);
1777 GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1778 " (format: %s)", len, gst_format_get_name (fmt));
1784 case GST_QUERY_CONVERT:{
1785 GstFormat src_fmt, dest_fmt;
1786 gint64 src_val, dest_val;
1788 gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1790 res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1794 gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1799 case GST_QUERY_SEEKING:{
1801 gboolean seekable = FALSE;
1804 /* If upstream can handle the query we're done */
1805 seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1807 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1811 gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1812 if ((fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT) ||
1813 flacdec->streaming) {
1814 gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1816 gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1822 res = gst_pad_query_default (pad, query);
1830 gst_object_unref (peer);
1832 gst_object_unref (flacdec);
1838 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1841 GstSeekFlags seek_flags;
1842 GstSeekType start_type;
1843 GstSeekType stop_type;
1845 GstFormat seek_format;
1846 gboolean only_update = FALSE;
1849 gint64 start, last_stop;
1852 if (flacdec->streaming) {
1853 GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1857 gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1858 &start, &stop_type, &stop);
1860 if (seek_format != GST_FORMAT_DEFAULT && seek_format != GST_FORMAT_TIME) {
1861 GST_DEBUG_OBJECT (flacdec,
1862 "seeking is only supported in TIME or DEFAULT format");
1867 GST_DEBUG_OBJECT (flacdec,
1868 "only forward playback supported, rate %f not allowed", rate);
1872 if (seek_format != GST_FORMAT_DEFAULT) {
1873 GstFormat target_format = GST_FORMAT_DEFAULT;
1875 if (start_type != GST_SEEK_TYPE_NONE &&
1876 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, start,
1877 &target_format, &start)) {
1878 GST_DEBUG_OBJECT (flacdec, "failed to convert start to DEFAULT format");
1882 if (stop_type != GST_SEEK_TYPE_NONE &&
1883 !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, stop,
1884 &target_format, &stop)) {
1885 GST_DEBUG_OBJECT (flacdec, "failed to convert stop to DEFAULT format");
1890 /* Check if we seeked after the end of file */
1891 if (start_type != GST_SEEK_TYPE_NONE && flacdec->segment.duration > 0 &&
1892 start >= flacdec->segment.duration) {
1893 flacdec->eos = TRUE;
1895 flacdec->eos = FALSE;
1898 flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1901 /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1903 GST_DEBUG_OBJECT (flacdec, "flushing");
1904 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_start ());
1905 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_start ());
1907 /* non flushing seek, pause the task */
1908 GST_DEBUG_OBJECT (flacdec, "stopping task");
1909 gst_pad_stop_task (flacdec->sinkpad);
1912 /* acquire the stream lock, this either happens when the streaming thread
1913 * stopped because of the flush or when the task is paused after the loop
1914 * function finished an iteration, which can never happen when it's blocked
1915 * downstream in PAUSED, for example */
1916 GST_PAD_STREAM_LOCK (flacdec->sinkpad);
1918 /* start seek with clear state to avoid seeking thread pushing segments/data.
1919 * Note current state may have some pending,
1920 * e.g. multi-sink seek leads to immediate subsequent seek events */
1921 if (flacdec->start_segment) {
1922 gst_event_unref (flacdec->start_segment);
1923 flacdec->start_segment = NULL;
1925 gst_buffer_replace (&flacdec->pending, NULL);
1926 flacdec->pending_samples = 0;
1928 /* save a segment copy until we know the seek worked. The idea is that
1929 * when the seek fails, we want to restore with what we were doing. */
1930 segment = flacdec->segment;
1932 /* update the segment with the seek values, last_stop will contain the new
1933 * position we should seek to */
1934 gst_segment_set_seek (&flacdec->segment, rate, GST_FORMAT_DEFAULT,
1935 seek_flags, start_type, start, stop_type, stop, &only_update);
1937 GST_DEBUG_OBJECT (flacdec,
1938 "configured segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT
1939 "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]",
1940 flacdec->segment.start, flacdec->segment.stop,
1941 GST_TIME_ARGS (flacdec->segment.start * GST_SECOND /
1942 flacdec->sample_rate),
1943 GST_TIME_ARGS (flacdec->segment.stop * GST_SECOND /
1944 flacdec->sample_rate));
1946 GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1947 flacdec->segment.last_stop);
1949 /* flush sinkpad again because we need to pull and push buffers while doing
1952 GST_DEBUG_OBJECT (flacdec, "flushing stop");
1953 gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_stop ());
1954 gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_stop ());
1957 /* mark ourselves as seeking because the above lines will trigger some
1958 * callbacks that need to behave differently when seeking */
1959 flacdec->seeking = TRUE;
1961 if (!flacdec->eos) {
1962 GST_LOG_OBJECT (flacdec, "calling seek_absolute");
1963 seek_ok = FLAC__stream_decoder_seek_absolute (flacdec->decoder,
1964 flacdec->segment.last_stop);
1965 GST_LOG_OBJECT (flacdec, "done with seek_absolute, seek_ok=%d", seek_ok);
1967 GST_LOG_OBJECT (flacdec, "not seeking, seeked after end of file");
1971 flacdec->seeking = FALSE;
1973 GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1974 flacdec->segment.last_stop);
1977 GST_WARNING_OBJECT (flacdec, "seek failed");
1978 /* seek failed, restore the segment and start streaming again with
1979 * the previous segment values */
1980 flacdec->segment = segment;
1981 } else if (!flush && flacdec->running) {
1982 /* we are running the current segment and doing a non-flushing seek,
1983 * close the segment first based on the last_stop. */
1984 GST_DEBUG_OBJECT (flacdec, "closing running segment %" G_GINT64_FORMAT
1985 " to %" G_GINT64_FORMAT, segment.start, segment.last_stop);
1987 /* convert the old segment values to time to close the old segment */
1988 start = gst_util_uint64_scale_int (segment.start, GST_SECOND,
1989 flacdec->sample_rate);
1991 gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1992 flacdec->sample_rate);
1994 /* queue the segment for sending in the stream thread, start and time are
1995 * always the same. */
1996 if (flacdec->close_segment)
1997 gst_event_unref (flacdec->close_segment);
1998 flacdec->close_segment =
1999 gst_event_new_new_segment_full (TRUE,
2000 segment.rate, segment.applied_rate, GST_FORMAT_TIME,
2001 start, last_stop, start);
2005 /* seek succeeded, flacdec->segment contains the new positions */
2006 GST_DEBUG_OBJECT (flacdec, "seek successful");
2009 /* convert the (new) segment values to time, we will need them to generate the
2010 * new segment events. */
2011 start = gst_util_uint64_scale_int (flacdec->segment.start, GST_SECOND,
2012 flacdec->sample_rate);
2013 last_stop = gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
2014 flacdec->sample_rate);
2016 /* for deriving a stop position for the playback segment from the seek
2017 * segment, we must take the duration when the stop is not set */
2018 if (flacdec->segment.stop != -1)
2019 stop = gst_util_uint64_scale_int (flacdec->segment.stop, GST_SECOND,
2020 flacdec->sample_rate);
2022 stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
2023 flacdec->sample_rate);
2025 /* notify start of new segment when we were asked to do so. */
2026 if (flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2027 /* last_stop contains the position we start from */
2028 gst_element_post_message (GST_ELEMENT (flacdec),
2029 gst_message_new_segment_start (GST_OBJECT (flacdec),
2030 GST_FORMAT_TIME, last_stop));
2033 /* if the seek was ok or (when it failed) we are flushing, we need to send out
2034 * a new segment. If we did not flush and the seek failed, we simply do
2035 * nothing here and continue where we were. */
2036 if (seek_ok || flush) {
2037 GST_DEBUG_OBJECT (flacdec, "Creating newsegment from %" GST_TIME_FORMAT
2038 " to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop),
2039 GST_TIME_ARGS (stop));
2040 /* now replace the old segment so that we send it in the stream thread the
2041 * next time it is scheduled. */
2042 if (flacdec->start_segment)
2043 gst_event_unref (flacdec->start_segment);
2044 flacdec->start_segment =
2045 gst_event_new_new_segment_full (FALSE,
2046 flacdec->segment.rate, flacdec->segment.applied_rate, GST_FORMAT_TIME,
2047 last_stop, stop, last_stop);
2050 /* we'll generate a discont on the next buffer */
2051 flacdec->discont = TRUE;
2052 /* the task is running again now */
2053 flacdec->running = TRUE;
2054 gst_pad_start_task (flacdec->sinkpad,
2055 (GstTaskFunction) gst_flac_dec_loop, flacdec->sinkpad);
2057 GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
2063 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
2065 gboolean res = TRUE;
2066 GstFlacDec *flacdec;
2068 flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
2070 switch (GST_EVENT_TYPE (event)) {
2071 case GST_EVENT_SEEK:{
2072 GST_DEBUG_OBJECT (flacdec, "received seek event %p", event);
2073 /* first, see if we're before a demuxer that
2074 * might handle the seek for us */
2075 gst_event_ref (event);
2076 res = gst_pad_event_default (pad, event);
2077 /* if not, try to handle it ourselves */
2079 GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
2080 res = gst_flac_dec_handle_seek_event (flacdec, event);
2082 gst_event_unref (event);
2086 res = gst_pad_event_default (pad, event);
2090 gst_object_unref (flacdec);
2096 gst_flac_dec_sink_activate (GstPad * sinkpad)
2098 if (gst_pad_check_pull_range (sinkpad))
2099 return gst_pad_activate_pull (sinkpad, TRUE);
2101 return gst_pad_activate_push (sinkpad, TRUE);
2105 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
2107 GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
2110 gst_flac_dec_setup_decoder (dec);
2111 dec->streaming = TRUE;
2112 dec->got_headers = FALSE;
2118 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
2123 GstFlacDec *flacdec;
2125 flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
2127 flacdec->offset = 0;
2128 gst_flac_dec_setup_decoder (flacdec);
2129 flacdec->running = TRUE;
2130 flacdec->streaming = FALSE;
2132 res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
2135 res = gst_pad_stop_task (sinkpad);
2140 static GstStateChangeReturn
2141 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2143 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2144 GstFlacDec *flacdec = GST_FLAC_DEC (element);
2146 switch (transition) {
2147 case GST_STATE_CHANGE_READY_TO_PAUSED:
2148 flacdec->eos = FALSE;
2149 flacdec->seeking = FALSE;
2150 flacdec->channels = 0;
2153 flacdec->sample_rate = 0;
2154 gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2160 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2161 if (ret == GST_STATE_CHANGE_FAILURE)
2164 switch (transition) {
2165 case GST_STATE_CHANGE_PAUSED_TO_READY:
2166 gst_segment_init (&flacdec->segment, GST_FORMAT_UNDEFINED);
2167 gst_flac_dec_reset_decoders (flacdec);