various: fix pad template leaks
[platform/upstream/gstreamer.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_static_pad_template (element_class,
182       &flac_dec_src_factory);
183   gst_element_class_add_static_pad_template (element_class,
184       &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] & 0xFC) != 0xF8)
412     return FALSE;
413   if (data[1] & 1) {
414     GST_WARNING_OBJECT (flacdec, "Variable block size FLAC unsupported");
415     return FALSE;
416   }
417
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        */
423
424   GST_LOG_OBJECT (flacdec,
425       "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
426
427   if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
428     return FALSE;
429   }
430
431   /* read block size from end of header? */
432   if (bs == 6)
433     bs_from_end = 8;
434   else if (bs == 7)
435     bs_from_end = 16;
436
437   /* read sample rate from end of header? */
438   if (sr == 0x0C)
439     sr_from_end = 8;
440   else if (sr == 0x0D || sr == 0x0E)
441     sr_from_end = 16;
442
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
445    * above.
446    */
447   val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
448
449   if (val == (guint32) - 1 || val == (guint32) - 2) {
450     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
451     return FALSE;
452   }
453
454   headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
455       (bs_from_end / 8) + (sr_from_end / 8);
456
457   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
458     GST_LOG_OBJECT (flacdec, "invalid checksum");
459     return FALSE;
460   }
461
462   if (flacdec->min_blocksize == flacdec->max_blocksize) {
463     *last_sample_num = (val + 1) * flacdec->min_blocksize;
464   } else {
465     *last_sample_num = 0;       /* FIXME: + length of last block in samples */
466   }
467
468   /* FIXME: only valid for fixed block size streams */
469   GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
470       *last_sample_num);
471
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));
476   }
477
478   return TRUE;
479 }
480
481 #define SCANBLOCK_SIZE  (64*1024)
482
483 static void
484 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
485 {
486   GstFormat format = GST_FORMAT_BYTES;
487   gint64 file_size, offset;
488
489   GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
490
491   if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
492     GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
493     return;
494   }
495
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");
499     return;
500   }
501
502   GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
503
504   offset = file_size - 1;
505   while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
506     GstFlowReturn flow;
507     GstBuffer *buf = NULL;
508     guint8 *data;
509     guint size;
510
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);
515
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));
519       return;
520     }
521
522     size = GST_BUFFER_SIZE (buf);
523     data = GST_BUFFER_DATA (buf);
524
525     while (size > 16) {
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);
530         return;
531       }
532       ++data;
533       --size;
534     }
535
536     gst_buffer_unref (buf);
537   }
538 }
539
540 static void
541 gst_flac_extract_picture_buffer (GstFlacDec * dec,
542     const FLAC__StreamMetadata * metadata)
543 {
544   FLAC__StreamMetadata_Picture picture;
545   GstTagList *tags;
546
547   g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
548
549   GST_LOG_OBJECT (dec, "Got PICTURE block");
550   picture = metadata->data.picture;
551
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);
555
556   tags = gst_tag_list_new ();
557
558   gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
559       picture.data_length, picture.type);
560
561   if (!gst_tag_list_is_empty (tags)) {
562     gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
563   } else {
564     GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
565     gst_tag_list_free (tags);
566   }
567 }
568
569 static void
570 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
571     const FLAC__StreamMetadata * metadata, void *client_data)
572 {
573   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
574
575   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
576
577   switch (metadata->type) {
578     case FLAC__METADATA_TYPE_STREAMINFO:{
579       gint64 samples;
580       guint depth;
581
582       samples = metadata->data.stream_info.total_samples;
583
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;
589
590       if (depth < 9)
591         flacdec->width = 8;
592       else if (depth < 17)
593         flacdec->width = 16;
594       else
595         flacdec->width = 32;
596
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,
602           flacdec->width);
603
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);
607       }
608
609       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
610
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) {
614         gint64 duration;
615
616         gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
617             samples);
618
619         /* convert duration to time */
620         duration = gst_util_uint64_scale_int (samples, GST_SECOND,
621             flacdec->sample_rate);
622
623         /* fixme, at this time we could seek to the queued seek event if we have
624          * any */
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);
631       }
632       break;
633     }
634     case FLAC__METADATA_TYPE_PICTURE:{
635       gst_flac_extract_picture_buffer (flacdec, metadata);
636       break;
637     }
638     case FLAC__METADATA_TYPE_VORBIS_COMMENT:
639       gst_flac_dec_update_metadata (flacdec, metadata);
640       break;
641     default:
642       break;
643   }
644 }
645
646 static void
647 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
648     FLAC__StreamDecoderErrorStatus status, void *client_data)
649 {
650   const gchar *error;
651   GstFlacDec *dec;
652
653   dec = GST_FLAC_DEC (client_data);
654
655   switch (status) {
656     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
657       /* Ignore this error and keep processing */
658       return;
659     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
660       error = "bad header";
661       break;
662     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
663       error = "CRC mismatch";
664       break;
665     default:
666       error = "unknown error";
667       break;
668   }
669
670   GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
671   dec->last_flow = GST_FLOW_ERROR;
672 }
673
674 static FLAC__StreamDecoderSeekStatus
675 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
676     FLAC__uint64 position, void *client_data)
677 {
678   GstFlacDec *flacdec;
679
680   flacdec = GST_FLAC_DEC (client_data);
681
682   GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
683   flacdec->offset = position;
684
685   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
686 }
687
688 static FLAC__StreamDecoderTellStatus
689 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
690     FLAC__uint64 * position, void *client_data)
691 {
692   GstFlacDec *flacdec;
693
694   flacdec = GST_FLAC_DEC (client_data);
695
696   *position = flacdec->offset;
697
698   GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
699
700   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
701 }
702
703 static FLAC__StreamDecoderLengthStatus
704 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
705     FLAC__uint64 * length, void *client_data)
706 {
707   GstFlacDec *flacdec;
708   GstFormat fmt = GST_FORMAT_BYTES;
709   gint64 len;
710   GstPad *peer;
711
712   flacdec = GST_FLAC_DEC (client_data);
713
714   if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
715     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
716
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;
721
722   *length = len;
723
724   GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
725       (gint64) * length);
726
727   return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
728 }
729
730 static FLAC__bool
731 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
732 {
733   GstFlacDec *flacdec;
734   GstFormat fmt;
735   GstPad *peer;
736   gboolean ret = FALSE;
737   gint64 len;
738
739   flacdec = GST_FLAC_DEC (client_data);
740
741   if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
742     GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
743     return TRUE;
744   }
745
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);
752     ret = TRUE;
753   }
754
755   gst_object_unref (peer);
756
757   return ret;
758 }
759
760 static FLAC__StreamDecoderReadStatus
761 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
762     FLAC__byte buffer[], size_t * bytes, void *client_data)
763 {
764   GstFlowReturn flow;
765   GstFlacDec *flacdec;
766   GstBuffer *buf;
767
768   flacdec = GST_FLAC_DEC (client_data);
769
770   flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
771
772   GST_PAD_STREAM_LOCK (flacdec->sinkpad);
773   flacdec->pull_flow = flow;
774   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
775
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;
780     else
781       return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
782   }
783
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;
790
791   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
792 }
793
794 static FLAC__StreamDecoderReadStatus
795 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
796     FLAC__byte buffer[], size_t * bytes, void *client_data)
797 {
798   GstFlacDec *dec = GST_FLAC_DEC (client_data);
799   guint len;
800
801   len = MIN (gst_adapter_available (dec->adapter), *bytes);
802
803   if (len == 0) {
804     GST_LOG_OBJECT (dec, "0 bytes available at the moment");
805     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
806   }
807
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);
811   *bytes = len;
812
813   gst_adapter_flush (dec->adapter, len);
814
815   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
816 }
817
818 static FLAC__StreamDecoderWriteStatus
819 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
820     const FLAC__int32 * const buffer[])
821 {
822   GstFlowReturn ret = GST_FLOW_OK;
823   GstBuffer *outbuf;
824   guint depth = frame->header.bits_per_sample;
825   guint width;
826   guint sample_rate = frame->header.sample_rate;
827   guint channels = frame->header.channels;
828   guint samples = frame->header.blocksize;
829   guint j, i;
830   GstClockTime next;
831
832   GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
833
834   /* if a DEFAULT segment is configured, don't send samples past the end
835    * of the segment */
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);
843   }
844
845   switch (depth) {
846     case 8:
847       width = 8;
848       break;
849     case 12:
850     case 16:
851       width = 16;
852       break;
853     case 20:
854     case 24:
855     case 32:
856       width = 32;
857       break;
858     case 0:
859       if (flacdec->depth < 4 || flacdec->depth > 32) {
860         GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
861             flacdec->depth);
862         ret = GST_FLOW_ERROR;
863         goto done;
864       }
865
866       depth = flacdec->depth;
867       if (depth < 9)
868         width = 8;
869       else if (depth < 17)
870         width = 16;
871       else
872         width = 32;
873
874       break;
875     default:
876       GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
877       ret = GST_FLOW_ERROR;
878       goto done;
879   }
880
881   if (sample_rate == 0) {
882     if (flacdec->sample_rate != 0) {
883       sample_rate = flacdec->sample_rate;
884     } else {
885       GST_ERROR_OBJECT (flacdec, "unknown sample rate");
886       ret = GST_FLOW_ERROR;
887       goto done;
888     }
889   }
890
891   if (!GST_PAD_CAPS (flacdec->srcpad)) {
892     GstCaps *caps;
893
894     GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
895         frame->header.sample_rate, channels);
896
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);
904
905     if (channels > 2) {
906       GstStructure *s = gst_caps_get_structure (caps, 0);
907
908       gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
909     }
910
911     flacdec->depth = depth;
912     flacdec->width = width;
913     flacdec->channels = channels;
914     flacdec->sample_rate = sample_rate;
915
916     gst_pad_set_caps (flacdec->srcpad, caps);
917     gst_caps_unref (caps);
918   }
919
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;
924   }
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;
929   }
930
931   if (flacdec->tags) {
932     gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
933         flacdec->tags);
934     flacdec->tags = NULL;
935   }
936
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);
954     }
955
956     outbuf = flacdec->pending = NULL;
957     flacdec->segment.last_stop += flacdec->pending_samples;
958     flacdec->pending_samples = 0;
959   }
960
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;
966   } else {
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);
971
972     if (ret != GST_FLOW_OK) {
973       GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
974           gst_flow_get_name (ret));
975       goto done;
976     }
977   }
978
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     /* note the + 1, as the granpos is the presentation time of the last sample,
982        whereas the last stop represents the end time of that sample */
983     flacdec->segment.last_stop = flacdec->cur_granulepos - samples + 1;
984     GST_LOG_OBJECT (flacdec, "granulepos = %" G_GINT64_FORMAT ", samples = %u",
985         flacdec->cur_granulepos, samples);
986   }
987
988   GST_BUFFER_TIMESTAMP (outbuf) =
989       gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
990       frame->header.sample_rate);
991
992   /* get next timestamp to calculate the duration */
993   next = gst_util_uint64_scale_int (flacdec->segment.last_stop + samples,
994       GST_SECOND, frame->header.sample_rate);
995
996   GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
997
998   if (width == 8) {
999     gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
1000
1001     for (i = 0; i < samples; i++) {
1002       for (j = 0; j < channels; j++) {
1003         *outbuffer++ = (gint8) buffer[j][i];
1004       }
1005     }
1006   } else if (width == 16) {
1007     gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
1008
1009     for (i = 0; i < samples; i++) {
1010       for (j = 0; j < channels; j++) {
1011         *outbuffer++ = (gint16) buffer[j][i];
1012       }
1013     }
1014   } else if (width == 32) {
1015     gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
1016
1017     for (i = 0; i < samples; i++) {
1018       for (j = 0; j < channels; j++) {
1019         *outbuffer++ = (gint32) buffer[j][i];
1020       }
1021     }
1022   } else {
1023     g_assert_not_reached ();
1024   }
1025
1026   if (!flacdec->seeking) {
1027     GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
1028         " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
1029         samples, GST_BUFFER_OFFSET (outbuf),
1030         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1031         GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1032
1033     if (flacdec->discont) {
1034       GST_DEBUG_OBJECT (flacdec, "marking discont");
1035       outbuf = gst_buffer_make_metadata_writable (outbuf);
1036       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1037       flacdec->discont = FALSE;
1038     }
1039     ret = gst_pad_push (flacdec->srcpad, outbuf);
1040     GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
1041     flacdec->segment.last_stop += samples;
1042   } else {
1043     GST_DEBUG_OBJECT (flacdec,
1044         "not pushing %d samples at offset %" G_GINT64_FORMAT
1045         " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
1046     gst_buffer_replace (&flacdec->pending, outbuf);
1047     gst_buffer_unref (outbuf);
1048     flacdec->pending_samples = samples;
1049     ret = GST_FLOW_OK;
1050   }
1051
1052   if (ret != GST_FLOW_OK) {
1053     GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1054         gst_flow_get_name (ret));
1055   }
1056
1057 done:
1058
1059
1060   /* we act on the flow return value later in the loop function, as we don't
1061    * want to mess up the internal decoder state by returning ABORT when the
1062    * error is in fact non-fatal (like a pad in flushing mode) and we want
1063    * to continue later. So just pretend everything's dandy and act later. */
1064   flacdec->last_flow = ret;
1065
1066   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1067 }
1068
1069 static FLAC__StreamDecoderWriteStatus
1070 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
1071     const FLAC__Frame * frame,
1072     const FLAC__int32 * const buffer[], void *client_data)
1073 {
1074   return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1075 }
1076
1077 static void
1078 gst_flac_dec_loop (GstPad * sinkpad)
1079 {
1080   GstFlacDec *flacdec;
1081   FLAC__StreamDecoderState s;
1082   FLAC__StreamDecoderInitStatus is;
1083
1084   flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1085
1086   GST_LOG_OBJECT (flacdec, "entering loop");
1087
1088   if (flacdec->eos) {
1089     GST_DEBUG_OBJECT (flacdec, "Seeked after end of file");
1090
1091     if (flacdec->close_segment) {
1092       GST_DEBUG_OBJECT (flacdec, "pushing close segment");
1093       gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
1094       flacdec->close_segment = NULL;
1095     }
1096     if (flacdec->start_segment) {
1097       GST_DEBUG_OBJECT (flacdec, "pushing start segment");
1098       gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
1099       flacdec->start_segment = NULL;
1100     }
1101
1102     if (flacdec->tags) {
1103       gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
1104           flacdec->tags);
1105       flacdec->tags = NULL;
1106     }
1107
1108     if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1109       goto eos_and_pause;
1110     } else {
1111       goto segment_done_and_pause;
1112     }
1113   }
1114
1115   if (flacdec->init) {
1116     GST_DEBUG_OBJECT (flacdec, "initializing new decoder");
1117     is = FLAC__stream_decoder_init_stream (flacdec->decoder,
1118         gst_flac_dec_read_seekable, gst_flac_dec_seek, gst_flac_dec_tell,
1119         gst_flac_dec_length, gst_flac_dec_eof, gst_flac_dec_write_stream,
1120         gst_flac_dec_metadata_cb, gst_flac_dec_error_cb, flacdec);
1121     if (is != FLAC__STREAM_DECODER_INIT_STATUS_OK)
1122       goto analyze_state;
1123
1124     /*    FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1125     flacdec->init = FALSE;
1126   }
1127
1128   flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1129
1130   flacdec->last_flow = GST_FLOW_OK;
1131
1132   GST_LOG_OBJECT (flacdec, "processing single");
1133   FLAC__stream_decoder_process_single (flacdec->decoder);
1134
1135 analyze_state:
1136
1137   GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1138   s = FLAC__stream_decoder_get_state (flacdec->decoder);
1139   switch (s) {
1140     case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
1141     case FLAC__STREAM_DECODER_READ_METADATA:
1142     case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
1143     case FLAC__STREAM_DECODER_READ_FRAME:
1144     {
1145       GST_DEBUG_OBJECT (flacdec, "everything ok");
1146
1147       if (flacdec->last_flow < GST_FLOW_UNEXPECTED ||
1148           flacdec->last_flow == GST_FLOW_NOT_LINKED) {
1149         GST_ELEMENT_ERROR (flacdec, STREAM, FAILED,
1150             (_("Internal data stream error.")),
1151             ("stream stopped, reason %s",
1152                 gst_flow_get_name (flacdec->last_flow)));
1153         goto eos_and_pause;
1154       } else if (flacdec->last_flow == GST_FLOW_UNEXPECTED) {
1155         goto eos_and_pause;
1156       } else if (flacdec->last_flow != GST_FLOW_OK) {
1157         goto pause;
1158       }
1159
1160       /* check if we're at the end of a configured segment */
1161       if (flacdec->segment.stop != -1 &&
1162           flacdec->segment.last_stop > 0 &&
1163           flacdec->segment.last_stop >= flacdec->segment.stop) {
1164         GST_DEBUG_OBJECT (flacdec, "reached end of the configured segment");
1165
1166         if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1167           goto eos_and_pause;
1168         } else {
1169           goto segment_done_and_pause;
1170         }
1171
1172         g_assert_not_reached ();
1173       }
1174
1175       return;
1176     }
1177
1178     case FLAC__STREAM_DECODER_END_OF_STREAM:{
1179       GST_DEBUG_OBJECT (flacdec, "EOS");
1180       FLAC__stream_decoder_reset (flacdec->decoder);
1181
1182       if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1183         if (flacdec->segment.duration > 0) {
1184           flacdec->segment.stop = flacdec->segment.duration;
1185         } else {
1186           flacdec->segment.stop = flacdec->segment.last_stop;
1187         }
1188         goto segment_done_and_pause;
1189       }
1190
1191       goto eos_and_pause;
1192     }
1193
1194       /* gst_flac_dec_read_seekable() returned ABORTED */
1195     case FLAC__STREAM_DECODER_ABORTED:
1196     {
1197       GST_INFO_OBJECT (flacdec, "read aborted: last pull_range flow = %s",
1198           gst_flow_get_name (flacdec->pull_flow));
1199       if (flacdec->pull_flow == GST_FLOW_WRONG_STATE) {
1200         /* it seems we need to flush the decoder here to reset the decoder
1201          * state after the abort for FLAC__stream_decoder_seek_absolute()
1202          * to work properly */
1203         GST_DEBUG_OBJECT (flacdec, "flushing decoder to reset decoder state");
1204         FLAC__stream_decoder_flush (flacdec->decoder);
1205         goto pause;
1206       }
1207       /* fall through */
1208     }
1209     case FLAC__STREAM_DECODER_OGG_ERROR:
1210     case FLAC__STREAM_DECODER_SEEK_ERROR:
1211     case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
1212     case FLAC__STREAM_DECODER_UNINITIALIZED:
1213     default:{
1214       /* fixme: this error sucks -- should try to figure out when/if an more
1215          specific error was already sent via the callback */
1216       GST_ELEMENT_ERROR (flacdec, STREAM, DECODE, (NULL),
1217           ("%s", FLAC__StreamDecoderStateString[s]));
1218       goto eos_and_pause;
1219     }
1220   }
1221
1222   return;
1223
1224 segment_done_and_pause:
1225   {
1226     gint64 stop_time;
1227
1228     stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1229         GST_SECOND, flacdec->sample_rate);
1230
1231     GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1232         GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1233
1234     gst_element_post_message (GST_ELEMENT (flacdec),
1235         gst_message_new_segment_done (GST_OBJECT (flacdec),
1236             GST_FORMAT_TIME, stop_time));
1237
1238     goto pause;
1239   }
1240 eos_and_pause:
1241   {
1242     GST_DEBUG_OBJECT (flacdec, "sending EOS event");
1243     flacdec->running = FALSE;
1244     gst_pad_push_event (flacdec->srcpad, gst_event_new_eos ());
1245     /* fall through to pause */
1246   }
1247 pause:
1248   {
1249     GST_DEBUG_OBJECT (flacdec, "pausing");
1250     gst_pad_pause_task (sinkpad);
1251     return;
1252   }
1253 }
1254
1255 static gboolean
1256 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1257 {
1258   GstFlacDec *dec;
1259   gboolean res;
1260
1261   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1262
1263   switch (GST_EVENT_TYPE (event)) {
1264     case GST_EVENT_FLUSH_STOP:{
1265       if (dec->init == FALSE) {
1266         FLAC__stream_decoder_flush (dec->decoder);
1267         gst_adapter_clear (dec->adapter);
1268       }
1269       res = gst_pad_push_event (dec->srcpad, event);
1270       break;
1271     }
1272     case GST_EVENT_NEWSEGMENT:{
1273       GstFormat fmt;
1274       gboolean update;
1275       gdouble rate, applied_rate;
1276       gint64 cur, stop, time;
1277
1278       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1279           &fmt, &cur, &stop, &time);
1280
1281       if (fmt == GST_FORMAT_TIME) {
1282         GstFormat dformat = GST_FORMAT_DEFAULT;
1283
1284         GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1285         dec->framed = TRUE;
1286         res = gst_pad_push_event (dec->srcpad, event);
1287
1288         /* this won't work for the first newsegment event though ... */
1289         if (gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, cur,
1290                 &dformat, &cur) && cur != -1 &&
1291             gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, stop,
1292                 &dformat, &stop) && stop != -1) {
1293           gst_segment_set_newsegment_full (&dec->segment, update, rate,
1294               applied_rate, dformat, cur, stop, time);
1295           GST_DEBUG_OBJECT (dec, "segment %" GST_SEGMENT_FORMAT, &dec->segment);
1296         } else {
1297           GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1298         }
1299       } else if (fmt == GST_FORMAT_BYTES || TRUE) {
1300         GST_DEBUG_OBJECT (dec, "newsegment event in %s format => not framed",
1301             gst_format_get_name (fmt));
1302         dec->framed = FALSE;
1303
1304         /* prepare generic newsegment event, for some reason our metadata
1305          * callback where we usually set this up is not being called in
1306          * push mode */
1307         if (dec->start_segment)
1308           gst_event_unref (dec->start_segment);
1309         dec->start_segment = gst_event_new_new_segment (FALSE, 1.0,
1310             GST_FORMAT_TIME, 0, -1, 0);
1311
1312         gst_event_unref (event);
1313         res = TRUE;
1314       }
1315       break;
1316     }
1317     case GST_EVENT_EOS:{
1318       GST_LOG_OBJECT (dec, "EOS, with %u bytes available in adapter",
1319           gst_adapter_available (dec->adapter));
1320       if (dec->init == FALSE) {
1321         if (gst_adapter_available (dec->adapter) > 0) {
1322           FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
1323         }
1324         FLAC__stream_decoder_flush (dec->decoder);
1325       }
1326       gst_adapter_clear (dec->adapter);
1327       res = gst_pad_push_event (dec->srcpad, event);
1328       break;
1329     }
1330     default:
1331       res = gst_pad_event_default (pad, event);
1332       break;
1333   }
1334
1335   gst_object_unref (dec);
1336
1337   return res;
1338 }
1339
1340 static gboolean
1341 gst_flac_dec_chain_parse_headers (GstFlacDec * dec)
1342 {
1343   guint8 marker[4];
1344   guint avail, off;
1345
1346   avail = gst_adapter_available (dec->adapter);
1347   if (avail < 4)
1348     return FALSE;
1349
1350   gst_adapter_copy (dec->adapter, marker, 0, 4);
1351   if (strncmp ((const gchar *) marker, "fLaC", 4) != 0) {
1352     GST_ERROR_OBJECT (dec, "Unexpected header, expected fLaC header");
1353     return TRUE;                /* abort header parsing */
1354   }
1355
1356   GST_DEBUG_OBJECT (dec, "fLaC header          : len           4 @ %7u", 0);
1357
1358   off = 4;
1359   while (avail > (off + 1 + 3)) {
1360     gboolean is_last;
1361     guint8 mb_hdr[4];
1362     guint len, block_type;
1363
1364     gst_adapter_copy (dec->adapter, mb_hdr, off, 4);
1365
1366     is_last = ((mb_hdr[0] & 0x80) == 0x80);
1367     block_type = mb_hdr[0] & 0x7f;
1368     len = GST_READ_UINT24_BE (mb_hdr + 1);
1369     GST_DEBUG_OBJECT (dec, "Metadata block type %u: len %7u + 4 @ %7u%s",
1370         block_type, len, off, (is_last) ? " (last)" : "");
1371     off += 4 + len;
1372
1373     if (is_last)
1374       break;
1375
1376     if (off >= avail) {
1377       GST_LOG_OBJECT (dec, "Need more data: next offset %u > avail %u", off,
1378           avail);
1379       return FALSE;
1380     }
1381   }
1382
1383   /* want metadata blocks plus at least one frame */
1384   return (off + FLAC__MAX_BLOCK_SIZE >= avail);
1385 }
1386
1387 static GstFlowReturn
1388 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1389 {
1390   FLAC__StreamDecoderInitStatus s;
1391   GstFlacDec *dec;
1392   gboolean got_audio_frame;
1393
1394   dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1395
1396   GST_LOG_OBJECT (dec,
1397       "buffer with ts=%" GST_TIME_FORMAT ", offset=%" G_GINT64_FORMAT
1398       ", end_offset=%" G_GINT64_FORMAT ", size=%u",
1399       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_BUFFER_OFFSET (buf),
1400       GST_BUFFER_OFFSET_END (buf), GST_BUFFER_SIZE (buf));
1401
1402   if (dec->init) {
1403     GST_DEBUG_OBJECT (dec, "initializing decoder");
1404     s = FLAC__stream_decoder_init_stream (dec->decoder,
1405         gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
1406         gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
1407         gst_flac_dec_error_cb, dec);
1408     if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1409       GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
1410       return GST_FLOW_ERROR;
1411     }
1412     GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1413     dec->init = FALSE;
1414   } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1415     /* Clear the adapter and the decoder */
1416     gst_adapter_clear (dec->adapter);
1417     FLAC__stream_decoder_flush (dec->decoder);
1418   }
1419
1420   if (dec->framed) {
1421     gint64 unused;
1422
1423     /* check if this is a flac audio frame (rather than a header or junk) */
1424     got_audio_frame = gst_flac_dec_scan_got_frame (dec, GST_BUFFER_DATA (buf),
1425         GST_BUFFER_SIZE (buf), &unused);
1426
1427     /* oggdemux will set granulepos in OFFSET_END instead of timestamp */
1428     if (G_LIKELY (got_audio_frame)) {
1429       /* old oggdemux for now */
1430       if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1431         dec->cur_granulepos = GST_BUFFER_OFFSET_END (buf);
1432       } else {
1433         GstFormat dformat = GST_FORMAT_DEFAULT;
1434
1435         /* upstream (e.g. demuxer) presents us time,
1436          * convert to default samples */
1437         gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME,
1438             GST_BUFFER_TIMESTAMP (buf), &dformat, &dec->segment.last_stop);
1439         dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1440       }
1441     }
1442   } else {
1443     dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1444     got_audio_frame = TRUE;
1445   }
1446
1447   gst_adapter_push (dec->adapter, buf);
1448   buf = NULL;
1449
1450   dec->last_flow = GST_FLOW_OK;
1451
1452   if (!dec->framed) {
1453     if (G_UNLIKELY (!dec->got_headers)) {
1454       if (!gst_flac_dec_chain_parse_headers (dec)) {
1455         GST_LOG_OBJECT (dec, "don't have metadata blocks yet, need more data");
1456         goto out;
1457       }
1458       GST_INFO_OBJECT (dec, "have all metadata blocks now");
1459       dec->got_headers = TRUE;
1460     }
1461
1462     /* wait until we have at least 64kB because libflac's StreamDecoder
1463      * interface is a bit dumb it seems (if we don't have as much data as
1464      * it wants it will call our read callback repeatedly and the only
1465      * way to stop that is to error out or EOS, which will affect the
1466      * decoder state). And the decoder seems to always ask for MAX_BLOCK_SIZE
1467      * bytes rather than the max. block size from the header). Requiring
1468      * MAX_BLOCK_SIZE bytes here should make sure it always gets enough data
1469      * to decode at least one block */
1470     while (gst_adapter_available (dec->adapter) >= FLAC__MAX_BLOCK_SIZE &&
1471         dec->last_flow == GST_FLOW_OK) {
1472       GST_LOG_OBJECT (dec, "%u bytes available",
1473           gst_adapter_available (dec->adapter));
1474       if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1475         GST_DEBUG_OBJECT (dec, "process_single failed");
1476         break;
1477       }
1478
1479       if (FLAC__stream_decoder_get_state (dec->decoder) ==
1480           FLAC__STREAM_DECODER_ABORTED) {
1481         GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
1482         dec->last_flow = GST_FLOW_ERROR;
1483         break;
1484       }
1485     }
1486   } else if (dec->framed && got_audio_frame) {
1487     /* framed - there should always be enough data to decode something */
1488     GST_LOG_OBJECT (dec, "%u bytes available",
1489         gst_adapter_available (dec->adapter));
1490     if (G_UNLIKELY (!dec->got_headers)) {
1491       /* The first time we get audio data, we know we got all the headers.
1492        * We then loop until all the metadata is processed, then do an extra
1493        * "process_single" step for the audio frame. */
1494       GST_DEBUG_OBJECT (dec,
1495           "First audio frame, ensuring all metadata is processed");
1496       if (!FLAC__stream_decoder_process_until_end_of_metadata (dec->decoder)) {
1497         GST_DEBUG_OBJECT (dec, "process_until_end_of_metadata failed");
1498       }
1499       GST_DEBUG_OBJECT (dec,
1500           "All metadata is now processed, reading to process audio data");
1501       dec->got_headers = TRUE;
1502     }
1503     if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1504       GST_DEBUG_OBJECT (dec, "process_single failed");
1505     }
1506   } else {
1507     GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1508   }
1509
1510 out:
1511
1512   return dec->last_flow;
1513 }
1514
1515 static gboolean
1516 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1517     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1518 {
1519   gboolean res = TRUE;
1520
1521   if (dec->width == 0 || dec->channels == 0 || dec->sample_rate == 0) {
1522     /* no frame decoded yet */
1523     GST_DEBUG_OBJECT (dec, "cannot convert: not set up yet");
1524     return FALSE;
1525   }
1526
1527   switch (src_format) {
1528     case GST_FORMAT_BYTES:{
1529       res = FALSE;
1530       break;
1531     }
1532     case GST_FORMAT_DEFAULT:
1533       switch (*dest_format) {
1534         case GST_FORMAT_BYTES:
1535           res = FALSE;
1536           break;
1537         case GST_FORMAT_TIME:
1538           /* granulepos = sample */
1539           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1540               dec->sample_rate);
1541           break;
1542         default:
1543           res = FALSE;
1544           break;
1545       }
1546       break;
1547     case GST_FORMAT_TIME:
1548       switch (*dest_format) {
1549         case GST_FORMAT_BYTES:
1550           res = FALSE;
1551           break;
1552         case GST_FORMAT_DEFAULT:
1553           *dest_value = gst_util_uint64_scale_int (src_value,
1554               dec->sample_rate, GST_SECOND);
1555           break;
1556         default:
1557           res = FALSE;
1558           break;
1559       }
1560       break;
1561     default:
1562       res = FALSE;
1563       break;
1564   }
1565   return res;
1566 }
1567
1568 static const GstQueryType *
1569 gst_flac_dec_get_sink_query_types (GstPad * pad)
1570 {
1571   static const GstQueryType types[] = {
1572     GST_QUERY_CONVERT,
1573     0,
1574   };
1575
1576   return types;
1577 }
1578
1579 static gboolean
1580 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1581 {
1582   GstFlacDec *dec;
1583   gboolean res = FALSE;
1584
1585   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1586
1587   GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1588
1589   switch (GST_QUERY_TYPE (query)) {
1590     case GST_QUERY_CONVERT:{
1591       GstFormat src_fmt, dest_fmt;
1592
1593       gint64 src_val, dest_val;
1594
1595       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1596
1597       res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1598           &dest_val);
1599
1600       if (res) {
1601         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1602       }
1603       GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1604       break;
1605     }
1606
1607     default:{
1608       res = gst_pad_query_default (pad, query);
1609       break;
1610     }
1611   }
1612
1613   gst_object_unref (dec);
1614   return res;
1615 }
1616
1617 static gboolean
1618 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1619     GstFormat * dest_format, gint64 * dest_value)
1620 {
1621   GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1622   gboolean res = TRUE;
1623   guint bytes_per_sample;
1624   guint scale = 1;
1625
1626   if (flacdec->width == 0 || flacdec->channels == 0 ||
1627       flacdec->sample_rate == 0) {
1628     /* no frame decoded yet */
1629     GST_DEBUG_OBJECT (flacdec, "cannot convert: not set up yet");
1630     return FALSE;
1631   }
1632
1633   bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1634
1635   switch (src_format) {
1636     case GST_FORMAT_BYTES:{
1637       switch (*dest_format) {
1638         case GST_FORMAT_DEFAULT:
1639           *dest_value =
1640               gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1641           break;
1642         case GST_FORMAT_TIME:
1643         {
1644           gint byterate = bytes_per_sample * flacdec->sample_rate;
1645
1646           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1647               byterate);
1648           break;
1649         }
1650         default:
1651           res = FALSE;
1652       }
1653       break;
1654     }
1655     case GST_FORMAT_DEFAULT:
1656       switch (*dest_format) {
1657         case GST_FORMAT_BYTES:
1658           *dest_value = src_value * bytes_per_sample;
1659           break;
1660         case GST_FORMAT_TIME:
1661           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1662               flacdec->sample_rate);
1663           break;
1664         default:
1665           res = FALSE;
1666       }
1667       break;
1668     case GST_FORMAT_TIME:
1669       switch (*dest_format) {
1670         case GST_FORMAT_BYTES:
1671           scale = bytes_per_sample;
1672         case GST_FORMAT_DEFAULT:
1673           *dest_value = gst_util_uint64_scale_int_round (src_value,
1674               scale * flacdec->sample_rate, GST_SECOND);
1675           break;
1676         default:
1677           res = FALSE;
1678       }
1679       break;
1680     default:
1681       res = FALSE;
1682   }
1683   return res;
1684 }
1685
1686 static const GstQueryType *
1687 gst_flac_dec_get_src_query_types (GstPad * pad)
1688 {
1689   static const GstQueryType types[] = {
1690     GST_QUERY_POSITION,
1691     GST_QUERY_DURATION,
1692     GST_QUERY_CONVERT,
1693     GST_QUERY_SEEKING,
1694     0,
1695   };
1696
1697   return types;
1698 }
1699
1700 static gboolean
1701 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1702 {
1703   GstFlacDec *flacdec;
1704   gboolean res = TRUE;
1705   GstPad *peer;
1706
1707   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1708   peer = gst_pad_get_peer (flacdec->sinkpad);
1709
1710   switch (GST_QUERY_TYPE (query)) {
1711     case GST_QUERY_POSITION:{
1712       GstFormat fmt;
1713       gint64 pos;
1714
1715       gst_query_parse_position (query, &fmt, NULL);
1716
1717       /* there might be a demuxer in front of us who can handle this */
1718       if (fmt == GST_FORMAT_TIME && (res = gst_pad_query (peer, query)))
1719         break;
1720
1721       if (fmt != GST_FORMAT_DEFAULT) {
1722         if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1723                 flacdec->segment.last_stop, &fmt, &pos)) {
1724           GST_DEBUG_OBJECT (flacdec, "failed to convert position into %s "
1725               "format", gst_format_get_name (fmt));
1726           res = FALSE;
1727           goto done;
1728         }
1729       } else {
1730         pos = flacdec->segment.last_stop;
1731       }
1732
1733       gst_query_set_position (query, fmt, pos);
1734
1735       GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1736           " (format: %s)", pos, gst_format_get_name (fmt));
1737
1738       res = TRUE;
1739       break;
1740     }
1741
1742     case GST_QUERY_DURATION:{
1743       GstFormat fmt;
1744       gint64 len;
1745
1746       gst_query_parse_duration (query, &fmt, NULL);
1747
1748       /* try any demuxers or parsers before us first */
1749       if ((fmt == GST_FORMAT_TIME || fmt == GST_FORMAT_DEFAULT) &&
1750           peer != NULL && gst_pad_query (peer, query)) {
1751         gst_query_parse_duration (query, NULL, &len);
1752         GST_DEBUG_OBJECT (flacdec, "peer returned duration %" GST_TIME_FORMAT,
1753             GST_TIME_ARGS (len));
1754         res = TRUE;
1755         goto done;
1756       }
1757
1758       if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1759         GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1760         res = FALSE;
1761         goto done;
1762       }
1763
1764       /* convert total number of samples to request format */
1765       if (fmt != GST_FORMAT_DEFAULT) {
1766         if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1767                 flacdec->segment.duration, &fmt, &len)) {
1768           GST_DEBUG_OBJECT (flacdec, "failed to convert duration into %s "
1769               "format", gst_format_get_name (fmt));
1770           res = FALSE;
1771           goto done;
1772         }
1773       } else {
1774         len = flacdec->segment.duration;
1775       }
1776
1777       gst_query_set_duration (query, fmt, len);
1778
1779       GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1780           " (format: %s)", len, gst_format_get_name (fmt));
1781
1782       res = TRUE;
1783       break;
1784     }
1785
1786     case GST_QUERY_CONVERT:{
1787       GstFormat src_fmt, dest_fmt;
1788       gint64 src_val, dest_val;
1789
1790       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1791
1792       res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1793           &dest_val);
1794
1795       if (res) {
1796         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1797       }
1798
1799       break;
1800     }
1801     case GST_QUERY_SEEKING:{
1802       GstFormat fmt;
1803       gboolean seekable = FALSE;
1804
1805       res = TRUE;
1806       /* If upstream can handle the query we're done */
1807       seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1808       if (seekable)
1809         gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1810       if (seekable)
1811         goto done;
1812
1813       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1814       if ((fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT) ||
1815           flacdec->streaming) {
1816         gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1817       } else {
1818         gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1819       }
1820       break;
1821     }
1822
1823     default:{
1824       res = gst_pad_query_default (pad, query);
1825       break;
1826     }
1827   }
1828
1829 done:
1830
1831   if (peer)
1832     gst_object_unref (peer);
1833
1834   gst_object_unref (flacdec);
1835
1836   return res;
1837 }
1838
1839 static gboolean
1840 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1841 {
1842   FLAC__bool seek_ok;
1843   GstSeekFlags seek_flags;
1844   GstSeekType start_type;
1845   GstSeekType stop_type;
1846   GstSegment segment;
1847   GstFormat seek_format;
1848   gboolean only_update = FALSE;
1849   gboolean flush;
1850   gdouble rate;
1851   gint64 start, last_stop;
1852   gint64 stop;
1853
1854   if (flacdec->streaming) {
1855     GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1856     return FALSE;
1857   }
1858
1859   gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1860       &start, &stop_type, &stop);
1861
1862   if (seek_format != GST_FORMAT_DEFAULT && seek_format != GST_FORMAT_TIME) {
1863     GST_DEBUG_OBJECT (flacdec,
1864         "seeking is only supported in TIME or DEFAULT format");
1865     return FALSE;
1866   }
1867
1868   if (rate < 0.0) {
1869     GST_DEBUG_OBJECT (flacdec,
1870         "only forward playback supported, rate %f not allowed", rate);
1871     return FALSE;
1872   }
1873
1874   if (seek_format != GST_FORMAT_DEFAULT) {
1875     GstFormat target_format = GST_FORMAT_DEFAULT;
1876
1877     if (start_type != GST_SEEK_TYPE_NONE &&
1878         !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, start,
1879             &target_format, &start)) {
1880       GST_DEBUG_OBJECT (flacdec, "failed to convert start to DEFAULT format");
1881       return FALSE;
1882     }
1883
1884     if (stop_type != GST_SEEK_TYPE_NONE &&
1885         !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, stop,
1886             &target_format, &stop)) {
1887       GST_DEBUG_OBJECT (flacdec, "failed to convert stop to DEFAULT format");
1888       return FALSE;
1889     }
1890   }
1891
1892   /* Check if we seeked after the end of file */
1893   if (start_type != GST_SEEK_TYPE_NONE && flacdec->segment.duration > 0 &&
1894       start >= flacdec->segment.duration) {
1895     flacdec->eos = TRUE;
1896   } else {
1897     flacdec->eos = FALSE;
1898   }
1899
1900   flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1901
1902   if (flush) {
1903     /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1904      * this. */
1905     GST_DEBUG_OBJECT (flacdec, "flushing");
1906     gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_start ());
1907     gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_start ());
1908   } else {
1909     /* non flushing seek, pause the task */
1910     GST_DEBUG_OBJECT (flacdec, "stopping task");
1911     gst_pad_stop_task (flacdec->sinkpad);
1912   }
1913
1914   /* acquire the stream lock, this either happens when the streaming thread
1915    * stopped because of the flush or when the task is paused after the loop
1916    * function finished an iteration, which can never happen when it's blocked
1917    * downstream in PAUSED, for example */
1918   GST_PAD_STREAM_LOCK (flacdec->sinkpad);
1919
1920   /* start seek with clear state to avoid seeking thread pushing segments/data.
1921    * Note current state may have some pending,
1922    * e.g. multi-sink seek leads to immediate subsequent seek events */
1923   if (flacdec->start_segment) {
1924     gst_event_unref (flacdec->start_segment);
1925     flacdec->start_segment = NULL;
1926   }
1927   gst_buffer_replace (&flacdec->pending, NULL);
1928   flacdec->pending_samples = 0;
1929
1930   /* save a segment copy until we know the seek worked. The idea is that
1931    * when the seek fails, we want to restore with what we were doing. */
1932   segment = flacdec->segment;
1933
1934   /* update the segment with the seek values, last_stop will contain the new
1935    * position we should seek to */
1936   gst_segment_set_seek (&flacdec->segment, rate, GST_FORMAT_DEFAULT,
1937       seek_flags, start_type, start, stop_type, stop, &only_update);
1938
1939   GST_DEBUG_OBJECT (flacdec,
1940       "configured segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT
1941       "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]",
1942       flacdec->segment.start, flacdec->segment.stop,
1943       GST_TIME_ARGS (flacdec->segment.start * GST_SECOND /
1944           flacdec->sample_rate),
1945       GST_TIME_ARGS (flacdec->segment.stop * GST_SECOND /
1946           flacdec->sample_rate));
1947
1948   GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1949       flacdec->segment.last_stop);
1950
1951   /* flush sinkpad again because we need to pull and push buffers while doing
1952    * the seek */
1953   if (flush) {
1954     GST_DEBUG_OBJECT (flacdec, "flushing stop");
1955     gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_stop ());
1956     gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_stop ());
1957   }
1958
1959   /* mark ourselves as seeking because the above lines will trigger some
1960    * callbacks that need to behave differently when seeking */
1961   flacdec->seeking = TRUE;
1962
1963   if (!flacdec->eos) {
1964     GST_LOG_OBJECT (flacdec, "calling seek_absolute");
1965     seek_ok = FLAC__stream_decoder_seek_absolute (flacdec->decoder,
1966         flacdec->segment.last_stop);
1967     GST_LOG_OBJECT (flacdec, "done with seek_absolute, seek_ok=%d", seek_ok);
1968   } else {
1969     GST_LOG_OBJECT (flacdec, "not seeking, seeked after end of file");
1970     seek_ok = TRUE;
1971   }
1972
1973   flacdec->seeking = FALSE;
1974
1975   GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1976       flacdec->segment.last_stop);
1977
1978   if (!seek_ok) {
1979     GST_WARNING_OBJECT (flacdec, "seek failed");
1980     /* seek failed, restore the segment and start streaming again with
1981      * the previous segment values */
1982     flacdec->segment = segment;
1983   } else if (!flush && flacdec->running) {
1984     /* we are running the current segment and doing a non-flushing seek, 
1985      * close the segment first based on the last_stop. */
1986     GST_DEBUG_OBJECT (flacdec, "closing running segment %" G_GINT64_FORMAT
1987         " to %" G_GINT64_FORMAT, segment.start, segment.last_stop);
1988
1989     /* convert the old segment values to time to close the old segment */
1990     start = gst_util_uint64_scale_int (segment.start, GST_SECOND,
1991         flacdec->sample_rate);
1992     last_stop =
1993         gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1994         flacdec->sample_rate);
1995
1996     /* queue the segment for sending in the stream thread, start and time are
1997      * always the same. */
1998     if (flacdec->close_segment)
1999       gst_event_unref (flacdec->close_segment);
2000     flacdec->close_segment =
2001         gst_event_new_new_segment_full (TRUE,
2002         segment.rate, segment.applied_rate, GST_FORMAT_TIME,
2003         start, last_stop, start);
2004   }
2005
2006   if (seek_ok) {
2007     /* seek succeeded, flacdec->segment contains the new positions */
2008     GST_DEBUG_OBJECT (flacdec, "seek successful");
2009   }
2010
2011   /* convert the (new) segment values to time, we will need them to generate the
2012    * new segment events. */
2013   start = gst_util_uint64_scale_int (flacdec->segment.start, GST_SECOND,
2014       flacdec->sample_rate);
2015   last_stop = gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
2016       flacdec->sample_rate);
2017
2018   /* for deriving a stop position for the playback segment from the seek
2019    * segment, we must take the duration when the stop is not set */
2020   if (flacdec->segment.stop != -1)
2021     stop = gst_util_uint64_scale_int (flacdec->segment.stop, GST_SECOND,
2022         flacdec->sample_rate);
2023   else
2024     stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
2025         flacdec->sample_rate);
2026
2027   /* notify start of new segment when we were asked to do so. */
2028   if (flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2029     /* last_stop contains the position we start from */
2030     gst_element_post_message (GST_ELEMENT (flacdec),
2031         gst_message_new_segment_start (GST_OBJECT (flacdec),
2032             GST_FORMAT_TIME, last_stop));
2033   }
2034
2035   /* if the seek was ok or (when it failed) we are flushing, we need to send out
2036    * a new segment. If we did not flush and the seek failed, we simply do
2037    * nothing here and continue where we were. */
2038   if (seek_ok || flush) {
2039     GST_DEBUG_OBJECT (flacdec, "Creating newsegment from %" GST_TIME_FORMAT
2040         " to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop),
2041         GST_TIME_ARGS (stop));
2042     /* now replace the old segment so that we send it in the stream thread the
2043      * next time it is scheduled. */
2044     if (flacdec->start_segment)
2045       gst_event_unref (flacdec->start_segment);
2046     flacdec->start_segment =
2047         gst_event_new_new_segment_full (FALSE,
2048         flacdec->segment.rate, flacdec->segment.applied_rate, GST_FORMAT_TIME,
2049         last_stop, stop, last_stop);
2050   }
2051
2052   /* we'll generate a discont on the next buffer */
2053   flacdec->discont = TRUE;
2054   /* the task is running again now */
2055   flacdec->running = TRUE;
2056   gst_pad_start_task (flacdec->sinkpad,
2057       (GstTaskFunction) gst_flac_dec_loop, flacdec->sinkpad);
2058
2059   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
2060
2061   return seek_ok;
2062 }
2063
2064 static gboolean
2065 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
2066 {
2067   gboolean res = TRUE;
2068   GstFlacDec *flacdec;
2069
2070   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
2071
2072   switch (GST_EVENT_TYPE (event)) {
2073     case GST_EVENT_SEEK:{
2074       GST_DEBUG_OBJECT (flacdec, "received seek event %p", event);
2075       /* first, see if we're before a demuxer that
2076        * might handle the seek for us */
2077       gst_event_ref (event);
2078       res = gst_pad_event_default (pad, event);
2079       /* if not, try to handle it ourselves */
2080       if (!res) {
2081         GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
2082         res = gst_flac_dec_handle_seek_event (flacdec, event);
2083       }
2084       gst_event_unref (event);
2085       break;
2086     }
2087     default:
2088       res = gst_pad_event_default (pad, event);
2089       break;
2090   }
2091
2092   gst_object_unref (flacdec);
2093
2094   return res;
2095 }
2096
2097 static gboolean
2098 gst_flac_dec_sink_activate (GstPad * sinkpad)
2099 {
2100   if (gst_pad_check_pull_range (sinkpad))
2101     return gst_pad_activate_pull (sinkpad, TRUE);
2102
2103   return gst_pad_activate_push (sinkpad, TRUE);
2104 }
2105
2106 static gboolean
2107 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
2108 {
2109   GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
2110
2111   if (active) {
2112     gst_flac_dec_setup_decoder (dec);
2113     dec->streaming = TRUE;
2114     dec->got_headers = FALSE;
2115   }
2116   return TRUE;
2117 }
2118
2119 static gboolean
2120 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
2121 {
2122   gboolean res;
2123
2124   if (active) {
2125     GstFlacDec *flacdec;
2126
2127     flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
2128
2129     flacdec->offset = 0;
2130     gst_flac_dec_setup_decoder (flacdec);
2131     flacdec->running = TRUE;
2132     flacdec->streaming = FALSE;
2133
2134     res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
2135         sinkpad);
2136   } else {
2137     res = gst_pad_stop_task (sinkpad);
2138   }
2139   return res;
2140 }
2141
2142 static GstStateChangeReturn
2143 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2144 {
2145   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2146   GstFlacDec *flacdec = GST_FLAC_DEC (element);
2147
2148   switch (transition) {
2149     case GST_STATE_CHANGE_READY_TO_PAUSED:
2150       flacdec->eos = FALSE;
2151       flacdec->seeking = FALSE;
2152       flacdec->channels = 0;
2153       flacdec->depth = 0;
2154       flacdec->width = 0;
2155       flacdec->sample_rate = 0;
2156       gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2157       break;
2158     default:
2159       break;
2160   }
2161
2162   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2163   if (ret == GST_STATE_CHANGE_FAILURE)
2164     return ret;
2165
2166   switch (transition) {
2167     case GST_STATE_CHANGE_PAUSED_TO_READY:
2168       gst_segment_init (&flacdec->segment, GST_FORMAT_UNDEFINED);
2169       gst_flac_dec_reset_decoders (flacdec);
2170       break;
2171     default:
2172       break;
2173   }
2174
2175   return ret;
2176 }