tizen 2.0 init
[framework/multimedia/gst-plugins-good0.10.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
48 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
49  * with newer GLib versions (>= 2.31.0) */
50 #define GLIB_DISABLE_DEPRECATION_WARNINGS
51
52 #include <string.h>
53
54 #include "gstflacdec.h"
55 #include <gst/gst-i18n-plugin.h>
56 #include <gst/gsttagsetter.h>
57 #include <gst/base/gsttypefindhelper.h>
58 #include <gst/audio/multichannel.h>
59 #include <gst/tag/tag.h>
60
61 /* Taken from http://flac.sourceforge.net/format.html#frame_header */
62 static const GstAudioChannelPosition channel_positions[8][8] = {
63   {GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
64   {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
65       GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
66         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
67         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
68       GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
69         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
70         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
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_REAR_LEFT,
77       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
78         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
79         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
80         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
81         GST_AUDIO_CHANNEL_POSITION_LFE,
82         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
83       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
84   /* FIXME: 7/8 channel layouts are not defined in the FLAC specs */
85   {
86         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
87         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
88         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
89         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
90         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
91         GST_AUDIO_CHANNEL_POSITION_LFE,
92       GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
93         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
94         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
95         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
96         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
97         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
98         GST_AUDIO_CHANNEL_POSITION_LFE,
99         GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
100       GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
101 };
102
103 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
104 #define GST_CAT_DEFAULT flacdec_debug
105
106 static void gst_flac_dec_finalize (GObject * object);
107 static void gst_flac_dec_loop (GstPad * pad);
108
109 static GstStateChangeReturn gst_flac_dec_change_state (GstElement * element,
110     GstStateChange transition);
111 static const GstQueryType *gst_flac_dec_get_src_query_types (GstPad * pad);
112 static const GstQueryType *gst_flac_dec_get_sink_query_types (GstPad * pad);
113 static gboolean gst_flac_dec_sink_query (GstPad * pad, GstQuery * query);
114 static gboolean gst_flac_dec_src_query (GstPad * pad, GstQuery * query);
115 static gboolean gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format,
116     gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
117 static gboolean gst_flac_dec_src_event (GstPad * pad, GstEvent * event);
118 static gboolean gst_flac_dec_sink_activate (GstPad * sinkpad);
119 static gboolean gst_flac_dec_sink_activate_pull (GstPad * sinkpad,
120     gboolean active);
121 static gboolean gst_flac_dec_sink_activate_push (GstPad * sinkpad,
122     gboolean active);
123 static gboolean gst_flac_dec_sink_event (GstPad * pad, GstEvent * event);
124 static GstFlowReturn gst_flac_dec_chain (GstPad * pad, GstBuffer * buf);
125
126 static void gst_flac_dec_reset_decoders (GstFlacDec * flacdec);
127 static void gst_flac_dec_setup_decoder (GstFlacDec * flacdec);
128
129 static FLAC__StreamDecoderReadStatus
130 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
131     FLAC__byte buffer[], size_t * bytes, void *client_data);
132 static FLAC__StreamDecoderReadStatus
133 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
134     FLAC__byte buffer[], size_t * bytes, void *client_data);
135 static FLAC__StreamDecoderSeekStatus
136 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
137     FLAC__uint64 position, void *client_data);
138 static FLAC__StreamDecoderTellStatus
139 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
140     FLAC__uint64 * position, void *client_data);
141 static FLAC__StreamDecoderLengthStatus
142 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
143     FLAC__uint64 * length, void *client_data);
144 static FLAC__bool gst_flac_dec_eof (const FLAC__StreamDecoder * decoder,
145     void *client_data);
146 static FLAC__StreamDecoderWriteStatus
147 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
148     const FLAC__Frame * frame,
149     const FLAC__int32 * const buffer[], void *client_data);
150 static void gst_flac_dec_metadata_cb (const FLAC__StreamDecoder *
151     decoder, const FLAC__StreamMetadata * metadata, void *client_data);
152 static void gst_flac_dec_error_cb (const FLAC__StreamDecoder *
153     decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
154
155 GST_BOILERPLATE (GstFlacDec, gst_flac_dec, GstElement, GST_TYPE_ELEMENT);
156
157 /* FIXME 0.11: Use width=32 for all depths and let audioconvert
158  * handle the conversions instead of doing it ourself.
159  */
160 #define GST_FLAC_DEC_SRC_CAPS                             \
161     "audio/x-raw-int, "                                   \
162     "endianness = (int) BYTE_ORDER, "                     \
163     "signed = (boolean) true, "                           \
164     "width = (int) { 8, 16, 32 }, "                       \
165     "depth = (int) [ 4, 32 ], "                           \
166     "rate = (int) [ 1, 655350 ], "                        \
167     "channels = (int) [ 1, 8 ]"
168
169 static GstStaticPadTemplate flac_dec_src_factory =
170 GST_STATIC_PAD_TEMPLATE ("src",
171     GST_PAD_SRC,
172     GST_PAD_ALWAYS,
173     GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
174 static GstStaticPadTemplate flac_dec_sink_factory =
175 GST_STATIC_PAD_TEMPLATE ("sink",
176     GST_PAD_SINK,
177     GST_PAD_ALWAYS,
178     GST_STATIC_CAPS ("audio/x-flac")
179     );
180
181 static void
182 gst_flac_dec_base_init (gpointer g_class)
183 {
184   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
185
186   gst_element_class_add_static_pad_template (element_class,
187       &flac_dec_src_factory);
188   gst_element_class_add_static_pad_template (element_class,
189       &flac_dec_sink_factory);
190   gst_element_class_set_details_simple (element_class, "FLAC audio decoder",
191       "Codec/Decoder/Audio",
192       "Decodes FLAC lossless audio streams", "Wim Taymans <wim@fluendo.com>");
193
194   GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
195 }
196
197 static void
198 gst_flac_dec_class_init (GstFlacDecClass * klass)
199 {
200   GstElementClass *gstelement_class;
201   GObjectClass *gobject_class;
202
203   gstelement_class = (GstElementClass *) klass;
204   gobject_class = (GObjectClass *) klass;
205
206   gobject_class->finalize = gst_flac_dec_finalize;
207
208   gstelement_class->change_state =
209       GST_DEBUG_FUNCPTR (gst_flac_dec_change_state);
210 }
211
212 static void
213 gst_flac_dec_init (GstFlacDec * flacdec, GstFlacDecClass * klass)
214 {
215   flacdec->sinkpad =
216       gst_pad_new_from_static_template (&flac_dec_sink_factory, "sink");
217   gst_pad_set_activate_function (flacdec->sinkpad,
218       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate));
219   gst_pad_set_activatepull_function (flacdec->sinkpad,
220       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_pull));
221   gst_pad_set_activatepush_function (flacdec->sinkpad,
222       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_push));
223   gst_pad_set_query_type_function (flacdec->sinkpad,
224       GST_DEBUG_FUNCPTR (gst_flac_dec_get_sink_query_types));
225   gst_pad_set_query_function (flacdec->sinkpad,
226       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_query));
227   gst_pad_set_event_function (flacdec->sinkpad,
228       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_event));
229   gst_pad_set_chain_function (flacdec->sinkpad,
230       GST_DEBUG_FUNCPTR (gst_flac_dec_chain));
231   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->sinkpad);
232
233   flacdec->srcpad =
234       gst_pad_new_from_static_template (&flac_dec_src_factory, "src");
235   gst_pad_set_query_type_function (flacdec->srcpad,
236       GST_DEBUG_FUNCPTR (gst_flac_dec_get_src_query_types));
237   gst_pad_set_query_function (flacdec->srcpad,
238       GST_DEBUG_FUNCPTR (gst_flac_dec_src_query));
239   gst_pad_set_event_function (flacdec->srcpad,
240       GST_DEBUG_FUNCPTR (gst_flac_dec_src_event));
241   gst_pad_use_fixed_caps (flacdec->srcpad);
242   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->srcpad);
243
244   gst_flac_dec_reset_decoders (flacdec);
245 }
246
247 static void
248 gst_flac_dec_reset_decoders (GstFlacDec * flacdec)
249 {
250   /* Clean up the decoder */
251   if (flacdec->decoder) {
252     FLAC__stream_decoder_delete (flacdec->decoder);
253     flacdec->decoder = NULL;
254   }
255
256   if (flacdec->adapter) {
257     gst_adapter_clear (flacdec->adapter);
258     g_object_unref (flacdec->adapter);
259     flacdec->adapter = NULL;
260   }
261
262   if (flacdec->close_segment) {
263     gst_event_unref (flacdec->close_segment);
264     flacdec->close_segment = NULL;
265   }
266   if (flacdec->start_segment) {
267     gst_event_unref (flacdec->start_segment);
268     flacdec->start_segment = NULL;
269   }
270   if (flacdec->tags) {
271     gst_tag_list_free (flacdec->tags);
272     flacdec->tags = NULL;
273   }
274   if (flacdec->pending) {
275     gst_buffer_unref (flacdec->pending);
276     flacdec->pending = NULL;
277   }
278
279   flacdec->segment.last_stop = 0;
280   flacdec->offset = 0;
281   flacdec->init = TRUE;
282 }
283
284 static void
285 gst_flac_dec_setup_decoder (GstFlacDec * dec)
286 {
287   gst_flac_dec_reset_decoders (dec);
288
289   dec->tags = gst_tag_list_new ();
290   gst_tag_list_add (dec->tags, GST_TAG_MERGE_REPLACE,
291       GST_TAG_AUDIO_CODEC, "FLAC", NULL);
292
293   dec->adapter = gst_adapter_new ();
294
295   dec->decoder = FLAC__stream_decoder_new ();
296
297   /* no point calculating since it's never checked here */
298   FLAC__stream_decoder_set_md5_checking (dec->decoder, false);
299   FLAC__stream_decoder_set_metadata_respond (dec->decoder,
300       FLAC__METADATA_TYPE_VORBIS_COMMENT);
301   FLAC__stream_decoder_set_metadata_respond (dec->decoder,
302       FLAC__METADATA_TYPE_PICTURE);
303 }
304
305 static void
306 gst_flac_dec_finalize (GObject * object)
307 {
308   GstFlacDec *flacdec;
309
310   flacdec = GST_FLAC_DEC (object);
311
312   gst_flac_dec_reset_decoders (flacdec);
313
314   G_OBJECT_CLASS (parent_class)->finalize (object);
315 }
316
317
318 static gboolean
319 gst_flac_dec_update_metadata (GstFlacDec * flacdec,
320     const FLAC__StreamMetadata * metadata)
321 {
322   GstTagList *list;
323   guint num, i;
324
325   if (flacdec->tags)
326     list = flacdec->tags;
327   else
328     flacdec->tags = list = gst_tag_list_new ();
329
330   num = metadata->data.vorbis_comment.num_comments;
331   GST_DEBUG_OBJECT (flacdec, "%u tag(s) found", num);
332
333   for (i = 0; i < num; ++i) {
334     gchar *vc, *name, *value;
335
336     vc = g_strndup ((gchar *) metadata->data.vorbis_comment.comments[i].entry,
337         metadata->data.vorbis_comment.comments[i].length);
338
339     if (gst_tag_parse_extended_comment (vc, &name, NULL, &value, TRUE)) {
340       GST_DEBUG_OBJECT (flacdec, "%s : %s", name, value);
341       if (value && strlen (value))
342         gst_vorbis_tag_add (list, name, value);
343       g_free (name);
344       g_free (value);
345     }
346
347     g_free (vc);
348   }
349
350   return TRUE;
351 }
352
353 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
354 static const guint8 crc8_table[256] = {
355   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
356   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
357   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
358   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
359   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
360   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
361   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
362   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
363   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
364   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
365   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
366   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
367   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
368   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
369   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
370   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
371   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
372   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
373   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
374   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
375   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
376   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
377   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
378   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
379   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
380   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
381   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
382   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
383   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
384   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
385   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
386   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
387 };
388
389 static guint8
390 gst_flac_calculate_crc8 (guint8 * data, guint length)
391 {
392   guint8 crc = 0;
393
394   while (length--) {
395     crc = crc8_table[crc ^ *data];
396     ++data;
397   }
398
399   return crc;
400 }
401
402 static gboolean
403 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
404     gint64 * last_sample_num)
405 {
406   guint headerlen;
407   guint sr_from_end = 0;        /* can be 0, 8 or 16 */
408   guint bs_from_end = 0;        /* can be 0, 8 or 16 */
409   guint32 val = 0;
410   guint8 bs, sr, ca, ss, pb;
411
412   if (size < 10)
413     return FALSE;
414
415   /* sync */
416   if (data[0] != 0xFF || (data[1] & 0xFC) != 0xF8)
417     return FALSE;
418   if (data[1] & 1) {
419     GST_WARNING_OBJECT (flacdec, "Variable block size FLAC unsupported");
420     return FALSE;
421   }
422
423   bs = (data[2] & 0xF0) >> 4;   /* blocksize marker   */
424   sr = (data[2] & 0x0F);        /* samplerate marker  */
425   ca = (data[3] & 0xF0) >> 4;   /* channel assignment */
426   ss = (data[3] & 0x0F) >> 1;   /* sample size marker */
427   pb = (data[3] & 0x01);        /* padding bit        */
428
429   GST_LOG_OBJECT (flacdec,
430       "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
431
432   if (bs == 0 || sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
433     return FALSE;
434   }
435
436   /* read block size from end of header? */
437   if (bs == 6)
438     bs_from_end = 8;
439   else if (bs == 7)
440     bs_from_end = 16;
441
442   /* read sample rate from end of header? */
443   if (sr == 0x0C)
444     sr_from_end = 8;
445   else if (sr == 0x0D || sr == 0x0E)
446     sr_from_end = 16;
447
448   /* FIXME: This is can be 36 bit if variable block size is used,
449    * fortunately not encoder supports this yet and we check for that
450    * above.
451    */
452   val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
453
454   if (val == (guint32) - 1 || val == (guint32) - 2) {
455     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
456     return FALSE;
457   }
458
459   headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
460       (bs_from_end / 8) + (sr_from_end / 8);
461
462   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
463     GST_LOG_OBJECT (flacdec, "invalid checksum");
464     return FALSE;
465   }
466
467   if (flacdec->min_blocksize == flacdec->max_blocksize) {
468     *last_sample_num = (val + 1) * flacdec->min_blocksize;
469   } else {
470     *last_sample_num = 0;       /* FIXME: + length of last block in samples */
471   }
472
473   /* FIXME: only valid for fixed block size streams */
474   GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
475       *last_sample_num);
476
477   if (flacdec->sample_rate > 0 && *last_sample_num != 0) {
478     GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
479         GST_TIME_FORMAT, *last_sample_num,
480         GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->sample_rate));
481   }
482
483   return TRUE;
484 }
485
486 #define SCANBLOCK_SIZE  (64*1024)
487
488 static void
489 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
490 {
491   GstFormat format = GST_FORMAT_BYTES;
492   gint64 file_size, offset;
493
494   GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
495
496   if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
497     GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
498     return;
499   }
500
501   if (flacdec->min_blocksize != flacdec->max_blocksize) {
502     GST_WARNING_OBJECT (flacdec, "scanning for last sample only works "
503         "for FLAC files with constant blocksize");
504     return;
505   }
506
507   GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
508
509   offset = file_size - 1;
510   while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
511     GstFlowReturn flow;
512     GstBuffer *buf = NULL;
513     guint8 *data;
514     guint size;
515
516     /* divide by 2 = not very sophisticated way to deal with overlapping */
517     offset -= SCANBLOCK_SIZE / 2;
518     GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
519         "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
520
521     flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
522     if (flow != GST_FLOW_OK) {
523       GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
524       return;
525     }
526
527     size = GST_BUFFER_SIZE (buf);
528     data = GST_BUFFER_DATA (buf);
529
530     while (size > 16) {
531       if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
532         GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
533             offset + GST_BUFFER_SIZE (buf) - size);
534         gst_buffer_unref (buf);
535         return;
536       }
537       ++data;
538       --size;
539     }
540
541     gst_buffer_unref (buf);
542   }
543 }
544
545 static void
546 gst_flac_extract_picture_buffer (GstFlacDec * dec,
547     const FLAC__StreamMetadata * metadata)
548 {
549   FLAC__StreamMetadata_Picture picture;
550   GstTagList *tags;
551
552   g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
553
554   GST_LOG_OBJECT (dec, "Got PICTURE block");
555   picture = metadata->data.picture;
556
557   GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
558       GST_STR_NULL (picture.mime_type));
559   GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
560
561   tags = gst_tag_list_new ();
562
563   gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
564       picture.data_length, picture.type);
565
566   if (!gst_tag_list_is_empty (tags)) {
567     gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
568   } else {
569     GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
570     gst_tag_list_free (tags);
571   }
572 }
573
574 static void
575 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
576     const FLAC__StreamMetadata * metadata, void *client_data)
577 {
578   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
579
580   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
581
582   switch (metadata->type) {
583     case FLAC__METADATA_TYPE_STREAMINFO:{
584       gint64 samples;
585       guint depth;
586
587       samples = metadata->data.stream_info.total_samples;
588
589       flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
590       flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
591       flacdec->sample_rate = metadata->data.stream_info.sample_rate;
592       flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
593       flacdec->channels = metadata->data.stream_info.channels;
594
595       if (depth < 9)
596         flacdec->width = 8;
597       else if (depth < 17)
598         flacdec->width = 16;
599       else
600         flacdec->width = 32;
601
602       GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
603           flacdec->min_blocksize, flacdec->max_blocksize);
604       GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
605           flacdec->sample_rate, flacdec->channels);
606       GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
607           flacdec->width);
608
609       /* Only scan for last block in pull-mode, since it uses pull_range() */
610       if (samples == 0 && !flacdec->streaming) {
611         gst_flac_dec_scan_for_last_block (flacdec, &samples);
612       }
613
614       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
615
616       /* in framed mode the demuxer/parser upstream has already pushed a
617        * newsegment event in TIME format which we've passed on */
618       if (samples > 0 && !flacdec->framed) {
619         gint64 duration;
620
621         gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
622             samples);
623
624         /* convert duration to time */
625         duration = gst_util_uint64_scale_int (samples, GST_SECOND,
626             flacdec->sample_rate);
627
628         /* fixme, at this time we could seek to the queued seek event if we have
629          * any */
630         if (flacdec->start_segment)
631           gst_event_unref (flacdec->start_segment);
632         flacdec->start_segment =
633             gst_event_new_new_segment_full (FALSE,
634             flacdec->segment.rate, flacdec->segment.applied_rate,
635             GST_FORMAT_TIME, 0, duration, 0);
636       }
637       break;
638     }
639     case FLAC__METADATA_TYPE_PICTURE:{
640       gst_flac_extract_picture_buffer (flacdec, metadata);
641       break;
642     }
643     case FLAC__METADATA_TYPE_VORBIS_COMMENT:
644       gst_flac_dec_update_metadata (flacdec, metadata);
645       break;
646     default:
647       break;
648   }
649 }
650
651 static void
652 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
653     FLAC__StreamDecoderErrorStatus status, void *client_data)
654 {
655   const gchar *error;
656   GstFlacDec *dec;
657
658   dec = GST_FLAC_DEC (client_data);
659
660   switch (status) {
661     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
662       /* Ignore this error and keep processing */
663       return;
664     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
665       error = "bad header";
666       break;
667     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
668       error = "CRC mismatch";
669       break;
670     default:
671       error = "unknown error";
672       break;
673   }
674
675   GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
676   dec->last_flow = GST_FLOW_ERROR;
677 }
678
679 static FLAC__StreamDecoderSeekStatus
680 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
681     FLAC__uint64 position, void *client_data)
682 {
683   GstFlacDec *flacdec;
684
685   flacdec = GST_FLAC_DEC (client_data);
686
687   GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
688   flacdec->offset = position;
689
690   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
691 }
692
693 static FLAC__StreamDecoderTellStatus
694 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
695     FLAC__uint64 * position, void *client_data)
696 {
697   GstFlacDec *flacdec;
698
699   flacdec = GST_FLAC_DEC (client_data);
700
701   *position = flacdec->offset;
702
703   GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
704
705   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
706 }
707
708 static FLAC__StreamDecoderLengthStatus
709 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
710     FLAC__uint64 * length, void *client_data)
711 {
712   GstFlacDec *flacdec;
713   GstFormat fmt = GST_FORMAT_BYTES;
714   gint64 len = -1;
715
716   flacdec = GST_FLAC_DEC (client_data);
717
718   if (!gst_pad_query_peer_duration (flacdec->sinkpad, &fmt, &len) ||
719       (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 }