upload tizen1.0 source
[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 #include <string.h>
48
49 #include "gstflacdec.h"
50 #include <gst/gst-i18n-plugin.h>
51 #include <gst/gsttagsetter.h>
52 #include <gst/base/gsttypefindhelper.h>
53 #include <gst/audio/multichannel.h>
54 #include <gst/tag/tag.h>
55
56 /* Taken from http://flac.sourceforge.net/format.html#frame_header */
57 static const GstAudioChannelPosition channel_positions[8][8] = {
58   {GST_AUDIO_CHANNEL_POSITION_FRONT_MONO},
59   {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
60       GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}, {
61         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
62         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
63       GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER}, {
64         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
65         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
66         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
67       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
68         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
69         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
70         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
71         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
72       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT}, {
73         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
74         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
75         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
76         GST_AUDIO_CHANNEL_POSITION_LFE,
77         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
78       GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
79   /* FIXME: 7/8 channel layouts are not defined in the FLAC specs */
80   {
81         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
82         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
83         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
84         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
85         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
86         GST_AUDIO_CHANNEL_POSITION_LFE,
87       GST_AUDIO_CHANNEL_POSITION_REAR_CENTER}, {
88         GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
89         GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
90         GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
91         GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
92         GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
93         GST_AUDIO_CHANNEL_POSITION_LFE,
94         GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT,
95       GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT}
96 };
97
98 GST_DEBUG_CATEGORY_STATIC (flacdec_debug);
99 #define GST_CAT_DEFAULT flacdec_debug
100
101 static void gst_flac_dec_finalize (GObject * object);
102 static void gst_flac_dec_loop (GstPad * pad);
103
104 static GstStateChangeReturn gst_flac_dec_change_state (GstElement * element,
105     GstStateChange transition);
106 static const GstQueryType *gst_flac_dec_get_src_query_types (GstPad * pad);
107 static const GstQueryType *gst_flac_dec_get_sink_query_types (GstPad * pad);
108 static gboolean gst_flac_dec_sink_query (GstPad * pad, GstQuery * query);
109 static gboolean gst_flac_dec_src_query (GstPad * pad, GstQuery * query);
110 static gboolean gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format,
111     gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
112 static gboolean gst_flac_dec_src_event (GstPad * pad, GstEvent * event);
113 static gboolean gst_flac_dec_sink_activate (GstPad * sinkpad);
114 static gboolean gst_flac_dec_sink_activate_pull (GstPad * sinkpad,
115     gboolean active);
116 static gboolean gst_flac_dec_sink_activate_push (GstPad * sinkpad,
117     gboolean active);
118 static gboolean gst_flac_dec_sink_event (GstPad * pad, GstEvent * event);
119 static GstFlowReturn gst_flac_dec_chain (GstPad * pad, GstBuffer * buf);
120
121 static void gst_flac_dec_reset_decoders (GstFlacDec * flacdec);
122 static void gst_flac_dec_setup_decoder (GstFlacDec * flacdec);
123
124 static FLAC__StreamDecoderReadStatus
125 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
126     FLAC__byte buffer[], size_t * bytes, void *client_data);
127 static FLAC__StreamDecoderReadStatus
128 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
129     FLAC__byte buffer[], size_t * bytes, void *client_data);
130 static FLAC__StreamDecoderSeekStatus
131 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
132     FLAC__uint64 position, void *client_data);
133 static FLAC__StreamDecoderTellStatus
134 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
135     FLAC__uint64 * position, void *client_data);
136 static FLAC__StreamDecoderLengthStatus
137 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
138     FLAC__uint64 * length, void *client_data);
139 static FLAC__bool gst_flac_dec_eof (const FLAC__StreamDecoder * decoder,
140     void *client_data);
141 static FLAC__StreamDecoderWriteStatus
142 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
143     const FLAC__Frame * frame,
144     const FLAC__int32 * const buffer[], void *client_data);
145 static void gst_flac_dec_metadata_cb (const FLAC__StreamDecoder *
146     decoder, const FLAC__StreamMetadata * metadata, void *client_data);
147 static void gst_flac_dec_error_cb (const FLAC__StreamDecoder *
148     decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
149
150 GST_BOILERPLATE (GstFlacDec, gst_flac_dec, GstElement, GST_TYPE_ELEMENT);
151
152 /* FIXME 0.11: Use width=32 for all depths and let audioconvert
153  * handle the conversions instead of doing it ourself.
154  */
155 #define GST_FLAC_DEC_SRC_CAPS                             \
156     "audio/x-raw-int, "                                   \
157     "endianness = (int) BYTE_ORDER, "                     \
158     "signed = (boolean) true, "                           \
159     "width = (int) { 8, 16, 32 }, "                       \
160     "depth = (int) [ 4, 32 ], "                           \
161     "rate = (int) [ 1, 655350 ], "                        \
162     "channels = (int) [ 1, 8 ]"
163
164 static GstStaticPadTemplate flac_dec_src_factory =
165 GST_STATIC_PAD_TEMPLATE ("src",
166     GST_PAD_SRC,
167     GST_PAD_ALWAYS,
168     GST_STATIC_CAPS (GST_FLAC_DEC_SRC_CAPS));
169 static GstStaticPadTemplate flac_dec_sink_factory =
170 GST_STATIC_PAD_TEMPLATE ("sink",
171     GST_PAD_SINK,
172     GST_PAD_ALWAYS,
173     GST_STATIC_CAPS ("audio/x-flac")
174     );
175
176 static void
177 gst_flac_dec_base_init (gpointer g_class)
178 {
179   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
180
181   gst_element_class_add_pad_template (element_class,
182       gst_static_pad_template_get (&flac_dec_src_factory));
183   gst_element_class_add_pad_template (element_class,
184       gst_static_pad_template_get (&flac_dec_sink_factory));
185   gst_element_class_set_details_simple (element_class, "FLAC audio decoder",
186       "Codec/Decoder/Audio",
187       "Decodes FLAC lossless audio streams", "Wim Taymans <wim@fluendo.com>");
188
189   GST_DEBUG_CATEGORY_INIT (flacdec_debug, "flacdec", 0, "flac decoder");
190 }
191
192 static void
193 gst_flac_dec_class_init (GstFlacDecClass * klass)
194 {
195   GstElementClass *gstelement_class;
196   GObjectClass *gobject_class;
197
198   gstelement_class = (GstElementClass *) klass;
199   gobject_class = (GObjectClass *) klass;
200
201   gobject_class->finalize = gst_flac_dec_finalize;
202
203   gstelement_class->change_state =
204       GST_DEBUG_FUNCPTR (gst_flac_dec_change_state);
205 }
206
207 static void
208 gst_flac_dec_init (GstFlacDec * flacdec, GstFlacDecClass * klass)
209 {
210   flacdec->sinkpad =
211       gst_pad_new_from_static_template (&flac_dec_sink_factory, "sink");
212   gst_pad_set_activate_function (flacdec->sinkpad,
213       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate));
214   gst_pad_set_activatepull_function (flacdec->sinkpad,
215       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_pull));
216   gst_pad_set_activatepush_function (flacdec->sinkpad,
217       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_activate_push));
218   gst_pad_set_query_type_function (flacdec->sinkpad,
219       GST_DEBUG_FUNCPTR (gst_flac_dec_get_sink_query_types));
220   gst_pad_set_query_function (flacdec->sinkpad,
221       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_query));
222   gst_pad_set_event_function (flacdec->sinkpad,
223       GST_DEBUG_FUNCPTR (gst_flac_dec_sink_event));
224   gst_pad_set_chain_function (flacdec->sinkpad,
225       GST_DEBUG_FUNCPTR (gst_flac_dec_chain));
226   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->sinkpad);
227
228   flacdec->srcpad =
229       gst_pad_new_from_static_template (&flac_dec_src_factory, "src");
230   gst_pad_set_query_type_function (flacdec->srcpad,
231       GST_DEBUG_FUNCPTR (gst_flac_dec_get_src_query_types));
232   gst_pad_set_query_function (flacdec->srcpad,
233       GST_DEBUG_FUNCPTR (gst_flac_dec_src_query));
234   gst_pad_set_event_function (flacdec->srcpad,
235       GST_DEBUG_FUNCPTR (gst_flac_dec_src_event));
236   gst_pad_use_fixed_caps (flacdec->srcpad);
237   gst_element_add_pad (GST_ELEMENT (flacdec), flacdec->srcpad);
238
239   gst_flac_dec_reset_decoders (flacdec);
240 }
241
242 static void
243 gst_flac_dec_reset_decoders (GstFlacDec * flacdec)
244 {
245   /* Clean up the decoder */
246   if (flacdec->decoder) {
247     FLAC__stream_decoder_delete (flacdec->decoder);
248     flacdec->decoder = NULL;
249   }
250
251   if (flacdec->adapter) {
252     gst_adapter_clear (flacdec->adapter);
253     g_object_unref (flacdec->adapter);
254     flacdec->adapter = NULL;
255   }
256
257   if (flacdec->close_segment) {
258     gst_event_unref (flacdec->close_segment);
259     flacdec->close_segment = NULL;
260   }
261   if (flacdec->start_segment) {
262     gst_event_unref (flacdec->start_segment);
263     flacdec->start_segment = NULL;
264   }
265   if (flacdec->tags) {
266     gst_tag_list_free (flacdec->tags);
267     flacdec->tags = NULL;
268   }
269   if (flacdec->pending) {
270     gst_buffer_unref (flacdec->pending);
271     flacdec->pending = NULL;
272   }
273
274   flacdec->segment.last_stop = 0;
275   flacdec->offset = 0;
276   flacdec->init = TRUE;
277 }
278
279 static void
280 gst_flac_dec_setup_decoder (GstFlacDec * dec)
281 {
282   gst_flac_dec_reset_decoders (dec);
283
284   dec->tags = gst_tag_list_new ();
285   gst_tag_list_add (dec->tags, GST_TAG_MERGE_REPLACE,
286       GST_TAG_AUDIO_CODEC, "FLAC", NULL);
287
288   dec->adapter = gst_adapter_new ();
289
290   dec->decoder = FLAC__stream_decoder_new ();
291
292   /* no point calculating since it's never checked here */
293   FLAC__stream_decoder_set_md5_checking (dec->decoder, false);
294   FLAC__stream_decoder_set_metadata_respond (dec->decoder,
295       FLAC__METADATA_TYPE_VORBIS_COMMENT);
296   FLAC__stream_decoder_set_metadata_respond (dec->decoder,
297       FLAC__METADATA_TYPE_PICTURE);
298 }
299
300 static void
301 gst_flac_dec_finalize (GObject * object)
302 {
303   GstFlacDec *flacdec;
304
305   flacdec = GST_FLAC_DEC (object);
306
307   gst_flac_dec_reset_decoders (flacdec);
308
309   G_OBJECT_CLASS (parent_class)->finalize (object);
310 }
311
312
313 static gboolean
314 gst_flac_dec_update_metadata (GstFlacDec * flacdec,
315     const FLAC__StreamMetadata * metadata)
316 {
317   GstTagList *list;
318   guint num, i;
319
320   if (flacdec->tags)
321     list = flacdec->tags;
322   else
323     flacdec->tags = list = gst_tag_list_new ();
324
325   num = metadata->data.vorbis_comment.num_comments;
326   GST_DEBUG_OBJECT (flacdec, "%u tag(s) found", num);
327
328   for (i = 0; i < num; ++i) {
329     gchar *vc, *name, *value;
330
331     vc = g_strndup ((gchar *) metadata->data.vorbis_comment.comments[i].entry,
332         metadata->data.vorbis_comment.comments[i].length);
333
334     if (gst_tag_parse_extended_comment (vc, &name, NULL, &value, TRUE)) {
335       GST_DEBUG_OBJECT (flacdec, "%s : %s", name, value);
336       if (value && strlen (value))
337         gst_vorbis_tag_add (list, name, value);
338       g_free (name);
339       g_free (value);
340     }
341
342     g_free (vc);
343   }
344
345   return TRUE;
346 }
347
348 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
349 static const guint8 crc8_table[256] = {
350   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
351   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
352   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
353   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
354   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
355   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
356   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
357   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
358   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
359   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
360   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
361   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
362   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
363   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
364   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
365   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
366   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
367   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
368   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
369   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
370   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
371   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
372   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
373   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
374   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
375   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
376   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
377   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
378   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
379   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
380   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
381   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
382 };
383
384 static guint8
385 gst_flac_calculate_crc8 (guint8 * data, guint length)
386 {
387   guint8 crc = 0;
388
389   while (length--) {
390     crc = crc8_table[crc ^ *data];
391     ++data;
392   }
393
394   return crc;
395 }
396
397 static gboolean
398 gst_flac_dec_scan_got_frame (GstFlacDec * flacdec, guint8 * data, guint size,
399     gint64 * last_sample_num)
400 {
401   guint headerlen;
402   guint sr_from_end = 0;        /* can be 0, 8 or 16 */
403   guint bs_from_end = 0;        /* can be 0, 8 or 16 */
404   guint32 val = 0;
405   guint8 bs, sr, ca, ss, pb;
406
407   if (size < 10)
408     return FALSE;
409
410   /* sync */
411   if (data[0] != 0xFF || data[1] != 0xF8)
412     return FALSE;
413
414   bs = (data[2] & 0xF0) >> 8;   /* blocksize marker   */
415   sr = (data[2] & 0x0F);        /* samplerate marker  */
416   ca = (data[3] & 0xF0) >> 8;   /* channel assignment */
417   ss = (data[3] & 0x0F) >> 1;   /* sample size marker */
418   pb = (data[3] & 0x01);        /* padding bit        */
419
420   GST_LOG_OBJECT (flacdec,
421       "got sync, bs=%x,sr=%x,ca=%x,ss=%x,pb=%x", bs, sr, ca, ss, pb);
422
423   if (sr == 0x0F || ca >= 0x0B || ss == 0x03 || ss == 0x07) {
424     return FALSE;
425   }
426
427   /* read block size from end of header? */
428   if (bs == 6)
429     bs_from_end = 8;
430   else if (bs == 7)
431     bs_from_end = 16;
432
433   /* read sample rate from end of header? */
434   if (sr == 0x0C)
435     sr_from_end = 8;
436   else if (sr == 0x0D || sr == 0x0E)
437     sr_from_end = 16;
438
439   /* FIXME: This is can be 36 bit if variable block size is used,
440    * fortunately not encoder supports this yet and we check for that
441    * above.
442    */
443   val = (guint32) g_utf8_get_char_validated ((gchar *) data + 4, -1);
444
445   if (val == (guint32) - 1 || val == (guint32) - 2) {
446     GST_LOG_OBJECT (flacdec, "failed to read sample/frame");
447     return FALSE;
448   }
449
450   headerlen = 4 + g_unichar_to_utf8 ((gunichar) val, NULL) +
451       (bs_from_end / 8) + (sr_from_end / 8);
452
453   if (gst_flac_calculate_crc8 (data, headerlen) != data[headerlen]) {
454     GST_LOG_OBJECT (flacdec, "invalid checksum");
455     return FALSE;
456   }
457
458   if (flacdec->min_blocksize == flacdec->max_blocksize) {
459     *last_sample_num = (val + 1) * flacdec->min_blocksize;
460   } else {
461     *last_sample_num = 0;       /* FIXME: + length of last block in samples */
462   }
463
464   /* FIXME: only valid for fixed block size streams */
465   GST_DEBUG_OBJECT (flacdec, "frame number: %" G_GINT64_FORMAT,
466       *last_sample_num);
467
468   if (flacdec->sample_rate > 0 && *last_sample_num != 0) {
469     GST_DEBUG_OBJECT (flacdec, "last sample %" G_GINT64_FORMAT " = %"
470         GST_TIME_FORMAT, *last_sample_num,
471         GST_TIME_ARGS (*last_sample_num * GST_SECOND / flacdec->sample_rate));
472   }
473
474   return TRUE;
475 }
476
477 #define SCANBLOCK_SIZE  (64*1024)
478
479 static void
480 gst_flac_dec_scan_for_last_block (GstFlacDec * flacdec, gint64 * samples)
481 {
482   GstFormat format = GST_FORMAT_BYTES;
483   gint64 file_size, offset;
484
485   GST_INFO_OBJECT (flacdec, "total number of samples unknown, scanning file");
486
487   if (!gst_pad_query_peer_duration (flacdec->sinkpad, &format, &file_size)) {
488     GST_WARNING_OBJECT (flacdec, "failed to query upstream size!");
489     return;
490   }
491
492   if (flacdec->min_blocksize != flacdec->max_blocksize) {
493     GST_WARNING_OBJECT (flacdec, "scanning for last sample only works "
494         "for FLAC files with constant blocksize");
495     return;
496   }
497
498   GST_DEBUG_OBJECT (flacdec, "upstream size: %" G_GINT64_FORMAT, file_size);
499
500   offset = file_size - 1;
501   while (offset >= MAX (SCANBLOCK_SIZE / 2, file_size / 2)) {
502     GstFlowReturn flow;
503     GstBuffer *buf = NULL;
504     guint8 *data;
505     guint size;
506
507     /* divide by 2 = not very sophisticated way to deal with overlapping */
508     offset -= SCANBLOCK_SIZE / 2;
509     GST_LOG_OBJECT (flacdec, "looking for frame at %" G_GINT64_FORMAT
510         "-%" G_GINT64_FORMAT, offset, offset + SCANBLOCK_SIZE);
511
512     flow = gst_pad_pull_range (flacdec->sinkpad, offset, SCANBLOCK_SIZE, &buf);
513     if (flow != GST_FLOW_OK) {
514       GST_DEBUG_OBJECT (flacdec, "flow = %s", gst_flow_get_name (flow));
515       return;
516     }
517
518     size = GST_BUFFER_SIZE (buf);
519     data = GST_BUFFER_DATA (buf);
520
521     while (size > 16) {
522       if (gst_flac_dec_scan_got_frame (flacdec, data, size, samples)) {
523         GST_DEBUG_OBJECT (flacdec, "frame sync at offset %" G_GINT64_FORMAT,
524             offset + GST_BUFFER_SIZE (buf) - size);
525         gst_buffer_unref (buf);
526         return;
527       }
528       ++data;
529       --size;
530     }
531
532     gst_buffer_unref (buf);
533   }
534 }
535
536 static void
537 gst_flac_extract_picture_buffer (GstFlacDec * dec,
538     const FLAC__StreamMetadata * metadata)
539 {
540   FLAC__StreamMetadata_Picture picture;
541   GstTagList *tags;
542
543   g_return_if_fail (metadata->type == FLAC__METADATA_TYPE_PICTURE);
544
545   GST_LOG_OBJECT (dec, "Got PICTURE block");
546   picture = metadata->data.picture;
547
548   GST_DEBUG_OBJECT (dec, "declared MIME type is: '%s'",
549       GST_STR_NULL (picture.mime_type));
550   GST_DEBUG_OBJECT (dec, "image data is %u bytes", picture.data_length);
551
552   tags = gst_tag_list_new ();
553
554   gst_tag_list_add_id3_image (tags, (guint8 *) picture.data,
555       picture.data_length, picture.type);
556
557   if (!gst_tag_list_is_empty (tags)) {
558     gst_element_found_tags_for_pad (GST_ELEMENT (dec), dec->srcpad, tags);
559   } else {
560     GST_DEBUG_OBJECT (dec, "problem parsing PICTURE block, skipping");
561     gst_tag_list_free (tags);
562   }
563 }
564
565 static void
566 gst_flac_dec_metadata_cb (const FLAC__StreamDecoder * decoder,
567     const FLAC__StreamMetadata * metadata, void *client_data)
568 {
569   GstFlacDec *flacdec = GST_FLAC_DEC (client_data);
570
571   GST_LOG_OBJECT (flacdec, "metadata type: %d", metadata->type);
572
573   switch (metadata->type) {
574     case FLAC__METADATA_TYPE_STREAMINFO:{
575       gint64 samples;
576       guint depth;
577
578       samples = metadata->data.stream_info.total_samples;
579
580       flacdec->min_blocksize = metadata->data.stream_info.min_blocksize;
581       flacdec->max_blocksize = metadata->data.stream_info.max_blocksize;
582       flacdec->sample_rate = metadata->data.stream_info.sample_rate;
583       flacdec->depth = depth = metadata->data.stream_info.bits_per_sample;
584       flacdec->channels = metadata->data.stream_info.channels;
585
586       if (depth < 9)
587         flacdec->width = 8;
588       else if (depth < 17)
589         flacdec->width = 16;
590       else
591         flacdec->width = 32;
592
593       GST_DEBUG_OBJECT (flacdec, "blocksize: min=%u, max=%u",
594           flacdec->min_blocksize, flacdec->max_blocksize);
595       GST_DEBUG_OBJECT (flacdec, "sample rate: %u, channels: %u",
596           flacdec->sample_rate, flacdec->channels);
597       GST_DEBUG_OBJECT (flacdec, "depth: %u, width: %u", flacdec->depth,
598           flacdec->width);
599
600       /* Only scan for last block in pull-mode, since it uses pull_range() */
601       if (samples == 0 && !flacdec->streaming) {
602         gst_flac_dec_scan_for_last_block (flacdec, &samples);
603       }
604
605       GST_DEBUG_OBJECT (flacdec, "total samples = %" G_GINT64_FORMAT, samples);
606
607       /* in framed mode the demuxer/parser upstream has already pushed a
608        * newsegment event in TIME format which we've passed on */
609       if (samples > 0 && !flacdec->framed) {
610         gint64 duration;
611
612         gst_segment_set_duration (&flacdec->segment, GST_FORMAT_DEFAULT,
613             samples);
614
615         /* convert duration to time */
616         duration = gst_util_uint64_scale_int (samples, GST_SECOND,
617             flacdec->sample_rate);
618
619         /* fixme, at this time we could seek to the queued seek event if we have
620          * any */
621         if (flacdec->start_segment)
622           gst_event_unref (flacdec->start_segment);
623         flacdec->start_segment =
624             gst_event_new_new_segment_full (FALSE,
625             flacdec->segment.rate, flacdec->segment.applied_rate,
626             GST_FORMAT_TIME, 0, duration, 0);
627       }
628       break;
629     }
630     case FLAC__METADATA_TYPE_PICTURE:{
631       gst_flac_extract_picture_buffer (flacdec, metadata);
632       break;
633     }
634     case FLAC__METADATA_TYPE_VORBIS_COMMENT:
635       gst_flac_dec_update_metadata (flacdec, metadata);
636       break;
637     default:
638       break;
639   }
640 }
641
642 static void
643 gst_flac_dec_error_cb (const FLAC__StreamDecoder * d,
644     FLAC__StreamDecoderErrorStatus status, void *client_data)
645 {
646   const gchar *error;
647   GstFlacDec *dec;
648
649   dec = GST_FLAC_DEC (client_data);
650
651   switch (status) {
652     case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
653       /* Ignore this error and keep processing */
654       return;
655     case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
656       error = "bad header";
657       break;
658     case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
659       error = "CRC mismatch";
660       break;
661     default:
662       error = "unknown error";
663       break;
664   }
665
666   GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL), ("%s (%d)", error, status));
667   dec->last_flow = GST_FLOW_ERROR;
668 }
669
670 static FLAC__StreamDecoderSeekStatus
671 gst_flac_dec_seek (const FLAC__StreamDecoder * decoder,
672     FLAC__uint64 position, void *client_data)
673 {
674   GstFlacDec *flacdec;
675
676   flacdec = GST_FLAC_DEC (client_data);
677
678   GST_DEBUG_OBJECT (flacdec, "seek %" G_GUINT64_FORMAT, (guint64) position);
679   flacdec->offset = position;
680
681   return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
682 }
683
684 static FLAC__StreamDecoderTellStatus
685 gst_flac_dec_tell (const FLAC__StreamDecoder * decoder,
686     FLAC__uint64 * position, void *client_data)
687 {
688   GstFlacDec *flacdec;
689
690   flacdec = GST_FLAC_DEC (client_data);
691
692   *position = flacdec->offset;
693
694   GST_DEBUG_OBJECT (flacdec, "tell %" G_GINT64_FORMAT, (gint64) * position);
695
696   return FLAC__STREAM_DECODER_TELL_STATUS_OK;
697 }
698
699 static FLAC__StreamDecoderLengthStatus
700 gst_flac_dec_length (const FLAC__StreamDecoder * decoder,
701     FLAC__uint64 * length, void *client_data)
702 {
703   GstFlacDec *flacdec;
704   GstFormat fmt = GST_FORMAT_BYTES;
705   gint64 len;
706   GstPad *peer;
707
708   flacdec = GST_FLAC_DEC (client_data);
709
710   if (!(peer = gst_pad_get_peer (flacdec->sinkpad)))
711     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
712
713   gst_pad_query_duration (peer, &fmt, &len);
714   gst_object_unref (peer);
715   if (fmt != GST_FORMAT_BYTES || len == -1)
716     return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
717
718   *length = len;
719
720   GST_DEBUG_OBJECT (flacdec, "encoded byte length %" G_GINT64_FORMAT,
721       (gint64) * length);
722
723   return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
724 }
725
726 static FLAC__bool
727 gst_flac_dec_eof (const FLAC__StreamDecoder * decoder, void *client_data)
728 {
729   GstFlacDec *flacdec;
730   GstFormat fmt;
731   GstPad *peer;
732   gboolean ret = FALSE;
733   gint64 len;
734
735   flacdec = GST_FLAC_DEC (client_data);
736
737   if (!(peer = gst_pad_get_peer (flacdec->sinkpad))) {
738     GST_WARNING_OBJECT (flacdec, "no peer pad, returning EOF");
739     return TRUE;
740   }
741
742   fmt = GST_FORMAT_BYTES;
743   if (gst_pad_query_duration (peer, &fmt, &len) && fmt == GST_FORMAT_BYTES &&
744       len != -1 && flacdec->offset >= len) {
745     GST_DEBUG_OBJECT (flacdec,
746         "offset=%" G_GINT64_FORMAT ", len=%" G_GINT64_FORMAT
747         ", returning EOF", flacdec->offset, len);
748     ret = TRUE;
749   }
750
751   gst_object_unref (peer);
752
753   return ret;
754 }
755
756 static FLAC__StreamDecoderReadStatus
757 gst_flac_dec_read_seekable (const FLAC__StreamDecoder * decoder,
758     FLAC__byte buffer[], size_t * bytes, void *client_data)
759 {
760   GstFlowReturn flow;
761   GstFlacDec *flacdec;
762   GstBuffer *buf;
763
764   flacdec = GST_FLAC_DEC (client_data);
765
766   flow = gst_pad_pull_range (flacdec->sinkpad, flacdec->offset, *bytes, &buf);
767
768   GST_PAD_STREAM_LOCK (flacdec->sinkpad);
769   flacdec->pull_flow = flow;
770   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
771
772   if (G_UNLIKELY (flow != GST_FLOW_OK)) {
773     GST_INFO_OBJECT (flacdec, "pull_range flow: %s", gst_flow_get_name (flow));
774     if (flow == GST_FLOW_UNEXPECTED)
775       return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
776     else
777       return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
778   }
779
780   GST_DEBUG_OBJECT (flacdec, "Read %d bytes at %" G_GUINT64_FORMAT,
781       GST_BUFFER_SIZE (buf), flacdec->offset);
782   memcpy (buffer, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
783   *bytes = GST_BUFFER_SIZE (buf);
784   gst_buffer_unref (buf);
785   flacdec->offset += *bytes;
786
787   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
788 }
789
790 static FLAC__StreamDecoderReadStatus
791 gst_flac_dec_read_stream (const FLAC__StreamDecoder * decoder,
792     FLAC__byte buffer[], size_t * bytes, void *client_data)
793 {
794   GstFlacDec *dec = GST_FLAC_DEC (client_data);
795   guint len;
796
797   len = MIN (gst_adapter_available (dec->adapter), *bytes);
798
799   if (len == 0) {
800     GST_LOG_OBJECT (dec, "0 bytes available at the moment");
801     return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
802   }
803
804   GST_LOG_OBJECT (dec, "feeding %u bytes to decoder (available=%u, bytes=%u)",
805       len, gst_adapter_available (dec->adapter), (guint) * bytes);
806   gst_adapter_copy (dec->adapter, buffer, 0, len);
807   *bytes = len;
808
809   gst_adapter_flush (dec->adapter, len);
810
811   return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
812 }
813
814 static FLAC__StreamDecoderWriteStatus
815 gst_flac_dec_write (GstFlacDec * flacdec, const FLAC__Frame * frame,
816     const FLAC__int32 * const buffer[])
817 {
818   GstFlowReturn ret = GST_FLOW_OK;
819   GstBuffer *outbuf;
820   guint depth = frame->header.bits_per_sample;
821   guint width;
822   guint sample_rate = frame->header.sample_rate;
823   guint channels = frame->header.channels;
824   guint samples = frame->header.blocksize;
825   guint j, i;
826   GstClockTime next;
827
828   GST_LOG_OBJECT (flacdec, "samples in frame header: %d", samples);
829
830   /* if a DEFAULT segment is configured, don't send samples past the end
831    * of the segment */
832   if (flacdec->segment.format == GST_FORMAT_DEFAULT &&
833       flacdec->segment.stop != -1 &&
834       flacdec->segment.last_stop >= 0 &&
835       flacdec->segment.last_stop + samples > flacdec->segment.stop) {
836     samples = flacdec->segment.stop - flacdec->segment.last_stop;
837     GST_DEBUG_OBJECT (flacdec,
838         "clipping last buffer to %d samples because of segment", samples);
839   }
840
841   switch (depth) {
842     case 8:
843       width = 8;
844       break;
845     case 12:
846     case 16:
847       width = 16;
848       break;
849     case 20:
850     case 24:
851     case 32:
852       width = 32;
853       break;
854     case 0:
855       if (flacdec->depth < 4 || flacdec->depth > 32) {
856         GST_ERROR_OBJECT (flacdec, "unsupported depth %d from STREAMINFO",
857             flacdec->depth);
858         ret = GST_FLOW_ERROR;
859         goto done;
860       }
861
862       depth = flacdec->depth;
863       if (depth < 9)
864         width = 8;
865       else if (depth < 17)
866         width = 16;
867       else
868         width = 32;
869
870       break;
871     default:
872       GST_ERROR_OBJECT (flacdec, "unsupported depth %d", depth);
873       ret = GST_FLOW_ERROR;
874       goto done;
875   }
876
877   if (sample_rate == 0) {
878     if (flacdec->sample_rate != 0) {
879       sample_rate = flacdec->sample_rate;
880     } else {
881       GST_ERROR_OBJECT (flacdec, "unknown sample rate");
882       ret = GST_FLOW_ERROR;
883       goto done;
884     }
885   }
886
887   if (!GST_PAD_CAPS (flacdec->srcpad)) {
888     GstCaps *caps;
889
890     GST_DEBUG_OBJECT (flacdec, "Negotiating %d Hz @ %d channels",
891         frame->header.sample_rate, channels);
892
893     caps = gst_caps_new_simple ("audio/x-raw-int",
894         "endianness", G_TYPE_INT, G_BYTE_ORDER,
895         "signed", G_TYPE_BOOLEAN, TRUE,
896         "width", G_TYPE_INT, width,
897         "depth", G_TYPE_INT, depth,
898         "rate", G_TYPE_INT, frame->header.sample_rate,
899         "channels", G_TYPE_INT, channels, NULL);
900
901     if (channels > 2) {
902       GstStructure *s = gst_caps_get_structure (caps, 0);
903
904       gst_audio_set_channel_positions (s, channel_positions[channels - 1]);
905     }
906
907     flacdec->depth = depth;
908     flacdec->width = width;
909     flacdec->channels = channels;
910     flacdec->sample_rate = sample_rate;
911
912     gst_pad_set_caps (flacdec->srcpad, caps);
913     gst_caps_unref (caps);
914   }
915
916   if (flacdec->close_segment) {
917     GST_DEBUG_OBJECT (flacdec, "pushing close segment");
918     gst_pad_push_event (flacdec->srcpad, flacdec->close_segment);
919     flacdec->close_segment = NULL;
920   }
921   if (flacdec->start_segment) {
922     GST_DEBUG_OBJECT (flacdec, "pushing start segment");
923     gst_pad_push_event (flacdec->srcpad, flacdec->start_segment);
924     flacdec->start_segment = NULL;
925   }
926
927   if (flacdec->tags) {
928     gst_element_found_tags_for_pad (GST_ELEMENT (flacdec), flacdec->srcpad,
929         flacdec->tags);
930     flacdec->tags = NULL;
931   }
932
933   if (flacdec->pending) {
934     GST_DEBUG_OBJECT (flacdec,
935         "pushing pending samples at offset %" G_GINT64_FORMAT " (%"
936         GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
937         GST_BUFFER_OFFSET (flacdec->pending),
938         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (flacdec->pending)),
939         GST_TIME_ARGS (GST_BUFFER_DURATION (flacdec->pending)));
940     /* Pending buffer was always allocated from the seeking thread,
941      * which means it wasn't gst_buffer_alloc'd. Do so now to let
942      * downstream negotiation work on older basetransform */
943     ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
944         GST_BUFFER_OFFSET (flacdec->pending),
945         GST_BUFFER_SIZE (flacdec->pending),
946         GST_BUFFER_CAPS (flacdec->pending), &outbuf);
947     if (ret == GST_FLOW_OK) {
948       gst_pad_push (flacdec->srcpad, flacdec->pending);
949       gst_buffer_unref (outbuf);
950     }
951
952     outbuf = flacdec->pending = NULL;
953     flacdec->segment.last_stop += flacdec->pending_samples;
954     flacdec->pending_samples = 0;
955   }
956
957   if (flacdec->seeking) {
958     GST_DEBUG_OBJECT (flacdec, "a pad_alloc would block here, do normal alloc");
959     outbuf = gst_buffer_new_and_alloc (samples * channels * (width / 8));
960     gst_buffer_set_caps (outbuf, GST_PAD_CAPS (flacdec->srcpad));
961     GST_BUFFER_OFFSET (outbuf) = flacdec->segment.last_stop;
962   } else {
963     GST_LOG_OBJECT (flacdec, "alloc_buffer_and_set_caps");
964     ret = gst_pad_alloc_buffer_and_set_caps (flacdec->srcpad,
965         flacdec->segment.last_stop, samples * channels * (width / 8),
966         GST_PAD_CAPS (flacdec->srcpad), &outbuf);
967
968     if (ret != GST_FLOW_OK) {
969       GST_DEBUG_OBJECT (flacdec, "gst_pad_alloc_buffer() returned %s",
970           gst_flow_get_name (ret));
971       goto done;
972     }
973   }
974
975   if (flacdec->cur_granulepos != GST_BUFFER_OFFSET_NONE) {
976     /* this should be fine since it should be one flac frame per ogg packet */
977     flacdec->segment.last_stop = flacdec->cur_granulepos - samples;
978     GST_LOG_OBJECT (flacdec, "granulepos = %" G_GINT64_FORMAT ", samples = %u",
979         flacdec->cur_granulepos, samples);
980   }
981
982   GST_BUFFER_TIMESTAMP (outbuf) =
983       gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
984       frame->header.sample_rate);
985
986   /* get next timestamp to calculate the duration */
987   next = gst_util_uint64_scale_int (flacdec->segment.last_stop + samples,
988       GST_SECOND, frame->header.sample_rate);
989
990   GST_BUFFER_DURATION (outbuf) = next - GST_BUFFER_TIMESTAMP (outbuf);
991
992   if (width == 8) {
993     gint8 *outbuffer = (gint8 *) GST_BUFFER_DATA (outbuf);
994
995     for (i = 0; i < samples; i++) {
996       for (j = 0; j < channels; j++) {
997         *outbuffer++ = (gint8) buffer[j][i];
998       }
999     }
1000   } else if (width == 16) {
1001     gint16 *outbuffer = (gint16 *) GST_BUFFER_DATA (outbuf);
1002
1003     for (i = 0; i < samples; i++) {
1004       for (j = 0; j < channels; j++) {
1005         *outbuffer++ = (gint16) buffer[j][i];
1006       }
1007     }
1008   } else if (width == 32) {
1009     gint32 *outbuffer = (gint32 *) GST_BUFFER_DATA (outbuf);
1010
1011     for (i = 0; i < samples; i++) {
1012       for (j = 0; j < channels; j++) {
1013         *outbuffer++ = (gint32) buffer[j][i];
1014       }
1015     }
1016   } else {
1017     g_assert_not_reached ();
1018   }
1019
1020   if (!flacdec->seeking) {
1021     GST_DEBUG_OBJECT (flacdec, "pushing %d samples at offset %" G_GINT64_FORMAT
1022         " (%" GST_TIME_FORMAT " + %" GST_TIME_FORMAT ")",
1023         samples, GST_BUFFER_OFFSET (outbuf),
1024         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)),
1025         GST_TIME_ARGS (GST_BUFFER_DURATION (outbuf)));
1026
1027     if (flacdec->discont) {
1028       GST_DEBUG_OBJECT (flacdec, "marking discont");
1029       outbuf = gst_buffer_make_metadata_writable (outbuf);
1030       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1031       flacdec->discont = FALSE;
1032     }
1033     ret = gst_pad_push (flacdec->srcpad, outbuf);
1034     GST_DEBUG_OBJECT (flacdec, "returned %s", gst_flow_get_name (ret));
1035     flacdec->segment.last_stop += samples;
1036   } else {
1037     GST_DEBUG_OBJECT (flacdec,
1038         "not pushing %d samples at offset %" G_GINT64_FORMAT
1039         " (in seek)", samples, GST_BUFFER_OFFSET (outbuf));
1040     gst_buffer_replace (&flacdec->pending, outbuf);
1041     gst_buffer_unref (outbuf);
1042     flacdec->pending_samples = samples;
1043     ret = GST_FLOW_OK;
1044   }
1045
1046   if (ret != GST_FLOW_OK) {
1047     GST_DEBUG_OBJECT (flacdec, "gst_pad_push() returned %s",
1048         gst_flow_get_name (ret));
1049   }
1050
1051 done:
1052
1053
1054   /* we act on the flow return value later in the loop function, as we don't
1055    * want to mess up the internal decoder state by returning ABORT when the
1056    * error is in fact non-fatal (like a pad in flushing mode) and we want
1057    * to continue later. So just pretend everything's dandy and act later. */
1058   flacdec->last_flow = ret;
1059
1060   return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
1061 }
1062
1063 static FLAC__StreamDecoderWriteStatus
1064 gst_flac_dec_write_stream (const FLAC__StreamDecoder * decoder,
1065     const FLAC__Frame * frame,
1066     const FLAC__int32 * const buffer[], void *client_data)
1067 {
1068   return gst_flac_dec_write (GST_FLAC_DEC (client_data), frame, buffer);
1069 }
1070
1071 static void
1072 gst_flac_dec_loop (GstPad * sinkpad)
1073 {
1074   GstFlacDec *flacdec;
1075   FLAC__StreamDecoderState s;
1076   FLAC__StreamDecoderInitStatus is;
1077
1078   flacdec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
1079
1080   GST_LOG_OBJECT (flacdec, "entering loop");
1081
1082   if (flacdec->init) {
1083     GST_DEBUG_OBJECT (flacdec, "initializing new decoder");
1084     is = FLAC__stream_decoder_init_stream (flacdec->decoder,
1085         gst_flac_dec_read_seekable, gst_flac_dec_seek, gst_flac_dec_tell,
1086         gst_flac_dec_length, gst_flac_dec_eof, gst_flac_dec_write_stream,
1087         gst_flac_dec_metadata_cb, gst_flac_dec_error_cb, flacdec);
1088     if (is != FLAC__STREAM_DECODER_INIT_STATUS_OK)
1089       goto analyze_state;
1090
1091     /*    FLAC__seekable_decoder_process_metadata (flacdec->decoder); */
1092     flacdec->init = FALSE;
1093   }
1094
1095   flacdec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1096
1097   flacdec->last_flow = GST_FLOW_OK;
1098
1099   GST_LOG_OBJECT (flacdec, "processing single");
1100   FLAC__stream_decoder_process_single (flacdec->decoder);
1101
1102 analyze_state:
1103
1104   GST_LOG_OBJECT (flacdec, "done processing, checking encoder state");
1105   s = FLAC__stream_decoder_get_state (flacdec->decoder);
1106   switch (s) {
1107     case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
1108     case FLAC__STREAM_DECODER_READ_METADATA:
1109     case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
1110     case FLAC__STREAM_DECODER_READ_FRAME:
1111     {
1112       GST_DEBUG_OBJECT (flacdec, "everything ok");
1113
1114       if (flacdec->last_flow < GST_FLOW_UNEXPECTED ||
1115           flacdec->last_flow == GST_FLOW_NOT_LINKED) {
1116         GST_ELEMENT_ERROR (flacdec, STREAM, FAILED,
1117             (_("Internal data stream error.")),
1118             ("stream stopped, reason %s",
1119                 gst_flow_get_name (flacdec->last_flow)));
1120         goto eos_and_pause;
1121       } else if (flacdec->last_flow == GST_FLOW_UNEXPECTED) {
1122         goto eos_and_pause;
1123       } else if (flacdec->last_flow != GST_FLOW_OK) {
1124         goto pause;
1125       }
1126
1127       /* check if we're at the end of a configured segment */
1128       if (flacdec->segment.stop != -1 &&
1129           flacdec->segment.last_stop > 0 &&
1130           flacdec->segment.last_stop >= flacdec->segment.stop) {
1131         GST_DEBUG_OBJECT (flacdec, "reached end of the configured segment");
1132
1133         if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) == 0) {
1134           goto eos_and_pause;
1135         } else {
1136           goto segment_done_and_pause;
1137         }
1138
1139         g_assert_not_reached ();
1140       }
1141
1142       return;
1143     }
1144
1145     case FLAC__STREAM_DECODER_END_OF_STREAM:{
1146       GST_DEBUG_OBJECT (flacdec, "EOS");
1147       FLAC__stream_decoder_reset (flacdec->decoder);
1148
1149       if ((flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0) {
1150         if (flacdec->segment.duration > 0) {
1151           flacdec->segment.stop = flacdec->segment.duration;
1152         } else {
1153           flacdec->segment.stop = flacdec->segment.last_stop;
1154         }
1155         goto segment_done_and_pause;
1156       }
1157
1158       goto eos_and_pause;
1159     }
1160
1161       /* gst_flac_dec_read_seekable() returned ABORTED */
1162     case FLAC__STREAM_DECODER_ABORTED:
1163     {
1164       GST_INFO_OBJECT (flacdec, "read aborted: last pull_range flow = %s",
1165           gst_flow_get_name (flacdec->pull_flow));
1166       if (flacdec->pull_flow == GST_FLOW_WRONG_STATE) {
1167         /* it seems we need to flush the decoder here to reset the decoder
1168          * state after the abort for FLAC__stream_decoder_seek_absolute()
1169          * to work properly */
1170         GST_DEBUG_OBJECT (flacdec, "flushing decoder to reset decoder state");
1171         FLAC__stream_decoder_flush (flacdec->decoder);
1172         goto pause;
1173       }
1174       /* fall through */
1175     }
1176     case FLAC__STREAM_DECODER_OGG_ERROR:
1177     case FLAC__STREAM_DECODER_SEEK_ERROR:
1178     case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
1179     case FLAC__STREAM_DECODER_UNINITIALIZED:
1180     default:{
1181       /* fixme: this error sucks -- should try to figure out when/if an more
1182          specific error was already sent via the callback */
1183       GST_ELEMENT_ERROR (flacdec, STREAM, DECODE, (NULL),
1184           ("%s", FLAC__StreamDecoderStateString[s]));
1185       goto eos_and_pause;
1186     }
1187   }
1188
1189   return;
1190
1191 segment_done_and_pause:
1192   {
1193     gint64 stop_time;
1194
1195     stop_time = gst_util_uint64_scale_int (flacdec->segment.stop,
1196         GST_SECOND, flacdec->sample_rate);
1197
1198     GST_DEBUG_OBJECT (flacdec, "posting SEGMENT_DONE message, stop time %"
1199         GST_TIME_FORMAT, GST_TIME_ARGS (stop_time));
1200
1201     gst_element_post_message (GST_ELEMENT (flacdec),
1202         gst_message_new_segment_done (GST_OBJECT (flacdec),
1203             GST_FORMAT_TIME, stop_time));
1204
1205     goto pause;
1206   }
1207 eos_and_pause:
1208   {
1209     GST_DEBUG_OBJECT (flacdec, "sending EOS event");
1210     flacdec->running = FALSE;
1211     gst_pad_push_event (flacdec->srcpad, gst_event_new_eos ());
1212     /* fall through to pause */
1213   }
1214 pause:
1215   {
1216     GST_DEBUG_OBJECT (flacdec, "pausing");
1217     gst_pad_pause_task (sinkpad);
1218     return;
1219   }
1220 }
1221
1222 static gboolean
1223 gst_flac_dec_sink_event (GstPad * pad, GstEvent * event)
1224 {
1225   GstFlacDec *dec;
1226   gboolean res;
1227
1228   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1229
1230   switch (GST_EVENT_TYPE (event)) {
1231     case GST_EVENT_FLUSH_STOP:{
1232       if (dec->init == FALSE) {
1233         FLAC__stream_decoder_flush (dec->decoder);
1234         gst_adapter_clear (dec->adapter);
1235       }
1236       res = gst_pad_push_event (dec->srcpad, event);
1237       break;
1238     }
1239     case GST_EVENT_NEWSEGMENT:{
1240       GstFormat fmt;
1241       gboolean update;
1242       gdouble rate, applied_rate;
1243       gint64 cur, stop, time;
1244
1245       gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
1246           &fmt, &cur, &stop, &time);
1247
1248       if (fmt == GST_FORMAT_TIME) {
1249         GstFormat dformat = GST_FORMAT_DEFAULT;
1250
1251         GST_DEBUG_OBJECT (dec, "newsegment event in TIME format => framed");
1252         dec->framed = TRUE;
1253         res = gst_pad_push_event (dec->srcpad, event);
1254
1255         /* this won't work for the first newsegment event though ... */
1256         if (gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, cur,
1257                 &dformat, &cur) && cur != -1 &&
1258             gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME, stop,
1259                 &dformat, &stop) && stop != -1) {
1260           gst_segment_set_newsegment_full (&dec->segment, update, rate,
1261               applied_rate, dformat, cur, stop, time);
1262           GST_DEBUG_OBJECT (dec, "segment %" GST_SEGMENT_FORMAT, &dec->segment);
1263         } else {
1264           GST_WARNING_OBJECT (dec, "couldn't convert time => samples");
1265         }
1266       } else if (fmt == GST_FORMAT_BYTES || TRUE) {
1267         GST_DEBUG_OBJECT (dec, "newsegment event in %s format => not framed",
1268             gst_format_get_name (fmt));
1269         dec->framed = FALSE;
1270
1271         /* prepare generic newsegment event, for some reason our metadata
1272          * callback where we usually set this up is not being called in
1273          * push mode */
1274         if (dec->start_segment)
1275           gst_event_unref (dec->start_segment);
1276         dec->start_segment = gst_event_new_new_segment (FALSE, 1.0,
1277             GST_FORMAT_TIME, 0, -1, 0);
1278
1279         gst_event_unref (event);
1280         res = TRUE;
1281       }
1282       break;
1283     }
1284     case GST_EVENT_EOS:{
1285       GST_LOG_OBJECT (dec, "EOS, with %u bytes available in adapter",
1286           gst_adapter_available (dec->adapter));
1287       if (dec->init == FALSE) {
1288         if (gst_adapter_available (dec->adapter) > 0) {
1289           FLAC__stream_decoder_process_until_end_of_stream (dec->decoder);
1290         }
1291         FLAC__stream_decoder_flush (dec->decoder);
1292       }
1293       gst_adapter_clear (dec->adapter);
1294       res = gst_pad_push_event (dec->srcpad, event);
1295       break;
1296     }
1297     default:
1298       res = gst_pad_event_default (pad, event);
1299       break;
1300   }
1301
1302   gst_object_unref (dec);
1303
1304   return res;
1305 }
1306
1307 static gboolean
1308 gst_flac_dec_chain_parse_headers (GstFlacDec * dec)
1309 {
1310   guint8 marker[4];
1311   guint avail, off;
1312
1313   avail = gst_adapter_available (dec->adapter);
1314   if (avail < 4)
1315     return FALSE;
1316
1317   gst_adapter_copy (dec->adapter, marker, 0, 4);
1318   if (strncmp ((const gchar *) marker, "fLaC", 4) != 0) {
1319     GST_ERROR_OBJECT (dec, "Unexpected header, expected fLaC header");
1320     return TRUE;                /* abort header parsing */
1321   }
1322
1323   GST_DEBUG_OBJECT (dec, "fLaC header          : len           4 @ %7u", 0);
1324
1325   off = 4;
1326   while (avail > (off + 1 + 3)) {
1327     gboolean is_last;
1328     guint8 mb_hdr[4];
1329     guint len, block_type;
1330
1331     gst_adapter_copy (dec->adapter, mb_hdr, off, 4);
1332
1333     is_last = ((mb_hdr[0] & 0x80) == 0x80);
1334     block_type = mb_hdr[0] & 0x7f;
1335     len = GST_READ_UINT24_BE (mb_hdr + 1);
1336     GST_DEBUG_OBJECT (dec, "Metadata block type %u: len %7u + 4 @ %7u%s",
1337         block_type, len, off, (is_last) ? " (last)" : "");
1338     off += 4 + len;
1339
1340     if (is_last)
1341       break;
1342
1343     if (off >= avail) {
1344       GST_LOG_OBJECT (dec, "Need more data: next offset %u > avail %u", off,
1345           avail);
1346       return FALSE;
1347     }
1348   }
1349
1350   /* want metadata blocks plus at least one frame */
1351   return (off + FLAC__MAX_BLOCK_SIZE >= avail);
1352 }
1353
1354 static GstFlowReturn
1355 gst_flac_dec_chain (GstPad * pad, GstBuffer * buf)
1356 {
1357   FLAC__StreamDecoderInitStatus s;
1358   GstFlacDec *dec;
1359   gboolean got_audio_frame;
1360
1361   dec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1362
1363   GST_LOG_OBJECT (dec, "buffer with ts=%" GST_TIME_FORMAT ", end_offset=%"
1364       G_GINT64_FORMAT ", size=%u", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
1365       GST_BUFFER_OFFSET_END (buf), GST_BUFFER_SIZE (buf));
1366
1367   if (dec->init) {
1368     GST_DEBUG_OBJECT (dec, "initializing decoder");
1369     s = FLAC__stream_decoder_init_stream (dec->decoder,
1370         gst_flac_dec_read_stream, NULL, NULL, NULL, NULL,
1371         gst_flac_dec_write_stream, gst_flac_dec_metadata_cb,
1372         gst_flac_dec_error_cb, dec);
1373     if (s != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
1374       GST_ELEMENT_ERROR (GST_ELEMENT (dec), LIBRARY, INIT, (NULL), (NULL));
1375       return GST_FLOW_ERROR;
1376     }
1377     GST_DEBUG_OBJECT (dec, "initialized (framed=%d)", dec->framed);
1378     dec->init = FALSE;
1379   } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT)) {
1380     /* Clear the adapter and the decoder */
1381     gst_adapter_clear (dec->adapter);
1382     FLAC__stream_decoder_flush (dec->decoder);
1383   }
1384
1385   if (dec->framed) {
1386     gint64 unused;
1387
1388     /* check if this is a flac audio frame (rather than a header or junk) */
1389     got_audio_frame = gst_flac_dec_scan_got_frame (dec, GST_BUFFER_DATA (buf),
1390         GST_BUFFER_SIZE (buf), &unused);
1391
1392     /* oggdemux will set granulepos in OFFSET_END instead of timestamp */
1393     if (G_LIKELY (got_audio_frame)) {
1394       /* old oggdemux for now */
1395       if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
1396         dec->cur_granulepos = GST_BUFFER_OFFSET_END (buf);
1397       } else {
1398         GstFormat dformat = GST_FORMAT_DEFAULT;
1399
1400         /* upstream (e.g. demuxer) presents us time,
1401          * convert to default samples */
1402         gst_flac_dec_convert_src (dec->srcpad, GST_FORMAT_TIME,
1403             GST_BUFFER_TIMESTAMP (buf), &dformat, &dec->segment.last_stop);
1404         dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1405       }
1406     }
1407   } else {
1408     dec->cur_granulepos = GST_BUFFER_OFFSET_NONE;
1409     got_audio_frame = TRUE;
1410   }
1411
1412   gst_adapter_push (dec->adapter, buf);
1413   buf = NULL;
1414
1415   dec->last_flow = GST_FLOW_OK;
1416
1417   if (!dec->framed) {
1418     if (G_UNLIKELY (!dec->got_headers)) {
1419       if (!gst_flac_dec_chain_parse_headers (dec)) {
1420         GST_LOG_OBJECT (dec, "don't have metadata blocks yet, need more data");
1421         goto out;
1422       }
1423       GST_INFO_OBJECT (dec, "have all metadata blocks now");
1424       dec->got_headers = TRUE;
1425     }
1426
1427     /* wait until we have at least 64kB because libflac's StreamDecoder
1428      * interface is a bit dumb it seems (if we don't have as much data as
1429      * it wants it will call our read callback repeatedly and the only
1430      * way to stop that is to error out or EOS, which will affect the
1431      * decoder state). And the decoder seems to always ask for MAX_BLOCK_SIZE
1432      * bytes rather than the max. block size from the header). Requiring
1433      * MAX_BLOCK_SIZE bytes here should make sure it always gets enough data
1434      * to decode at least one block */
1435     while (gst_adapter_available (dec->adapter) >= FLAC__MAX_BLOCK_SIZE &&
1436         dec->last_flow == GST_FLOW_OK) {
1437       GST_LOG_OBJECT (dec, "%u bytes available",
1438           gst_adapter_available (dec->adapter));
1439       if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1440         GST_DEBUG_OBJECT (dec, "process_single failed");
1441         break;
1442       }
1443
1444       if (FLAC__stream_decoder_get_state (dec->decoder) ==
1445           FLAC__STREAM_DECODER_ABORTED) {
1446         GST_WARNING_OBJECT (dec, "Read callback caused internal abort");
1447         dec->last_flow = GST_FLOW_ERROR;
1448         break;
1449       }
1450     }
1451   } else if (dec->framed && got_audio_frame) {
1452     /* framed - there should always be enough data to decode something */
1453     GST_LOG_OBJECT (dec, "%u bytes available",
1454         gst_adapter_available (dec->adapter));
1455     if (!FLAC__stream_decoder_process_single (dec->decoder)) {
1456       GST_DEBUG_OBJECT (dec, "process_single failed");
1457     }
1458   } else {
1459     GST_DEBUG_OBJECT (dec, "don't have all headers yet");
1460   }
1461
1462 out:
1463
1464   return dec->last_flow;
1465 }
1466
1467 static gboolean
1468 gst_flac_dec_convert_sink (GstFlacDec * dec, GstFormat src_format,
1469     gint64 src_value, GstFormat * dest_format, gint64 * dest_value)
1470 {
1471   gboolean res = TRUE;
1472
1473   if (dec->width == 0 || dec->channels == 0 || dec->sample_rate == 0) {
1474     /* no frame decoded yet */
1475     GST_DEBUG_OBJECT (dec, "cannot convert: not set up yet");
1476     return FALSE;
1477   }
1478
1479   switch (src_format) {
1480     case GST_FORMAT_BYTES:{
1481       res = FALSE;
1482       break;
1483     }
1484     case GST_FORMAT_DEFAULT:
1485       switch (*dest_format) {
1486         case GST_FORMAT_BYTES:
1487           res = FALSE;
1488           break;
1489         case GST_FORMAT_TIME:
1490           /* granulepos = sample */
1491           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1492               dec->sample_rate);
1493           break;
1494         default:
1495           res = FALSE;
1496           break;
1497       }
1498       break;
1499     case GST_FORMAT_TIME:
1500       switch (*dest_format) {
1501         case GST_FORMAT_BYTES:
1502           res = FALSE;
1503           break;
1504         case GST_FORMAT_DEFAULT:
1505           *dest_value = gst_util_uint64_scale_int (src_value,
1506               dec->sample_rate, GST_SECOND);
1507           break;
1508         default:
1509           res = FALSE;
1510           break;
1511       }
1512       break;
1513     default:
1514       res = FALSE;
1515       break;
1516   }
1517   return res;
1518 }
1519
1520 static const GstQueryType *
1521 gst_flac_dec_get_sink_query_types (GstPad * pad)
1522 {
1523   static const GstQueryType types[] = {
1524     GST_QUERY_CONVERT,
1525     0,
1526   };
1527
1528   return types;
1529 }
1530
1531 static gboolean
1532 gst_flac_dec_sink_query (GstPad * pad, GstQuery * query)
1533 {
1534   GstFlacDec *dec;
1535   gboolean res = FALSE;
1536
1537   dec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1538
1539   GST_LOG_OBJECT (dec, "%s query", GST_QUERY_TYPE_NAME (query));
1540
1541   switch (GST_QUERY_TYPE (query)) {
1542     case GST_QUERY_CONVERT:{
1543       GstFormat src_fmt, dest_fmt;
1544
1545       gint64 src_val, dest_val;
1546
1547       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1548
1549       res = gst_flac_dec_convert_sink (dec, src_fmt, src_val, &dest_fmt,
1550           &dest_val);
1551
1552       if (res) {
1553         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1554       }
1555       GST_LOG_OBJECT (dec, "conversion %s", (res) ? "ok" : "FAILED");
1556       break;
1557     }
1558
1559     default:{
1560       res = gst_pad_query_default (pad, query);
1561       break;
1562     }
1563   }
1564
1565   gst_object_unref (dec);
1566   return res;
1567 }
1568
1569 static gboolean
1570 gst_flac_dec_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
1571     GstFormat * dest_format, gint64 * dest_value)
1572 {
1573   GstFlacDec *flacdec = GST_FLAC_DEC (GST_PAD_PARENT (pad));
1574   gboolean res = TRUE;
1575   guint bytes_per_sample;
1576   guint scale = 1;
1577
1578   if (flacdec->width == 0 || flacdec->channels == 0 ||
1579       flacdec->sample_rate == 0) {
1580     /* no frame decoded yet */
1581     GST_DEBUG_OBJECT (flacdec, "cannot convert: not set up yet");
1582     return FALSE;
1583   }
1584
1585   bytes_per_sample = flacdec->channels * (flacdec->width / 8);
1586
1587   switch (src_format) {
1588     case GST_FORMAT_BYTES:{
1589       switch (*dest_format) {
1590         case GST_FORMAT_DEFAULT:
1591           *dest_value =
1592               gst_util_uint64_scale_int (src_value, 1, bytes_per_sample);
1593           break;
1594         case GST_FORMAT_TIME:
1595         {
1596           gint byterate = bytes_per_sample * flacdec->sample_rate;
1597
1598           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1599               byterate);
1600           break;
1601         }
1602         default:
1603           res = FALSE;
1604       }
1605       break;
1606     }
1607     case GST_FORMAT_DEFAULT:
1608       switch (*dest_format) {
1609         case GST_FORMAT_BYTES:
1610           *dest_value = src_value * bytes_per_sample;
1611           break;
1612         case GST_FORMAT_TIME:
1613           *dest_value = gst_util_uint64_scale_int (src_value, GST_SECOND,
1614               flacdec->sample_rate);
1615           break;
1616         default:
1617           res = FALSE;
1618       }
1619       break;
1620     case GST_FORMAT_TIME:
1621       switch (*dest_format) {
1622         case GST_FORMAT_BYTES:
1623           scale = bytes_per_sample;
1624         case GST_FORMAT_DEFAULT:
1625           *dest_value = gst_util_uint64_scale_int (src_value,
1626               scale * flacdec->sample_rate, GST_SECOND);
1627           break;
1628         default:
1629           res = FALSE;
1630       }
1631       break;
1632     default:
1633       res = FALSE;
1634   }
1635   return res;
1636 }
1637
1638 static const GstQueryType *
1639 gst_flac_dec_get_src_query_types (GstPad * pad)
1640 {
1641   static const GstQueryType types[] = {
1642     GST_QUERY_POSITION,
1643     GST_QUERY_DURATION,
1644     GST_QUERY_CONVERT,
1645     GST_QUERY_SEEKING,
1646     0,
1647   };
1648
1649   return types;
1650 }
1651
1652 static gboolean
1653 gst_flac_dec_src_query (GstPad * pad, GstQuery * query)
1654 {
1655   GstFlacDec *flacdec;
1656   gboolean res = TRUE;
1657   GstPad *peer;
1658
1659   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
1660   peer = gst_pad_get_peer (flacdec->sinkpad);
1661
1662   switch (GST_QUERY_TYPE (query)) {
1663     case GST_QUERY_POSITION:{
1664       GstFormat fmt;
1665       gint64 pos;
1666
1667       gst_query_parse_position (query, &fmt, NULL);
1668
1669       /* there might be a demuxer in front of us who can handle this */
1670       if (fmt == GST_FORMAT_TIME && (res = gst_pad_query (peer, query)))
1671         break;
1672
1673       if (fmt != GST_FORMAT_DEFAULT) {
1674         if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1675                 flacdec->segment.last_stop, &fmt, &pos)) {
1676           GST_DEBUG_OBJECT (flacdec, "failed to convert position into %s "
1677               "format", gst_format_get_name (fmt));
1678           res = FALSE;
1679           goto done;
1680         }
1681       } else {
1682         pos = flacdec->segment.last_stop;
1683       }
1684
1685       gst_query_set_position (query, fmt, pos);
1686
1687       GST_DEBUG_OBJECT (flacdec, "returning position %" G_GUINT64_FORMAT
1688           " (format: %s)", pos, gst_format_get_name (fmt));
1689
1690       res = TRUE;
1691       break;
1692     }
1693
1694     case GST_QUERY_DURATION:{
1695       GstFormat fmt;
1696       gint64 len;
1697
1698       gst_query_parse_duration (query, &fmt, NULL);
1699
1700       /* try any demuxers before us first */
1701       if (fmt == GST_FORMAT_TIME && peer && gst_pad_query (peer, query)) {
1702         gst_query_parse_duration (query, NULL, &len);
1703         GST_DEBUG_OBJECT (flacdec, "peer returned duration %" GST_TIME_FORMAT,
1704             GST_TIME_ARGS (len));
1705         res = TRUE;
1706         goto done;
1707       }
1708
1709       if (flacdec->segment.duration == 0 || flacdec->segment.duration == -1) {
1710         GST_DEBUG_OBJECT (flacdec, "duration not known yet");
1711         res = FALSE;
1712         goto done;
1713       }
1714
1715       /* convert total number of samples to request format */
1716       if (fmt != GST_FORMAT_DEFAULT) {
1717         if (!gst_flac_dec_convert_src (flacdec->srcpad, GST_FORMAT_DEFAULT,
1718                 flacdec->segment.duration, &fmt, &len)) {
1719           GST_DEBUG_OBJECT (flacdec, "failed to convert duration into %s "
1720               "format", gst_format_get_name (fmt));
1721           res = FALSE;
1722           goto done;
1723         }
1724       } else {
1725         len = flacdec->segment.duration;
1726       }
1727
1728       gst_query_set_duration (query, fmt, len);
1729
1730       GST_DEBUG_OBJECT (flacdec, "returning duration %" G_GUINT64_FORMAT
1731           " (format: %s)", len, gst_format_get_name (fmt));
1732
1733       res = TRUE;
1734       break;
1735     }
1736
1737     case GST_QUERY_CONVERT:{
1738       GstFormat src_fmt, dest_fmt;
1739       gint64 src_val, dest_val;
1740
1741       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, NULL);
1742
1743       res = gst_flac_dec_convert_src (pad, src_fmt, src_val, &dest_fmt,
1744           &dest_val);
1745
1746       if (res) {
1747         gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
1748       }
1749
1750       break;
1751     }
1752     case GST_QUERY_SEEKING:{
1753       GstFormat fmt;
1754       gboolean seekable = FALSE;
1755
1756       res = TRUE;
1757       /* If upstream can handle the query we're done */
1758       seekable = gst_pad_peer_query (flacdec->sinkpad, query);
1759       if (seekable)
1760         gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
1761       if (seekable)
1762         goto done;
1763
1764       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
1765       if ((fmt != GST_FORMAT_TIME && fmt != GST_FORMAT_DEFAULT) ||
1766           flacdec->streaming) {
1767         gst_query_set_seeking (query, fmt, FALSE, -1, -1);
1768       } else {
1769         gst_query_set_seeking (query, GST_FORMAT_TIME, TRUE, 0, -1);
1770       }
1771       break;
1772     }
1773
1774     default:{
1775       res = gst_pad_query_default (pad, query);
1776       break;
1777     }
1778   }
1779
1780 done:
1781
1782   if (peer)
1783     gst_object_unref (peer);
1784
1785   gst_object_unref (flacdec);
1786
1787   return res;
1788 }
1789
1790 static gboolean
1791 gst_flac_dec_handle_seek_event (GstFlacDec * flacdec, GstEvent * event)
1792 {
1793   FLAC__bool seek_ok;
1794   GstSeekFlags seek_flags;
1795   GstSeekType start_type;
1796   GstSeekType stop_type;
1797   GstSegment segment;
1798   GstFormat seek_format;
1799   gboolean only_update = FALSE;
1800   gboolean flush;
1801   gdouble rate;
1802   gint64 start, last_stop;
1803   gint64 stop;
1804
1805   if (flacdec->streaming) {
1806     GST_DEBUG_OBJECT (flacdec, "seeking in streaming mode not implemented yet");
1807     return FALSE;
1808   }
1809
1810   gst_event_parse_seek (event, &rate, &seek_format, &seek_flags, &start_type,
1811       &start, &stop_type, &stop);
1812
1813   if (seek_format != GST_FORMAT_DEFAULT && seek_format != GST_FORMAT_TIME) {
1814     GST_DEBUG_OBJECT (flacdec,
1815         "seeking is only supported in TIME or DEFAULT format");
1816     return FALSE;
1817   }
1818
1819   if (rate < 0.0) {
1820     GST_DEBUG_OBJECT (flacdec,
1821         "only forward playback supported, rate %f not allowed", rate);
1822     return FALSE;
1823   }
1824
1825   if (seek_format != GST_FORMAT_DEFAULT) {
1826     GstFormat target_format = GST_FORMAT_DEFAULT;
1827
1828     if (start_type != GST_SEEK_TYPE_NONE &&
1829         !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, start,
1830             &target_format, &start)) {
1831       GST_DEBUG_OBJECT (flacdec, "failed to convert start to DEFAULT format");
1832       return FALSE;
1833     }
1834
1835     if (stop_type != GST_SEEK_TYPE_NONE &&
1836         !gst_flac_dec_convert_src (flacdec->srcpad, seek_format, stop,
1837             &target_format, &stop)) {
1838       GST_DEBUG_OBJECT (flacdec, "failed to convert stop to DEFAULT format");
1839       return FALSE;
1840     }
1841   }
1842
1843   flush = ((seek_flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
1844
1845   if (flush) {
1846     /* flushing seek, clear the pipeline of stuff, we need a newsegment after
1847      * this. */
1848     GST_DEBUG_OBJECT (flacdec, "flushing");
1849     gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_start ());
1850     gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_start ());
1851   } else {
1852     /* non flushing seek, pause the task */
1853     GST_DEBUG_OBJECT (flacdec, "stopping task");
1854     gst_pad_stop_task (flacdec->sinkpad);
1855   }
1856
1857   /* acquire the stream lock, this either happens when the streaming thread
1858    * stopped because of the flush or when the task is paused after the loop
1859    * function finished an iteration, which can never happen when it's blocked
1860    * downstream in PAUSED, for example */
1861   GST_PAD_STREAM_LOCK (flacdec->sinkpad);
1862
1863   /* start seek with clear state to avoid seeking thread pushing segments/data.
1864    * Note current state may have some pending,
1865    * e.g. multi-sink seek leads to immediate subsequent seek events */
1866   if (flacdec->start_segment) {
1867     gst_event_unref (flacdec->start_segment);
1868     flacdec->start_segment = NULL;
1869   }
1870   gst_buffer_replace (&flacdec->pending, NULL);
1871   flacdec->pending_samples = 0;
1872
1873   /* save a segment copy until we know the seek worked. The idea is that
1874    * when the seek fails, we want to restore with what we were doing. */
1875   segment = flacdec->segment;
1876
1877   /* update the segment with the seek values, last_stop will contain the new
1878    * position we should seek to */
1879   gst_segment_set_seek (&flacdec->segment, rate, GST_FORMAT_DEFAULT,
1880       seek_flags, start_type, start, stop_type, stop, &only_update);
1881
1882   GST_DEBUG_OBJECT (flacdec,
1883       "configured segment: [%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT
1884       "] = [%" GST_TIME_FORMAT "-%" GST_TIME_FORMAT "]",
1885       flacdec->segment.start, flacdec->segment.stop,
1886       GST_TIME_ARGS (flacdec->segment.start * GST_SECOND /
1887           flacdec->sample_rate),
1888       GST_TIME_ARGS (flacdec->segment.stop * GST_SECOND /
1889           flacdec->sample_rate));
1890
1891   GST_DEBUG_OBJECT (flacdec, "performing seek to sample %" G_GINT64_FORMAT,
1892       flacdec->segment.last_stop);
1893
1894   /* flush sinkpad again because we need to pull and push buffers while doing
1895    * the seek */
1896   if (flush) {
1897     GST_DEBUG_OBJECT (flacdec, "flushing stop");
1898     gst_pad_push_event (flacdec->sinkpad, gst_event_new_flush_stop ());
1899     gst_pad_push_event (flacdec->srcpad, gst_event_new_flush_stop ());
1900   }
1901
1902   /* mark ourselves as seeking because the above lines will trigger some
1903    * callbacks that need to behave differently when seeking */
1904   flacdec->seeking = TRUE;
1905
1906   GST_LOG_OBJECT (flacdec, "calling seek_absolute");
1907   seek_ok = FLAC__stream_decoder_seek_absolute (flacdec->decoder,
1908       flacdec->segment.last_stop);
1909   GST_LOG_OBJECT (flacdec, "done with seek_absolute, seek_ok=%d", seek_ok);
1910
1911   flacdec->seeking = FALSE;
1912
1913   GST_DEBUG_OBJECT (flacdec, "performed seek to sample %" G_GINT64_FORMAT,
1914       flacdec->segment.last_stop);
1915
1916
1917   if (!seek_ok) {
1918     GST_WARNING_OBJECT (flacdec, "seek failed");
1919     /* seek failed, restore the segment and start streaming again with
1920      * the previous segment values */
1921     flacdec->segment = segment;
1922   } else if (!flush && flacdec->running) {
1923     /* we are running the current segment and doing a non-flushing seek, 
1924      * close the segment first based on the last_stop. */
1925     GST_DEBUG_OBJECT (flacdec, "closing running segment %" G_GINT64_FORMAT
1926         " to %" G_GINT64_FORMAT, segment.start, segment.last_stop);
1927
1928     /* convert the old segment values to time to close the old segment */
1929     start = gst_util_uint64_scale_int (segment.start, GST_SECOND,
1930         flacdec->sample_rate);
1931     last_stop =
1932         gst_util_uint64_scale_int (segment.last_stop, GST_SECOND,
1933         flacdec->sample_rate);
1934
1935     /* queue the segment for sending in the stream thread, start and time are
1936      * always the same. */
1937     if (flacdec->close_segment)
1938       gst_event_unref (flacdec->close_segment);
1939     flacdec->close_segment =
1940         gst_event_new_new_segment_full (TRUE,
1941         segment.rate, segment.applied_rate, GST_FORMAT_TIME,
1942         start, last_stop, start);
1943   }
1944
1945   if (seek_ok) {
1946     /* seek succeeded, flacdec->segment contains the new positions */
1947     GST_DEBUG_OBJECT (flacdec, "seek successful");
1948   }
1949
1950   /* convert the (new) segment values to time, we will need them to generate the
1951    * new segment events. */
1952   start = gst_util_uint64_scale_int (flacdec->segment.start, GST_SECOND,
1953       flacdec->sample_rate);
1954   last_stop = gst_util_uint64_scale_int (flacdec->segment.last_stop, GST_SECOND,
1955       flacdec->sample_rate);
1956
1957   /* for deriving a stop position for the playback segment from the seek
1958    * segment, we must take the duration when the stop is not set */
1959   if (flacdec->segment.stop != -1)
1960     stop = gst_util_uint64_scale_int (flacdec->segment.stop, GST_SECOND,
1961         flacdec->sample_rate);
1962   else
1963     stop = gst_util_uint64_scale_int (flacdec->segment.duration, GST_SECOND,
1964         flacdec->sample_rate);
1965
1966   /* notify start of new segment when we were asked to do so. */
1967   if (flacdec->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1968     /* last_stop contains the position we start from */
1969     gst_element_post_message (GST_ELEMENT (flacdec),
1970         gst_message_new_segment_start (GST_OBJECT (flacdec),
1971             GST_FORMAT_TIME, last_stop));
1972   }
1973
1974   /* if the seek was ok or (when it failed) we are flushing, we need to send out
1975    * a new segment. If we did not flush and the seek failed, we simply do
1976    * nothing here and continue where we were. */
1977   if (seek_ok || flush) {
1978     GST_DEBUG_OBJECT (flacdec, "Creating newsegment from %" GST_TIME_FORMAT
1979         " to %" GST_TIME_FORMAT, GST_TIME_ARGS (last_stop),
1980         GST_TIME_ARGS (stop));
1981     /* now replace the old segment so that we send it in the stream thread the
1982      * next time it is scheduled. */
1983     if (flacdec->start_segment)
1984       gst_event_unref (flacdec->start_segment);
1985     flacdec->start_segment =
1986         gst_event_new_new_segment_full (FALSE,
1987         flacdec->segment.rate, flacdec->segment.applied_rate, GST_FORMAT_TIME,
1988         last_stop, stop, last_stop);
1989   }
1990
1991   /* we'll generate a discont on the next buffer */
1992   flacdec->discont = TRUE;
1993   /* the task is running again now */
1994   flacdec->running = TRUE;
1995   gst_pad_start_task (flacdec->sinkpad,
1996       (GstTaskFunction) gst_flac_dec_loop, flacdec->sinkpad);
1997
1998   GST_PAD_STREAM_UNLOCK (flacdec->sinkpad);
1999
2000   return seek_ok;
2001 }
2002
2003 static gboolean
2004 gst_flac_dec_src_event (GstPad * pad, GstEvent * event)
2005 {
2006   gboolean res = TRUE;
2007   GstFlacDec *flacdec;
2008
2009   flacdec = GST_FLAC_DEC (gst_pad_get_parent (pad));
2010
2011   switch (GST_EVENT_TYPE (event)) {
2012     case GST_EVENT_SEEK:{
2013       GST_DEBUG_OBJECT (flacdec, "received seek event %p", event);
2014       /* first, see if we're before a demuxer that
2015        * might handle the seek for us */
2016       gst_event_ref (event);
2017       res = gst_pad_event_default (pad, event);
2018       /* if not, try to handle it ourselves */
2019       if (!res) {
2020         GST_DEBUG_OBJECT (flacdec, "default failed, handling ourselves");
2021         res = gst_flac_dec_handle_seek_event (flacdec, event);
2022       }
2023       gst_event_unref (event);
2024       break;
2025     }
2026     default:
2027       res = gst_pad_event_default (pad, event);
2028       break;
2029   }
2030
2031   gst_object_unref (flacdec);
2032
2033   return res;
2034 }
2035
2036 static gboolean
2037 gst_flac_dec_sink_activate (GstPad * sinkpad)
2038 {
2039   if (gst_pad_check_pull_range (sinkpad))
2040     return gst_pad_activate_pull (sinkpad, TRUE);
2041
2042   return gst_pad_activate_push (sinkpad, TRUE);
2043 }
2044
2045 static gboolean
2046 gst_flac_dec_sink_activate_push (GstPad * sinkpad, gboolean active)
2047 {
2048   GstFlacDec *dec = GST_FLAC_DEC (GST_OBJECT_PARENT (sinkpad));
2049
2050   if (active) {
2051     gst_flac_dec_setup_decoder (dec);
2052     dec->streaming = TRUE;
2053     dec->got_headers = FALSE;
2054   }
2055   return TRUE;
2056 }
2057
2058 static gboolean
2059 gst_flac_dec_sink_activate_pull (GstPad * sinkpad, gboolean active)
2060 {
2061   gboolean res;
2062
2063   if (active) {
2064     GstFlacDec *flacdec;
2065
2066     flacdec = GST_FLAC_DEC (GST_PAD_PARENT (sinkpad));
2067
2068     flacdec->offset = 0;
2069     gst_flac_dec_setup_decoder (flacdec);
2070     flacdec->running = TRUE;
2071     flacdec->streaming = FALSE;
2072
2073     res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flac_dec_loop,
2074         sinkpad);
2075   } else {
2076     res = gst_pad_stop_task (sinkpad);
2077   }
2078   return res;
2079 }
2080
2081 static GstStateChangeReturn
2082 gst_flac_dec_change_state (GstElement * element, GstStateChange transition)
2083 {
2084   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2085   GstFlacDec *flacdec = GST_FLAC_DEC (element);
2086
2087   switch (transition) {
2088     case GST_STATE_CHANGE_READY_TO_PAUSED:
2089       flacdec->seeking = FALSE;
2090       flacdec->channels = 0;
2091       flacdec->depth = 0;
2092       flacdec->width = 0;
2093       flacdec->sample_rate = 0;
2094       gst_segment_init (&flacdec->segment, GST_FORMAT_DEFAULT);
2095       break;
2096     default:
2097       break;
2098   }
2099
2100   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2101   if (ret == GST_STATE_CHANGE_FAILURE)
2102     return ret;
2103
2104   switch (transition) {
2105     case GST_STATE_CHANGE_PAUSED_TO_READY:
2106       gst_segment_init (&flacdec->segment, GST_FORMAT_UNDEFINED);
2107       gst_flac_dec_reset_decoders (flacdec);
2108       break;
2109     default:
2110       break;
2111   }
2112
2113   return ret;
2114 }