flacdec: Send EOS when seeking after the end of file instead of failing
[platform/upstream/gst-plugins-good.git] / ext / flac / gstflacdec.c
1 /* GStreamer
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>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:element-flacdec
24  * @see_also: #GstFlacEnc
25  *
26  * flacdec decodes FLAC streams.
27  * <ulink url="http://flac.sourceforge.net/">FLAC</ulink>
28  * is a Free Lossless Audio Codec.
29  *
30  * <refsect2>
31  * <title>Example launch line</title>
32  * |[
33  * gst-launch filesrc location=media/small/dark.441-16-s.flac ! flacdec ! audioconvert ! audioresample ! autoaudiosink
34  * ]|
35  * |[
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
37  * ]|
38  * </refsect2>
39  */
40
41 /* TODO: add seeking when operating chain-based with unframed input */
42 /* FIXME: demote/remove granulepos handling and make more time-centric */
43
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47 #include <string.h>
48
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>
55
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 */
80   {
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}
96 };
97
98 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
99 #define GST_CAT_DEFAULT flacdec_debug
100
101 static void gst_flac_dec_finalize (GObject * object);
102 static void gst_flac_dec_loop (GstPad * pad);
103
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,
115     gboolean active);
116 static gboolean gst_flac_dec_sink_activate_push (GstPad * sinkpad,
117     gboolean active);
118 static gboolean gst_flac_dec_sink_event (GstPad * pad, GstEvent * event);
119 static GstFlowReturn gst_flac_dec_chain (GstPad * pad, GstBuffer * buf);
120
121 static void gst_flac_dec_reset_decoders (GstFlacDec * flacdec);
122 static void gst_flac_dec_setup_decoder (GstFlacDec * flacdec);
123
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,
140     void *client_data);
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);
149
150 GST_BOILERPLATE (GstFlacDec, gst_flac_dec, GstElement, GST_TYPE_ELEMENT);
151
152 /* FIXME 0.11: Use width=32 for all depths and let audioconvert
153  * handle the conversions instead of doing it ourself.
154  */
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 ]"
163
164 static GstStaticPadTemplate flac_dec_src_factory =
165 GST_STATIC_PAD_TEMPLATE ("src",
166     GST_PAD_SRC,
167     GST_PAD_ALWAYS,
168     GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
169 static GstStaticPadTemplate flac_dec_sink_factory =
170 GST_STATIC_PAD_TEMPLATE ("sink",
171     GST_PAD_SINK,
172     GST_PAD_ALWAYS,
173     GST_STATIC_CAPS ("audio/x-flac")
174     );
175
176 static void
177 gst_flac_dec_base_init (gpointer g_class)
178 {
179   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
180
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>");
188
189   GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
190 }
191
192 static void
193 gst_flac_dec_class_init (GstFlacDecClass * klass)
194 {
195   GstElementClass *gstelement_class;
196   GObjectClass *gobject_class;
197
198   gstelement_class = (GstElementClass *) klass;
199   gobject_class = (GObjectClass *) klass;
200
201   gobject_class->finalize = gst_flac_dec_finalize;
202
203   gstelement_class->change_state =
204       GST_DEBUG_FUNCPTR (gst_flac_dec_change_state);
205 }
206
207 static void
208 gst_flac_dec_init (GstFlacDec * flacdec, GstFlacDecClass * klass)
209 {
210   flacdec->sinkpad =
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);
227
228   flacdec->srcpad =
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);
238
239   gst_flac_dec_reset_decoders (flacdec);
240 }
241
242 static void
243 gst_flac_dec_reset_decoders (GstFlacDec * flacdec)
244 {
245   /* Clean up the decoder */
246   if (flacdec->decoder) {
247     FLAC__stream_decoder_delete (flacdec->decoder);
248     flacdec->decoder = NULL;
249   }
250
251   if (flacdec->adapter) {
252     gst_adapter_clear (flacdec->adapter);
253     g_object_unref (flacdec->adapter);
254     flacdec->adapter = NULL;
255   }
256
257   if (flacdec->close_segment) {
258     gst_event_unref (flacdec->close_segment);
259     flacdec->close_segment = NULL;
260   }
261   if (flacdec->start_segment) {
262     gst_event_unref (flacdec->start_segment);
263     flacdec->start_segment = NULL;
264   }
265   if (flacdec->tags) {
266     gst_tag_list_free (flacdec->tags);
267     flacdec->tags = NULL;
268   }
269   if (flacdec->pending) {
270     gst_buffer_unref (flacdec->pending);
271     flacdec->pending = NULL;
272   }
273
274   flacdec->segment.last_stop = 0;
275   flacdec->offset = 0;
276   flacdec->init = TRUE;
277 }
278
279 static void
280 gst_flac_dec_setup_decoder (GstFlacDec * dec)
281 {
282   gst_flac_dec_reset_decoders (dec);
283
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);
287
288   dec->adapter = gst_adapter_new ();
289
290   dec->decoder = FLAC__stream_decoder_new ();
291
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);
298 }
299
300 static void
301 gst_flac_dec_finalize (GObject * object)
302 {
303   GstFlacDec *flacdec;
304
305   flacdec = GST_FLAC_DEC (object);
306
307   gst_flac_dec_reset_decoders (flacdec);
308
309   G_OBJECT_CLASS (parent_class)->finalize (object);
310 }
311
312
313 static gboolean
314 gst_flac_dec_update_metadata (GstFlacDec * flacdec,
315     const FLAC__StreamMetadata * metadata)
316 {
317   GstTagList *list;
318   guint num, i;
319
320   if (flacdec->tags)
321     list = flacdec->tags;
322   else
323     flacdec->tags = list = gst_tag_list_new ();
324
325   num = metadata->data.vorbis_comment.num_comments;
326   GST_DEBUG_OBJECT (flacdec, "%u tag(s) found", num);
327
328   for (i = 0; i < num; ++i) {
329     gchar *vc, *name, *value;
330
331     vc = g_strndup ((gchar *) metadata->data.vorbis_comment.comments[i].entry,
332         metadata->data.vorbis_comment.comments[i].length);
333
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);
338       g_free (name);
339       g_free (value);
340     }
341
342     g_free (vc);
343   }
344
345   return TRUE;
346 }
347
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
382 };
383
384 static guint8
385 gst_flac_calculate_crc8 (guint8 * data, guint length)
386 {
387   guint8 crc = 0;
388
389   while (length--) {
390     crc = crc8_table[crc ^ *data];
391     ++data;
392   }
393
394   return crc;
395 }
396
397 static gboolean
398 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
399     gint64 * last_sample_num)
400 {
401   guint headerlen;
402   guint sr_from_end = 0;        /* can be 0, 8 or 16 */
403   guint bs_from_end = 0;        /* can be 0, 8 or 16 */
404   guint32 val = 0;
405   guint8 bs, sr, ca, ss, pb;
406
407   if (size < 10)
408     return FALSE;
409
410   /* sync */
411   if (data[0] != 0xFF || data[1] != 0xF8)
412     return FALSE;
413
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        */
419
420   GST_LOG_OBJECT (flacdec,
421       "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
422
423   if (sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
424     return FALSE;
425   }
426
427   /* read block size from end of header? */
428   if (bs == 6)
429     bs_from_end = 8;
430   else if (bs == 7)
431     bs_from_end = 16;
432
433   /* read sample rate from end of header? */
434   if (sr == 0x0C)
435     sr_from_end = 8;
436   else if (sr == 0x0D || sr == 0x0E)
437     sr_from_end = 16;
438
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
441    * above.
442    */
443   val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
444
445   if (val == (guint32) - 1 || val == (guint32) - 2) {
446     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
447     return FALSE;
448   }
449
450   headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
451       (bs_from_end / 8) + (sr_from_end / 8);
452
453   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
454     GST_LOG_OBJECT (flacdec, "invalid checksum");
455     return FALSE;
456   }
457
458   if (flacdec->min_blocksize == flacdec->max_blocksize) {
459     *last_sample_num = (val + 1) * flacdec->min_blocksize;
460   } else {
461     *last_sample_num = 0;       /* FIXME: + length of last block in samples */
462   }
463
464   /* FIXME: only valid for fixed block size streams */
465   GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
466       *last_sample_num);
467
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));
472   }
473
474   return TRUE;
475 }
476
477 #define SCANBLOCK_SIZE  (64*1024)
478
479 static void
480 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
481 {
482   GstFormat format = GST_FORMAT_BYTES;
483   gint64 file_size, offset;
484
485   GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
486
487   if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
488     GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
489     return;
490   }
491
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");
495     return;
496   }
497
498   GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
499
500   offset = file_size - 1;
501   while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
502     GstFlowReturn flow;
503     GstBuffer *buf = NULL;
504     guint8 *data;
505     guint size;
506
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);
511
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));
515       return;
516     }
517
518     size = GST_BUFFER_SIZE (buf);
519     data = GST_BUFFER_DATA (buf);
520
521     while (size > 16) {
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);
526         return;
527       }
528       ++data;
529       --size;
530     }
531
532     gst_buffer_unref (buf);
533   }
534 }
535
536 static void
537 gst_flac_extract_picture_buffer (GstFlacDec * dec,
538     const FLAC__StreamMetadata * metadata)
539 {
540   FLAC__StreamMetadata_Picture picture;
541   GstTagList *tags;
542
543   g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
544
545   GST_LOG_OBJECT (dec, "Got PICTURE block");
546   picture = metadata->data.picture;
547
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);
551
552   tags = gst_tag_list_new ();
553
554   gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
555       picture.data_length, picture.type);
556
557   if (!gst_tag_list_is_empty (tags)) {
558     gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
559   } else {
560     GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
561     gst_tag_list_free (tags);
562   }
563 }
564
565 static void
566 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
567     const FLAC__StreamMetadata * metadata, void *client_data)
568 {
569   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
570
571   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
572
573   switch (metadata->type) {
574     case FLAC__METADATA_TYPE_STREAMINFO:{
575       gint64 samples;
576       guint depth;
577
578       samples = metadata->data.stream_info.total_samples;
579
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;
585
586       if (depth < 9)
587         flacdec->width = 8;
588       else if (depth < 17)
589         flacdec->width = 16;
590       else
591         flacdec->width = 32;
592
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,
598           flacdec->width);
599
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);
603       }
604
605       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
606
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) {
610         gint64 duration;
611
612         gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
613             samples);
614
615         /* convert duration to time */
616         duration = gst_util_uint64_scale_int (samples, GST_SECOND,
617             flacdec->sample_rate);
618
619         /* fixme, at this time we could seek to the queued seek event if we have
620          * any */
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);
627       }
628       break;
629     }
630     case FLAC__METADATA_TYPE_PICTURE:{
631       gst_flac_extract_picture_buffer (flacdec, metadata);
632       break;
633     }
634     case FLAC__METADATA_TYPE_VORBIS_COMMENT:
635       gst_flac_dec_update_metadata (flacdec, metadata);
636       break;
637     default:
638       break;
639   }
640 }
641
642 static void
643 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
644     FLAC__StreamDecoderErrorStatus status, void *client_data)
645 {
646   const gchar *error;
647   GstFlacDec *dec;
648
649   dec = GST_FLAC_DEC (client_data);
650
651   switch (status) {
652     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
653       /* Ignore this error and keep processing */
654       return;
655     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
656       error = "bad header";
657       break;
658     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
659       error = "CRC mismatch";
660       break;
661     default:
662       error = "unknown error";
663       break;
664   }
665
666   GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
667   dec->last_flow = GST_FLOW_ERROR;
668 }
669
670 static FLAC__StreamDecoderSeekStatus
671 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
672     FLAC__uint64 position, void *client_data)
673 {
674   GstFlacDec *flacdec;
675
676   flacdec = GST_FLAC_DEC (client_data);
677
678   GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
679   flacdec->offset = position;
680
681   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
682 }
683
684 static FLAC__StreamDecoderTellStatus
685 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
686     FLAC__uint64 * position, void *client_data)
687 {
688   GstFlacDec *flacdec;
689
690   flacdec = GST_FLAC_DEC (client_data);
691
692   *position = flacdec->offset;
693
694   GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
695
696   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
697 }
698
699 static FLAC__StreamDecoderLengthStatus
700 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
701     FLAC__uint64 * length, void *client_data)
702 {
703   GstFlacDec *flacdec;
704   GstFormat fmt = GST_FORMAT_BYTES;
705   gint64 len;
706   GstPad *peer;
707
708   flacdec = GST_FLAC_DEC (client_data);
709
710   if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
711     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
712
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;
717
718   *length = len;
719
720   GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
721       (gint64) * length);
722
723   return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
724 }
725
726 static FLAC__bool
727 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
728 {
729   GstFlacDec *flacdec;
730   GstFormat fmt;
731   GstPad *peer;
732   gboolean ret = FALSE;
733   gint64 len;
734
735   flacdec = GST_FLAC_DEC (client_data);
736
737   if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
738     GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
739     return TRUE;
740   }
741
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);
748     ret = TRUE;
749   }
750
751   gst_object_unref (peer);
752
753   return ret;
754 }
755
756 static FLAC__StreamDecoderReadStatus
757 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
758     FLAC__byte buffer[], size_t * bytes, void *client_data)
759 {
760   GstFlowReturn flow;
761   GstFlacDec *flacdec;
762   GstBuffer *buf;
763
764   flacdec = GST_FLAC_DEC (client_data);
765
766   flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
767
768   GST_PAD_STREAM_LOCK (flacdec->sinkpad);
769   flacdec->pull_flow = flow;
770   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
771
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;
776     else
777       return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
778   }
779
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;
786
787   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
788 }
789
790 static FLAC__StreamDecoderReadStatus
791 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
792     FLAC__byte buffer[], size_t * bytes, void *client_data)
793 {
794   GstFlacDec *dec = GST_FLAC_DEC (client_data);
795   guint len;
796
797   len = MIN (gst_adapter_available (dec->adapter), *bytes);
798
799   if (len == 0) {
800     GST_LOG_OBJECT (dec, "0 bytes available at the moment");
801     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
802   }
803
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);
807   *bytes = len;
808
809   gst_adapter_flush (dec->adapter, len);
810
811   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
812 }
813
814 static FLAC__StreamDecoderWriteStatus
815 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
816     const FLAC__int32 * const buffer[])
817 {
818   GstFlowReturn ret = GST_FLOW_OK;
819   GstBuffer *outbuf;
820   guint depth = frame->header.bits_per_sample;
821   guint width;
822   guint sample_rate = frame->header.sample_rate;
823   guint channels = frame->header.channels;
824   guint samples = frame->header.blocksize;
825   guint j, i;
826   GstClockTime next;
827
828   GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
829
830   /* if a DEFAULT segment is configured, don't send samples past the end
831    * of the segment */
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);
839   }
840
841   switch (depth) {
842     case 8:
843       width = 8;
844       break;
845     case 12:
846     case 16:
847       width = 16;
848       break;
849     case 20:
850     case 24:
851     case 32:
852       width = 32;
853       break;
854     case 0:
855       if (flacdec->depth < 4 || flacdec->depth > 32) {
856         GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
857             flacdec->depth);
858         ret = GST_FLOW_ERROR;
859         goto done;
860       }
861
862       depth = flacdec->depth;
863       if (depth < 9)
864         width = 8;
865       else if (depth < 17)
866         width = 16;
867       else
868         width = 32;
869
870       break;
871     default:
872       GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
873       ret = GST_FLOW_ERROR;
874       goto done;
875   }
876
877   if (sample_rate == 0) {
878     if (flacdec->sample_rate != 0) {
879       sample_rate = flacdec->sample_rate;
880     } else {
881       GST_ERROR_OBJECT (flacdec, "unknown sample rate");
882       ret = GST_FLOW_ERROR;
883       goto done;
884     }
885   }
886
887   if (!GST_PAD_CAPS (flacdec->srcpad)) {
888     GstCaps *caps;
889
890     GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
891         frame->header.sample_rate, channels);
892
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);
900
901     if (channels > 2) {
902       GstStructure *s = gst_caps_get_structure (caps, 0);
903
904       gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
905     }
906
907     flacdec->depth = depth;
908     flacdec->width = width;
909     flacdec->channels = channels;
910     flacdec->sample_rate = sample_rate;
911
912     gst_pad_set_caps (flacdec->srcpad, caps);
913     gst_caps_unref (caps);
914   }
915
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;
920   }
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;
925   }
926
927   if (flacdec->tags) {
928     gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
929         flacdec->tags);
930     flacdec->tags = NULL;
931   }
932
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);
950     }
951
952     outbuf = flacdec->pending = NULL;
953     flacdec->segment.last_stop += flacdec->pending_samples;
954     flacdec->pending_samples = 0;
955   }
956
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;
962   } else {
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);
967
968     if (ret != GST_FLOW_OK) {
969       GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
970           gst_flow_get_name (ret));
971       goto done;
972     }
973   }
974
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);
980   }
981
982   GST_BUFFER_TIMESTAMP (outbuf) =
983       gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
984       frame->header.sample_rate);
985
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);
989
990   GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
991
992   if (width == 8) {
993     gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
994
995     for (i = 0; i < samples; i++) {
996       for (j = 0; j < channels; j++) {
997         *outbuffer++ = (gint8) buffer[j][i];
998       }
999     }
1000   } else if (width == 16) {
1001     gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
1002
1003     for (i = 0; i < samples; i++) {
1004       for (j = 0; j < channels; j++) {
1005         *outbuffer++ = (gint16) buffer[j][i];
1006       }
1007     }
1008   } else if (width == 32) {
1009     gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
1010
1011     for (i = 0; i < samples; i++) {
1012       for (j = 0; j < channels; j++) {
1013         *outbuffer++ = (gint32) buffer[j][i];
1014       }
1015     }
1016   } else {
1017     g_assert_not_reached ();
1018   }
1019
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)));
1026
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;
1032     }
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;
1036   } else {
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;
1043     ret = GST_FLOW_OK;
1044   }
1045
1046   if (ret != GST_FLOW_OK) {
1047     GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1048         gst_flow_get_name (ret));
1049   }
1050
1051 done:
1052
1053
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;
1059
1060   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1061 }
1062
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)
1067 {
1068   return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1069 }
1070
1071 static void
1072 gst_flac_dec_loop (GstPad * sinkpad)
1073 {
1074   GstFlacDec *flacdec;
1075   FLAC__StreamDecoderState s;
1076   FLAC__StreamDecoderInitStatus is;
1077
1078   flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1079
1080   GST_LOG_OBJECT (flacdec, "entering loop");
1081
1082   if (flacdec->eos) {
1083     GST_DEBUG_OBJECT (flacdec, "Seeked after end of file");
1084
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;
1089     }
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;
1094     }
1095
1096     if (flacdec->tags) {
1097       gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
1098           flacdec->tags);
1099       flacdec->tags = NULL;
1100     }
1101
1102     if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1103       goto eos_and_pause;
1104     } else {
1105       goto segment_done_and_pause;
1106     }
1107   }
1108
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)
1116       goto analyze_state;
1117
1118     /*    FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1119     flacdec->init = FALSE;
1120   }
1121
1122   flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1123
1124   flacdec->last_flow = GST_FLOW_OK;
1125
1126   GST_LOG_OBJECT (flacdec, "processing single");
1127   FLAC__stream_decoder_process_single (flacdec->decoder);
1128
1129 analyze_state:
1130
1131   GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1132   s = FLAC__stream_decoder_get_state (flacdec->decoder);
1133   switch (s) {
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:
1138     {
1139       GST_DEBUG_OBJECT (flacdec, "everything ok");
1140
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)));
1147         goto eos_and_pause;
1148       } else if (flacdec->last_flow == GST_FLOW_UNEXPECTED) {
1149         goto eos_and_pause;
1150       } else if (flacdec->last_flow != GST_FLOW_OK) {
1151         goto pause;
1152       }
1153
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");
1159
1160         if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1161           goto eos_and_pause;
1162         } else {
1163           goto segment_done_and_pause;
1164         }
1165
1166         g_assert_not_reached ();
1167       }
1168
1169       return;
1170     }
1171
1172     case FLAC__STREAM_DECODER_END_OF_STREAM:{
1173       GST_DEBUG_OBJECT (flacdec, "EOS");
1174       FLAC__stream_decoder_reset (flacdec->decoder);
1175
1176       if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1177         if (flacdec->segment.duration > 0) {
1178           flacdec->segment.stop = flacdec->segment.duration;
1179         } else {
1180           flacdec->segment.stop = flacdec->segment.last_stop;
1181         }
1182         goto segment_done_and_pause;
1183       }
1184
1185       goto eos_and_pause;
1186     }
1187
1188       /* gst_flac_dec_read_seekable() returned ABORTED */
1189     case FLAC__STREAM_DECODER_ABORTED:
1190     {
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);
1199         goto pause;
1200       }
1201       /* fall through */
1202     }
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:
1207     default:{
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]));
1212       goto eos_and_pause;
1213     }
1214   }
1215
1216   return;
1217
1218 segment_done_and_pause:
1219   {
1220     gint64 stop_time;
1221
1222     stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1223         GST_SECOND, flacdec->sample_rate);
1224
1225     GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1226         GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1227
1228     gst_element_post_message (GST_ELEMENT (flacdec),
1229         gst_message_new_segment_done (GST_OBJECT (flacdec),
1230             GST_FORMAT_TIME, stop_time));
1231
1232     goto pause;
1233   }
1234 eos_and_pause:
1235   {
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 */
1240   }
1241 pause:
1242   {
1243     GST_DEBUG_OBJECT (flacdec, "pausing");
1244     gst_pad_pause_task (sinkpad);
1245     return;
1246   }
1247 }
1248
1249 static gboolean
1250 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1251 {
1252   GstFlacDec *dec;
1253   gboolean res;
1254
1255   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1256
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);
1262       }
1263       res = gst_pad_push_event (dec->srcpad, event);
1264       break;
1265     }
1266     case GST_EVENT_NEWSEGMENT:{
1267       GstFormat fmt;
1268       gboolean update;
1269       gdouble rate, applied_rate;
1270       gint64 cur, stop, time;
1271
1272       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1273           &fmt, &cur, &stop, &time);
1274
1275       if (fmt == GST_FORMAT_TIME) {
1276         GstFormat dformat = GST_FORMAT_DEFAULT;
1277
1278         GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1279         dec->framed = TRUE;
1280         res = gst_pad_push_event (dec->srcpad, event);
1281
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);
1290         } else {
1291           GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1292         }
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;
1297
1298         /* prepare generic newsegment event, for some reason our metadata
1299          * callback where we usually set this up is not being called in
1300          * push mode */
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);
1305
1306         gst_event_unref (event);
1307         res = TRUE;
1308       }
1309       break;
1310     }
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);
1317         }
1318         FLAC__stream_decoder_flush (dec->decoder);
1319       }
1320       gst_adapter_clear (dec->adapter);
1321       res = gst_pad_push_event (dec->srcpad, event);
1322       break;
1323     }
1324     default:
1325       res = gst_pad_event_default (pad, event);
1326       break;
1327   }
1328
1329   gst_object_unref (dec);
1330
1331   return res;
1332 }
1333
1334 static gboolean
1335 gst_flac_dec_chain_parse_headers (GstFlacDec * dec)
1336 {
1337   guint8 marker[4];
1338   guint avail, off;
1339
1340   avail = gst_adapter_available (dec->adapter);
1341   if (avail < 4)
1342     return FALSE;
1343
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 */
1348   }
1349
1350   GST_DEBUG_OBJECT (dec, "fLaC header          : len           4 @ %7u", 0);
1351
1352   off = 4;
1353   while (avail > (off + 1 + 3)) {
1354     gboolean is_last;
1355     guint8 mb_hdr[4];
1356     guint len, block_type;
1357
1358     gst_adapter_copy (dec->adapter, mb_hdr, off, 4);
1359
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)" : "");
1365     off += 4 + len;
1366
1367     if (is_last)
1368       break;
1369
1370     if (off >= avail) {
1371       GST_LOG_OBJECT (dec, "Need more data: next offset %u > avail %u", off,
1372           avail);
1373       return FALSE;
1374     }
1375   }
1376
1377   /* want metadata blocks plus at least one frame */
1378   return (off + FLAC__MAX_BLOCK_SIZE >= avail);
1379 }
1380
1381 static GstFlowReturn
1382 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1383 {
1384   FLAC__StreamDecoderInitStatus s;
1385   GstFlacDec *dec;
1386   gboolean got_audio_frame;
1387
1388   dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1389
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));
1393
1394   if (dec->init) {
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;
1403     }
1404     GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1405     dec->init = FALSE;
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);
1410   }
1411
1412   if (dec->framed) {
1413     gint64 unused;
1414
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);
1418
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);
1424       } else {
1425         GstFormat dformat = GST_FORMAT_DEFAULT;
1426
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;
1432       }
1433     }
1434   } else {
1435     dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1436     got_audio_frame = TRUE;
1437   }
1438
1439   gst_adapter_push (dec->adapter, buf);
1440   buf = NULL;
1441
1442   dec->last_flow = GST_FLOW_OK;
1443
1444   if (!dec->framed) {
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");
1448         goto out;
1449       }
1450       GST_INFO_OBJECT (dec, "have all metadata blocks now");
1451       dec->got_headers = TRUE;
1452     }
1453
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");
1468         break;
1469       }
1470
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;
1475         break;
1476       }
1477     }
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");
1484     }
1485   } else {
1486     GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1487   }
1488
1489 out:
1490
1491   return dec->last_flow;
1492 }
1493
1494 static gboolean
1495 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1496     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1497 {
1498   gboolean res = TRUE;
1499
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");
1503     return FALSE;
1504   }
1505
1506   switch (src_format) {
1507     case GST_FORMAT_BYTES:{
1508       res = FALSE;
1509       break;
1510     }
1511     case GST_FORMAT_DEFAULT:
1512       switch (*dest_format) {
1513         case GST_FORMAT_BYTES:
1514           res = FALSE;
1515           break;
1516         case GST_FORMAT_TIME:
1517           /* granulepos = sample */
1518           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1519               dec->sample_rate);
1520           break;
1521         default:
1522           res = FALSE;
1523           break;
1524       }
1525       break;
1526     case GST_FORMAT_TIME:
1527       switch (*dest_format) {
1528         case GST_FORMAT_BYTES:
1529           res = FALSE;
1530           break;
1531         case GST_FORMAT_DEFAULT:
1532           *dest_value = gst_util_uint64_scale_int (src_value,
1533               dec->sample_rate, GST_SECOND);
1534           break;
1535         default:
1536           res = FALSE;
1537           break;
1538       }
1539       break;
1540     default:
1541       res = FALSE;
1542       break;
1543   }
1544   return res;
1545 }
1546
1547 static const GstQueryType *
1548 gst_flac_dec_get_sink_query_types (GstPad * pad)
1549 {
1550   static const GstQueryType types[] = {
1551     GST_QUERY_CONVERT,
1552     0,
1553   };
1554
1555   return types;
1556 }
1557
1558 static gboolean
1559 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1560 {
1561   GstFlacDec *dec;
1562   gboolean res = FALSE;
1563
1564   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1565
1566   GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1567
1568   switch (GST_QUERY_TYPE (query)) {
1569     case GST_QUERY_CONVERT:{
1570       GstFormat src_fmt, dest_fmt;
1571
1572       gint64 src_val, dest_val;
1573
1574       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1575
1576       res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1577           &dest_val);
1578
1579       if (res) {
1580         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1581       }
1582       GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1583       break;
1584     }
1585
1586     default:{
1587       res = gst_pad_query_default (pad, query);
1588       break;
1589     }
1590   }
1591
1592   gst_object_unref (dec);
1593   return res;
1594 }
1595
1596 static gboolean
1597 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1598     GstFormat * dest_format, gint64 * dest_value)
1599 {
1600   GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1601   gboolean res = TRUE;
1602   guint bytes_per_sample;
1603   guint scale = 1;
1604
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");
1609     return FALSE;
1610   }
1611
1612   bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1613
1614   switch (src_format) {
1615     case GST_FORMAT_BYTES:{
1616       switch (*dest_format) {
1617         case GST_FORMAT_DEFAULT:
1618           *dest_value =
1619               gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1620           break;
1621         case GST_FORMAT_TIME:
1622         {
1623           gint byterate = bytes_per_sample * flacdec->sample_rate;
1624
1625           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1626               byterate);
1627           break;
1628         }
1629         default:
1630           res = FALSE;
1631       }
1632       break;
1633     }
1634     case GST_FORMAT_DEFAULT:
1635       switch (*dest_format) {
1636         case GST_FORMAT_BYTES:
1637           *dest_value = src_value * bytes_per_sample;
1638           break;
1639         case GST_FORMAT_TIME:
1640           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1641               flacdec->sample_rate);
1642           break;
1643         default:
1644           res = FALSE;
1645       }
1646       break;
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);
1654           break;
1655         default:
1656           res = FALSE;
1657       }
1658       break;
1659     default:
1660       res = FALSE;
1661   }
1662   return res;
1663 }
1664
1665 static const GstQueryType *
1666 gst_flac_dec_get_src_query_types (GstPad * pad)
1667 {
1668   static const GstQueryType types[] = {
1669     GST_QUERY_POSITION,
1670     GST_QUERY_DURATION,
1671     GST_QUERY_CONVERT,
1672     GST_QUERY_SEEKING,
1673     0,
1674   };
1675
1676   return types;
1677 }
1678
1679 static gboolean
1680 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1681 {
1682   GstFlacDec *flacdec;
1683   gboolean res = TRUE;
1684   GstPad *peer;
1685
1686   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1687   peer = gst_pad_get_peer (flacdec->sinkpad);
1688
1689   switch (GST_QUERY_TYPE (query)) {
1690     case GST_QUERY_POSITION:{
1691       GstFormat fmt;
1692       gint64 pos;
1693
1694       gst_query_parse_position (query, &fmt, NULL);
1695
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)))
1698         break;
1699
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));
1705           res = FALSE;
1706           goto done;
1707         }
1708       } else {
1709         pos = flacdec->segment.last_stop;
1710       }
1711
1712       gst_query_set_position (query, fmt, pos);
1713
1714       GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1715           " (format: %s)", pos, gst_format_get_name (fmt));
1716
1717       res = TRUE;
1718       break;
1719     }
1720
1721     case GST_QUERY_DURATION:{
1722       GstFormat fmt;
1723       gint64 len;
1724
1725       gst_query_parse_duration (query, &fmt, NULL);
1726
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));
1732         res = TRUE;
1733         goto done;
1734       }
1735
1736       if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1737         GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1738         res = FALSE;
1739         goto done;
1740       }
1741
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));
1748           res = FALSE;
1749           goto done;
1750         }
1751       } else {
1752         len = flacdec->segment.duration;
1753       }
1754
1755       gst_query_set_duration (query, fmt, len);
1756
1757       GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1758           " (format: %s)", len, gst_format_get_name (fmt));
1759
1760       res = TRUE;
1761       break;
1762     }
1763
1764     case GST_QUERY_CONVERT:{
1765       GstFormat src_fmt, dest_fmt;
1766       gint64 src_val, dest_val;
1767
1768       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1769
1770       res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1771           &dest_val);
1772
1773       if (res) {
1774         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1775       }
1776
1777       break;
1778     }
1779     case GST_QUERY_SEEKING:{
1780       GstFormat fmt;
1781       gboolean seekable = FALSE;
1782
1783       res = TRUE;
1784       /* If upstream can handle the query we're done */
1785       seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1786       if (seekable)
1787         gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1788       if (seekable)
1789         goto done;
1790
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);
1795       } else {
1796         gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1797       }
1798       break;
1799     }
1800
1801     default:{
1802       res = gst_pad_query_default (pad, query);
1803       break;
1804     }
1805   }
1806
1807 done:
1808
1809   if (peer)
1810     gst_object_unref (peer);
1811
1812   gst_object_unref (flacdec);
1813
1814   return res;
1815 }
1816
1817 static gboolean
1818 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1819 {
1820   FLAC__bool seek_ok;
1821   GstSeekFlags seek_flags;
1822   GstSeekType start_type;
1823   GstSeekType stop_type;
1824   GstSegment segment;
1825   GstFormat seek_format;
1826   gboolean only_update = FALSE;
1827   gboolean flush;
1828   gdouble rate;
1829   gint64 start, last_stop;
1830   gint64 stop;
1831
1832   if (flacdec->streaming) {
1833     GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1834     return FALSE;
1835   }
1836
1837   gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1838       &start, &stop_type, &stop);
1839
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");
1843     return FALSE;
1844   }
1845
1846   if (rate < 0.0) {
1847     GST_DEBUG_OBJECT (flacdec,
1848         "only forward playback supported, rate %f not allowed", rate);
1849     return FALSE;
1850   }
1851
1852   if (seek_format != GST_FORMAT_DEFAULT) {
1853     GstFormat target_format = GST_FORMAT_DEFAULT;
1854
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");
1859       return FALSE;
1860     }
1861
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");
1866       return FALSE;
1867     }
1868   }
1869
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;
1874   } else {
1875     flacdec->eos = FALSE;
1876   }
1877
1878   flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1879
1880   if (flush) {
1881     /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1882      * this. */
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 ());
1886   } else {
1887     /* non flushing seek, pause the task */
1888     GST_DEBUG_OBJECT (flacdec, "stopping task");
1889     gst_pad_stop_task (flacdec->sinkpad);
1890   }
1891
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);
1897
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;
1904   }
1905   gst_buffer_replace (&flacdec->pending, NULL);
1906   flacdec->pending_samples = 0;
1907
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;
1911
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);
1916
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));
1925
1926   GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1927       flacdec->segment.last_stop);
1928
1929   /* flush sinkpad again because we need to pull and push buffers while doing
1930    * the seek */
1931   if (flush) {
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 ());
1935   }
1936
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;
1940
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);
1946   } else {
1947     GST_LOG_OBJECT (flacdec, "not seeking, seeked after end of file");
1948     seek_ok = TRUE;
1949   }
1950
1951   flacdec->seeking = FALSE;
1952
1953   GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1954       flacdec->segment.last_stop);
1955
1956   if (!seek_ok) {
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);
1966
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);
1970     last_stop =
1971         gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1972         flacdec->sample_rate);
1973
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);
1982   }
1983
1984   if (seek_ok) {
1985     /* seek succeeded, flacdec->segment contains the new positions */
1986     GST_DEBUG_OBJECT (flacdec, "seek successful");
1987   }
1988
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);
1995
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);
2001   else
2002     stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
2003         flacdec->sample_rate);
2004
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));
2011   }
2012
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);
2028   }
2029
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);
2036
2037   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
2038
2039   return seek_ok;
2040 }
2041
2042 static gboolean
2043 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
2044 {
2045   gboolean res = TRUE;
2046   GstFlacDec *flacdec;
2047
2048   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
2049
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 */
2058       if (!res) {
2059         GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
2060         res = gst_flac_dec_handle_seek_event (flacdec, event);
2061       }
2062       gst_event_unref (event);
2063       break;
2064     }
2065     default:
2066       res = gst_pad_event_default (pad, event);
2067       break;
2068   }
2069
2070   gst_object_unref (flacdec);
2071
2072   return res;
2073 }
2074
2075 static gboolean
2076 gst_flac_dec_sink_activate (GstPad * sinkpad)
2077 {
2078   if (gst_pad_check_pull_range (sinkpad))
2079     return gst_pad_activate_pull (sinkpad, TRUE);
2080
2081   return gst_pad_activate_push (sinkpad, TRUE);
2082 }
2083
2084 static gboolean
2085 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
2086 {
2087   GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
2088
2089   if (active) {
2090     gst_flac_dec_setup_decoder (dec);
2091     dec->streaming = TRUE;
2092     dec->got_headers = FALSE;
2093   }
2094   return TRUE;
2095 }
2096
2097 static gboolean
2098 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
2099 {
2100   gboolean res;
2101
2102   if (active) {
2103     GstFlacDec *flacdec;
2104
2105     flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
2106
2107     flacdec->offset = 0;
2108     gst_flac_dec_setup_decoder (flacdec);
2109     flacdec->running = TRUE;
2110     flacdec->streaming = FALSE;
2111
2112     res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
2113         sinkpad);
2114   } else {
2115     res = gst_pad_stop_task (sinkpad);
2116   }
2117   return res;
2118 }
2119
2120 static GstStateChangeReturn
2121 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2122 {
2123   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2124   GstFlacDec *flacdec = GST_FLAC_DEC (element);
2125
2126   switch (transition) {
2127     case GST_STATE_CHANGE_READY_TO_PAUSED:
2128       flacdec->eos = FALSE;
2129       flacdec->seeking = FALSE;
2130       flacdec->channels = 0;
2131       flacdec->depth = 0;
2132       flacdec->width = 0;
2133       flacdec->sample_rate = 0;
2134       gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2135       break;
2136     default:
2137       break;
2138   }
2139
2140   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2141   if (ret == GST_STATE_CHANGE_FAILURE)
2142     return ret;
2143
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);
2148       break;
2149     default:
2150       break;
2151   }
2152
2153   return ret;
2154 }