flacparse: factor out buffer time and offset resetting
[platform/upstream/gst-plugins-good.git] / gst / audioparsers / gstflacparse.c
1 /* GStreamer
2  *
3  * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4  * Copyright (C) 2009 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
5  * Copyright (C) 2009 Nokia Corporation. All rights reserved.
6  *   Contact: Stefan Kost <stefan.kost@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 /**
25  * SECTION:element-flacparse
26  * @see_also: flacdec, oggdemux, vorbisparse
27  *
28  * The flacparse element will parse the header packets of the FLAC
29  * stream and put them as the streamheader in the caps. This is used in the
30  * multifdsink case where you want to stream live FLAC streams to multiple
31  * clients, each client has to receive the streamheaders first before they can
32  * consume the FLAC packets.
33  *
34  * This element also makes sure that the buffers that it pushes out are properly
35  * timestamped and that their offset and offset_end are set. The buffers that
36  * flacparse outputs have all of the metadata that oggmux expects to receive,
37  * which allows you to (for example) remux an ogg/flac or convert a native FLAC
38  * format file to an ogg bitstream.
39  *
40  * <refsect2>
41  * <title>Example pipelines</title>
42  * |[
43  * gst-launch-1.0 -v filesrc location=sine.flac ! flacparse ! identity \
44  *            ! oggmux ! filesink location=sine-remuxed.ogg
45  * ]| This pipeline converts a native FLAC format file to an ogg bitstream.
46  * It also illustrates that the streamheader is set in the caps, and that each
47  * buffer has the timestamp, duration, offset, and offset_end set.
48  * </refsect2>
49  *
50  */
51
52 #ifdef HAVE_CONFIG_H
53 #include "config.h"
54 #endif
55
56 #include "gstflacparse.h"
57
58 #include <string.h>
59 #include <gst/tag/tag.h>
60 #include <gst/audio/audio.h>
61 #include <gst/base/base.h>
62 #include <gst/pbutils/pbutils.h>
63
64 GST_DEBUG_CATEGORY_STATIC (flacparse_debug);
65 #define GST_CAT_DEFAULT flacparse_debug
66
67 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
68 static const guint8 crc8_table[256] = {
69   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
70   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
71   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
72   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
73   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
74   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
75   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
76   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
77   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
78   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
79   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
80   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
81   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
82   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
83   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
84   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
85   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
86   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
87   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
88   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
89   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
90   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
91   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
92   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
93   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
94   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
95   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
96   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
97   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
98   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
99   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
100   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
101 };
102
103 static guint8
104 gst_flac_calculate_crc8 (const guint8 * data, guint length)
105 {
106   guint8 crc = 0;
107
108   while (length--) {
109     crc = crc8_table[crc ^ *data];
110     ++data;
111   }
112
113   return crc;
114 }
115
116 /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
117 static const guint16 crc16_table[256] = {
118   0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
119   0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
120   0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
121   0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
122   0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
123   0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
124   0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
125   0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
126   0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
127   0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
128   0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
129   0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
130   0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
131   0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
132   0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
133   0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
134   0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
135   0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
136   0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
137   0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
138   0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
139   0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
140   0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
141   0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
142   0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
143   0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
144   0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
145   0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
146   0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
147   0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
148   0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
149   0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
150 };
151
152 static guint16
153 gst_flac_calculate_crc16 (const guint8 * data, guint length)
154 {
155   guint16 crc = 0;
156
157   while (length--) {
158     crc = ((crc << 8) ^ crc16_table[(crc >> 8) ^ *data]) & 0xffff;
159     data++;
160   }
161
162   return crc;
163 }
164
165 enum
166 {
167   PROP_0,
168   PROP_CHECK_FRAME_CHECKSUMS
169 };
170
171 #define DEFAULT_CHECK_FRAME_CHECKSUMS FALSE
172
173 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
174     GST_PAD_SRC,
175     GST_PAD_ALWAYS,
176     GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) true, "
177         "channels = (int) [ 1, 8 ], " "rate = (int) [ 1, 655350 ]")
178     );
179
180 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
181     GST_PAD_SINK,
182     GST_PAD_ALWAYS,
183     GST_STATIC_CAPS ("audio/x-flac")
184     );
185
186 static GstBuffer *gst_flac_parse_generate_vorbiscomment (GstFlacParse *
187     flacparse);
188
189 static inline void gst_flac_parse_reset_buffer_time_and_offset (GstBuffer *
190     buffer);
191 static void gst_flac_parse_reset (GstFlacParse * parser);
192 static gboolean gst_flac_parse_handle_block_type (GstFlacParse * flacparse,
193     guint type, GstBuffer * sbuffer);
194 static void gst_flac_parse_finalize (GObject * object);
195 static void gst_flac_parse_set_property (GObject * object, guint prop_id,
196     const GValue * value, GParamSpec * pspec);
197 static void gst_flac_parse_get_property (GObject * object, guint prop_id,
198     GValue * value, GParamSpec * pspec);
199
200 static gboolean gst_flac_parse_start (GstBaseParse * parse);
201 static gboolean gst_flac_parse_stop (GstBaseParse * parse);
202 static GstFlowReturn gst_flac_parse_handle_frame (GstBaseParse * parse,
203     GstBaseParseFrame * frame, gint * skipsize);
204 static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
205     GstBaseParseFrame * frame, gint size);
206 static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
207     GstBaseParseFrame * frame);
208 static gboolean gst_flac_parse_convert (GstBaseParse * parse,
209     GstFormat src_format, gint64 src_value, GstFormat dest_format,
210     gint64 * dest_value);
211 static gboolean gst_flac_parse_src_event (GstBaseParse * parse,
212     GstEvent * event);
213 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
214     GstCaps * filter);
215
216 #define gst_flac_parse_parent_class parent_class
217 G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);
218
219 static void
220 gst_flac_parse_class_init (GstFlacParseClass * klass)
221 {
222   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
223   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
224   GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
225
226   GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
227       "Flac parser element");
228
229   gobject_class->finalize = gst_flac_parse_finalize;
230   gobject_class->set_property = gst_flac_parse_set_property;
231   gobject_class->get_property = gst_flac_parse_get_property;
232
233   g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
234       g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
235           "Check the overall checksums of every frame",
236           DEFAULT_CHECK_FRAME_CHECKSUMS,
237           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
238
239   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
240   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
241   baseparse_class->handle_frame =
242       GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
243   baseparse_class->pre_push_frame =
244       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
245   baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
246   baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
247   baseparse_class->get_sink_caps =
248       GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
249
250   gst_element_class_add_pad_template (element_class,
251       gst_static_pad_template_get (&src_factory));
252   gst_element_class_add_pad_template (element_class,
253       gst_static_pad_template_get (&sink_factory));
254
255   gst_element_class_set_static_metadata (element_class, "FLAC audio parser",
256       "Codec/Parser/Audio",
257       "Parses audio with the FLAC lossless audio codec",
258       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
259 }
260
261 static void
262 gst_flac_parse_init (GstFlacParse * flacparse)
263 {
264   flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
265   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (flacparse));
266   GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (flacparse));
267 }
268
269 static void
270 gst_flac_parse_set_property (GObject * object, guint prop_id,
271     const GValue * value, GParamSpec * pspec)
272 {
273   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
274
275   switch (prop_id) {
276     case PROP_CHECK_FRAME_CHECKSUMS:
277       flacparse->check_frame_checksums = g_value_get_boolean (value);
278       break;
279     default:
280       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
281       break;
282   }
283 }
284
285 static void
286 gst_flac_parse_get_property (GObject * object, guint prop_id,
287     GValue * value, GParamSpec * pspec)
288 {
289   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
290
291   switch (prop_id) {
292     case PROP_CHECK_FRAME_CHECKSUMS:
293       g_value_set_boolean (value, flacparse->check_frame_checksums);
294       break;
295     default:
296       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
297       break;
298   }
299 }
300
301 static void
302 gst_flac_parse_reset (GstFlacParse * parser)
303 {
304   if (parser->tags) {
305     gst_tag_list_unref (parser->tags);
306     parser->tags = NULL;
307   }
308   if (parser->toc) {
309     gst_toc_unref (parser->toc);
310     parser->toc = NULL;
311   }
312   if (parser->seektable) {
313     gst_buffer_unref (parser->seektable);
314     parser->seektable = NULL;
315   }
316
317   g_list_foreach (parser->headers, (GFunc) gst_mini_object_unref, NULL);
318   g_list_free (parser->headers);
319   parser->headers = NULL;
320 }
321
322 static void
323 gst_flac_parse_finalize (GObject * object)
324 {
325   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
326
327   gst_flac_parse_reset (flacparse);
328   G_OBJECT_CLASS (parent_class)->finalize (object);
329 }
330
331 static gboolean
332 gst_flac_parse_start (GstBaseParse * parse)
333 {
334   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
335
336   flacparse->state = GST_FLAC_PARSE_STATE_INIT;
337   flacparse->min_blocksize = 0;
338   flacparse->max_blocksize = 0;
339   flacparse->min_framesize = 0;
340   flacparse->max_framesize = 0;
341
342   flacparse->upstream_length = -1;
343
344   flacparse->samplerate = 0;
345   flacparse->channels = 0;
346   flacparse->bps = 0;
347   flacparse->total_samples = 0;
348
349   flacparse->offset = GST_CLOCK_TIME_NONE;
350   flacparse->blocking_strategy = 0;
351   flacparse->block_size = 0;
352   flacparse->sample_number = 0;
353   flacparse->strategy_checked = FALSE;
354
355   flacparse->sent_codec_tag = FALSE;
356
357   /* "fLaC" marker */
358   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
359
360   /* inform baseclass we can come up with ts, based on counters in packets */
361   gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
362   gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);
363
364   return TRUE;
365 }
366
367 static gboolean
368 gst_flac_parse_stop (GstBaseParse * parse)
369 {
370   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
371
372   gst_flac_parse_reset (flacparse);
373   return TRUE;
374 }
375
376 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
377
378 static const guint16 blocksize_table[16] = {
379   0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
380   256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
381   256 << 7,
382 };
383
384 static const guint32 sample_rate_table[16] = {
385   0,
386   88200, 176400, 192000,
387   8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
388   0, 0, 0, 0,
389 };
390
391 typedef enum
392 {
393   FRAME_HEADER_VALID,
394   FRAME_HEADER_INVALID,
395   FRAME_HEADER_MORE_DATA
396 } FrameHeaderCheckReturn;
397
398 static FrameHeaderCheckReturn
399 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
400     const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
401     gboolean * suspect)
402 {
403   GstBitReader reader = GST_BIT_READER_INIT (data, size);
404   guint8 blocking_strategy;
405   guint16 block_size;
406   guint32 samplerate = 0;
407   guint64 sample_number;
408   guint8 channels, bps;
409   guint8 tmp = 0;
410   guint8 actual_crc, expected_crc = 0;
411
412   /* Skip 14 bit sync code */
413   gst_bit_reader_skip_unchecked (&reader, 14);
414
415   /* Must be 0 */
416   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
417     goto error;
418
419   /* 0 == fixed block size, 1 == variable block size */
420   blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
421   if (flacparse->force_variable_block_size)
422     blocking_strategy = 1;
423
424   /* block size index, calculation of the real blocksize below */
425   block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
426   if (block_size == 0)
427     goto error;
428
429   /* sample rate index, calculation of the real samplerate below */
430   samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
431   if (samplerate == 0x0f)
432     goto error;
433
434   /* channel assignment */
435   channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
436   if (channels < 8) {
437     channels++;
438   } else if (channels <= 10) {
439     channels = 2;
440   } else if (channels > 10) {
441     goto error;
442   }
443   if (flacparse->channels && flacparse->channels != channels)
444     goto error;
445
446   /* bits per sample */
447   bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
448   if (bps == 0x03 || bps == 0x07) {
449     goto error;
450   } else if (bps == 0 && flacparse->bps == 0) {
451     goto need_streaminfo;
452   }
453   bps = sample_size_table[bps];
454   if (flacparse->bps && bps != flacparse->bps)
455     goto error;
456
457   /* reserved, must be 0 */
458   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
459     goto error;
460
461   /* read "utf8" encoded sample/frame number */
462   {
463     gint len = 0;
464
465     len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
466
467     /* This is slightly faster than a loop */
468     if (!(len & 0x80)) {
469       sample_number = len;
470       len = 0;
471     } else if ((len & 0xc0) && !(len & 0x20)) {
472       sample_number = len & 0x1f;
473       len = 1;
474     } else if ((len & 0xe0) && !(len & 0x10)) {
475       sample_number = len & 0x0f;
476       len = 2;
477     } else if ((len & 0xf0) && !(len & 0x08)) {
478       sample_number = len & 0x07;
479       len = 3;
480     } else if ((len & 0xf8) && !(len & 0x04)) {
481       sample_number = len & 0x03;
482       len = 4;
483     } else if ((len & 0xfc) && !(len & 0x02)) {
484       sample_number = len & 0x01;
485       len = 5;
486     } else if ((len & 0xfe) && !(len & 0x01)) {
487       sample_number = len & 0x0;
488       len = 6;
489     } else {
490       goto error;
491     }
492
493     if ((blocking_strategy == 0 && len > 5) ||
494         (blocking_strategy == 1 && len > 6))
495       goto error;
496
497     while (len > 0) {
498       if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
499         goto need_more_data;
500
501       if ((tmp & 0xc0) != 0x80)
502         goto error;
503
504       sample_number <<= 6;
505       sample_number |= (tmp & 0x3f);
506       len--;
507     }
508   }
509
510   /* calculate real blocksize from the blocksize index */
511   if (block_size == 6) {
512     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
513       goto need_more_data;
514     block_size++;
515   } else if (block_size == 7) {
516     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
517       goto need_more_data;
518     block_size++;
519   } else {
520     block_size = blocksize_table[block_size];
521   }
522
523   /* calculate the real samplerate from the samplerate index */
524   if (samplerate == 0 && flacparse->samplerate == 0) {
525     goto need_streaminfo;
526   } else if (samplerate < 12) {
527     samplerate = sample_rate_table[samplerate];
528   } else if (samplerate == 12) {
529     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
530       goto need_more_data;
531     samplerate *= 1000;
532   } else if (samplerate == 13) {
533     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
534       goto need_more_data;
535   } else if (samplerate == 14) {
536     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
537       goto need_more_data;
538     samplerate *= 10;
539   }
540
541   if (flacparse->samplerate && flacparse->samplerate != samplerate)
542     goto error;
543
544   /* check crc-8 for the header */
545   if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
546     goto need_more_data;
547
548   actual_crc =
549       gst_flac_calculate_crc8 (data,
550       (gst_bit_reader_get_pos (&reader) / 8) - 1);
551   if (actual_crc != expected_crc)
552     goto error;
553
554   /* Sanity check sample number against blocking strategy, as it seems
555      some files claim fixed block size but supply sample numbers,
556      rather than block numbers. */
557   if (blocking_strategy == 0 && flacparse->block_size != 0) {
558     if (!flacparse->strategy_checked) {
559       if (block_size == sample_number) {
560         GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
561             "but seems to be lying: assuming variable block size");
562         flacparse->force_variable_block_size = TRUE;
563         blocking_strategy = 1;
564       }
565       flacparse->strategy_checked = TRUE;
566     }
567   }
568
569   /* documentation says:
570    * The "blocking strategy" bit must be the same throughout the entire stream. */
571   if (flacparse->blocking_strategy != blocking_strategy) {
572     if (flacparse->block_size != 0) {
573       GST_WARNING_OBJECT (flacparse, "blocking strategy is not constant");
574       if (suspect)
575         *suspect = TRUE;
576     }
577   }
578
579   /* 
580      The FLAC format documentation says:
581      The "blocking strategy" bit determines how to calculate the sample number
582      of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
583      frame header encodes the frame number as above, and the frame's starting
584      sample number will be the frame number times the blocksize. If it is 1
585      (variable-blocksize), the frame header encodes the frame's starting
586      sample number itself. (In the case of a fixed-blocksize stream, only the
587      last block may be shorter than the stream blocksize; its starting sample
588      number will be calculated as the frame number times the previous frame's
589      blocksize, or zero if it is the first frame). 
590
591      Therefore, when in fixed block size mode, we only update the block size
592      the first time, then reuse that block size for subsequent calls.
593      This will also fix a timestamp problem with the last block's timestamp
594      being miscalculated by scaling the block number by a "wrong" block size.
595    */
596   if (blocking_strategy == 0) {
597     if (flacparse->block_size != 0) {
598       /* after first block */
599       if (flacparse->block_size != block_size) {
600         /* TODO: can we know we're on the last frame, to avoid warning ? */
601         GST_WARNING_OBJECT (flacparse, "Block size is not constant");
602         block_size = flacparse->block_size;
603         if (suspect)
604           *suspect = TRUE;
605       }
606     }
607   }
608
609   if (set) {
610     flacparse->block_size = block_size;
611     if (!flacparse->samplerate)
612       flacparse->samplerate = samplerate;
613     if (!flacparse->bps)
614       flacparse->bps = bps;
615     if (!flacparse->blocking_strategy)
616       flacparse->blocking_strategy = blocking_strategy;
617     if (!flacparse->channels)
618       flacparse->channels = channels;
619     if (!flacparse->sample_number)
620       flacparse->sample_number = sample_number;
621
622     GST_DEBUG_OBJECT (flacparse,
623         "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
624         "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
625         flacparse->block_size, flacparse->sample_number);
626   }
627
628   if (block_size_ret)
629     *block_size_ret = block_size;
630
631   return FRAME_HEADER_VALID;
632
633 need_streaminfo:
634   GST_ERROR_OBJECT (flacparse, "Need STREAMINFO metadata. Bits per sample "
635       "or sample rate not in frame header");
636 error:
637   return FRAME_HEADER_INVALID;
638
639 need_more_data:
640   return FRAME_HEADER_MORE_DATA;
641 }
642
643 static gboolean
644 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
645     GstBaseParseFrame * frame, guint * ret)
646 {
647   GstBuffer *buffer;
648   GstMapInfo map;
649   guint max, remaining;
650   guint i, search_start, search_end;
651   FrameHeaderCheckReturn header_ret;
652   guint16 block_size;
653   gboolean suspect_start = FALSE, suspect_end = FALSE;
654   gboolean result = FALSE;
655
656   buffer = frame->buffer;
657   gst_buffer_map (buffer, &map, GST_MAP_READ);
658
659   if (map.size < flacparse->min_framesize)
660     goto need_more;
661
662   header_ret =
663       gst_flac_parse_frame_header_is_valid (flacparse, map.data, map.size, TRUE,
664       &block_size, &suspect_start);
665   if (header_ret == FRAME_HEADER_INVALID) {
666     *ret = 0;
667     goto cleanup;
668   }
669   if (header_ret == FRAME_HEADER_MORE_DATA)
670     goto need_more;
671
672   /* mind unknown framesize */
673   search_start = MAX (2, flacparse->min_framesize);
674   if (flacparse->max_framesize)
675     search_end = MIN (map.size, flacparse->max_framesize + 9 + 2);
676   else
677     search_end = map.size;
678   search_end -= 2;
679
680   remaining = map.size;
681
682   for (i = search_start; i < search_end; i++, remaining--) {
683
684     if ((GST_READ_UINT16_BE (map.data + i) & 0xfffe) != 0xfff8)
685       continue;
686
687     GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
688     suspect_end = FALSE;
689     header_ret =
690         gst_flac_parse_frame_header_is_valid (flacparse, map.data + i,
691         remaining, FALSE, NULL, &suspect_end);
692     if (header_ret == FRAME_HEADER_VALID) {
693       if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
694         guint16 actual_crc = gst_flac_calculate_crc16 (map.data, i - 2);
695         guint16 expected_crc = GST_READ_UINT16_BE (map.data + i - 2);
696
697         GST_LOG_OBJECT (flacparse,
698             "checking checksum, frame suspect (%d, %d)",
699             suspect_start, suspect_end);
700         if (actual_crc != expected_crc) {
701           GST_DEBUG_OBJECT (flacparse, "checksum did not match");
702           continue;
703         }
704       }
705       *ret = i;
706       flacparse->block_size = block_size;
707       result = TRUE;
708       goto cleanup;
709     } else if (header_ret == FRAME_HEADER_MORE_DATA) {
710       goto need_more;
711     }
712   }
713
714   /* For the last frame output everything to the end */
715   if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
716     if (flacparse->check_frame_checksums) {
717       guint16 actual_crc = gst_flac_calculate_crc16 (map.data, map.size - 2);
718       guint16 expected_crc = GST_READ_UINT16_BE (map.data + map.size - 2);
719
720       if (actual_crc == expected_crc) {
721         *ret = map.size;
722         flacparse->block_size = block_size;
723         result = TRUE;
724         goto cleanup;
725       }
726     } else {
727       *ret = map.size;
728       flacparse->block_size = block_size;
729       result = TRUE;
730       goto cleanup;
731     }
732   }
733
734   /* so we searched to expected end and found nothing,
735    * give up on this frame (start) */
736   if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
737     GST_LOG_OBJECT (flacparse,
738         "could not determine valid frame end, discarding frame (start)");
739     *ret = 1;
740     return FALSE;
741   }
742
743 need_more:
744   max = flacparse->max_framesize + 16;
745   if (max == 16)
746     max = 1 << 24;
747   *ret = MIN (map.size + 4096, max);
748   result = TRUE;
749
750 cleanup:
751   gst_buffer_unmap (buffer, &map);
752   return result;
753 }
754
755 static GstFlowReturn
756 gst_flac_parse_handle_frame (GstBaseParse * parse,
757     GstBaseParseFrame * frame, gint * skipsize)
758 {
759   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
760   GstBuffer *buffer = frame->buffer;
761   GstMapInfo map;
762   gboolean result = TRUE;
763   GstFlowReturn ret = GST_FLOW_OK;
764   guint framesize = 0;
765
766   gst_buffer_map (buffer, &map, GST_MAP_READ);
767
768   *skipsize = 1;
769
770   if (G_UNLIKELY (map.size < 4)) {
771     result = FALSE;
772     goto cleanup;
773   }
774
775   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
776     if (memcmp (map.data, "fLaC", 4) == 0) {
777       GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
778       framesize = 4;
779       goto cleanup;
780     }
781     if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
782       GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
783       /* Minimal size of a frame header */
784       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
785       flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
786       *skipsize = 0;
787       result = FALSE;
788       goto cleanup;
789     }
790     GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
791     result = FALSE;
792     goto cleanup;
793   }
794
795   if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
796     guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
797
798     GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
799     framesize = size;
800     goto cleanup;
801   }
802
803   if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
804     gboolean ret;
805     guint next;
806
807     flacparse->offset = GST_BUFFER_OFFSET (buffer);
808     flacparse->blocking_strategy = 0;
809     flacparse->sample_number = 0;
810
811     GST_DEBUG_OBJECT (flacparse, "Found sync code");
812     ret = gst_flac_parse_frame_is_valid (flacparse, frame, &next);
813     if (ret) {
814       framesize = next;
815       goto cleanup;
816     } else {
817       /* If we're at EOS and the frame was not valid, drop it! */
818       if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
819         GST_WARNING_OBJECT (flacparse, "EOS");
820         result = FALSE;
821         goto cleanup;
822       }
823
824       if (next == 0) {
825       } else if (next > map.size) {
826         GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
827         *skipsize = 0;
828         gst_base_parse_set_min_frame_size (parse, next);
829         result = FALSE;
830         goto cleanup;
831       } else {
832         GST_ERROR_OBJECT (flacparse,
833             "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
834         result = FALSE;
835         goto cleanup;
836       }
837     }
838   } else {
839     GstByteReader reader;
840     gint off;
841
842     gst_byte_reader_init (&reader, map.data, map.size);
843     off =
844         gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
845         0, map.size);
846
847     if (off > 0) {
848       GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
849       *skipsize = off;
850       result = FALSE;
851       goto cleanup;
852     } else {
853       GST_DEBUG_OBJECT (flacparse, "Sync code not found");
854       *skipsize = map.size - 3;
855       result = FALSE;
856       goto cleanup;
857     }
858   }
859
860   result = FALSE;
861
862 cleanup:
863   gst_buffer_unmap (buffer, &map);
864
865   if (result)
866     *skipsize = 0;
867
868   if (result && framesize <= map.size) {
869     ret = gst_flac_parse_parse_frame (parse, frame, framesize);
870     if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
871       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
872       ret = GST_FLOW_OK;
873     }
874     if (ret == GST_FLOW_OK)
875       ret = gst_base_parse_finish_frame (parse, frame, framesize);
876   }
877
878   return ret;
879 }
880
881 static gboolean
882 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
883 {
884   GstBitReader reader;
885   GstMapInfo map;
886
887   gst_buffer_map (buffer, &map, GST_MAP_READ);
888   gst_bit_reader_init (&reader, map.data, map.size);
889
890   if (map.size != 4 + 34) {
891     GST_ERROR_OBJECT (flacparse,
892         "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
893     goto failure;
894   }
895
896   /* Skip metadata block header */
897   if (!gst_bit_reader_skip (&reader, 32))
898     goto error;
899
900   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
901     goto error;
902   if (flacparse->min_blocksize < 16) {
903     GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
904         flacparse->min_blocksize);
905   }
906
907   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
908     goto error;
909   if (flacparse->max_blocksize < 16) {
910     GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
911         flacparse->max_blocksize);
912   }
913
914   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
915     goto error;
916   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
917     goto error;
918
919   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
920     goto error;
921   if (flacparse->samplerate == 0) {
922     GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
923     goto failure;
924   }
925
926   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
927     goto error;
928   flacparse->channels++;
929   if (flacparse->channels > 8) {
930     GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
931         flacparse->channels);
932     goto failure;
933   }
934
935   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
936     goto error;
937   flacparse->bps++;
938
939   if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
940     goto error;
941   if (flacparse->total_samples) {
942     gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
943         GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
944   }
945
946   gst_buffer_unmap (buffer, &map);
947
948   GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
949       "\tmin/max blocksize: %u/%u,\n"
950       "\tmin/max framesize: %u/%u,\n"
951       "\tsamplerate: %u,\n"
952       "\tchannels: %u,\n"
953       "\tbits per sample: %u,\n"
954       "\ttotal samples: %" G_GUINT64_FORMAT,
955       flacparse->min_blocksize, flacparse->max_blocksize,
956       flacparse->min_framesize, flacparse->max_framesize,
957       flacparse->samplerate,
958       flacparse->channels, flacparse->bps, flacparse->total_samples);
959
960   return TRUE;
961
962 error:
963   GST_ERROR_OBJECT (flacparse, "Failed to read data");
964 failure:
965   gst_buffer_unmap (buffer, &map);
966   return FALSE;
967 }
968
969 static gboolean
970 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
971     GstBuffer * buffer)
972 {
973   GstTagList *tags;
974   GstMapInfo map;
975
976   gst_buffer_map (buffer, &map, GST_MAP_READ);
977
978   tags =
979       gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
980   gst_buffer_unmap (buffer, &map);
981
982   if (tags == NULL) {
983     GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
984   } else if (gst_tag_list_is_empty (tags)) {
985     gst_tag_list_unref (tags);
986   } else if (flacparse->tags == NULL) {
987     flacparse->tags = tags;
988   } else {
989     gst_tag_list_insert (flacparse->tags, tags, GST_TAG_MERGE_APPEND);
990     gst_tag_list_unref (tags);
991   }
992
993   return TRUE;
994 }
995
996 static gboolean
997 gst_flac_parse_handle_cuesheet (GstFlacParse * flacparse, GstBuffer * buffer)
998 {
999   GstByteReader reader;
1000   GstMapInfo map;
1001   guint i, j;
1002   guint8 n_tracks, track_num, index;
1003   guint64 offset;
1004   gint64 start, stop;
1005   gchar *id;
1006   gchar isrc[13];
1007   GstTagList *tags;
1008   GstToc *toc;
1009   GstTocEntry *cur_entry = NULL, *prev_entry = NULL;
1010
1011   gst_buffer_map (buffer, &map, GST_MAP_READ);
1012   gst_byte_reader_init (&reader, map.data, map.size);
1013
1014   toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1015
1016   /* skip 4 bytes METADATA_BLOCK_HEADER */
1017   /* http://flac.sourceforge.net/format.html#metadata_block_header */
1018   if (!gst_byte_reader_skip (&reader, 4))
1019     goto error;
1020
1021   /* skip 395 bytes from METADATA_BLOCK_CUESHEET */
1022   /* http://flac.sourceforge.net/format.html#metadata_block_cuesheet */
1023   if (!gst_byte_reader_skip (&reader, 395))
1024     goto error;
1025
1026   if (!gst_byte_reader_get_uint8 (&reader, &n_tracks))
1027     goto error;
1028
1029   /* CUESHEET_TRACK */
1030   /* http://flac.sourceforge.net/format.html#cuesheet_track */
1031   for (i = 0; i < n_tracks; i++) {
1032     if (!gst_byte_reader_get_uint64_be (&reader, &offset))
1033       goto error;
1034     if (!gst_byte_reader_get_uint8 (&reader, &track_num))
1035       goto error;
1036
1037     if (gst_byte_reader_get_remaining (&reader) < 12)
1038       goto error;
1039     memcpy (isrc, map.data + gst_byte_reader_get_pos (&reader), 12);
1040     /* \0-terminate the string */
1041     isrc[12] = '\0';
1042     if (!gst_byte_reader_skip (&reader, 12))
1043       goto error;
1044
1045     /* skip 14 bytes from CUESHEET_TRACK */
1046     if (!gst_byte_reader_skip (&reader, 14))
1047       goto error;
1048     if (!gst_byte_reader_get_uint8 (&reader, &index))
1049       goto error;
1050     /* add tracks in TOC */
1051     /* lead-out tack has number 170 or 255 */
1052     if (track_num != 170 && track_num != 255) {
1053       prev_entry = cur_entry;
1054       /* previous track stop time = current track start time */
1055       if (prev_entry != NULL) {
1056         gst_toc_entry_get_start_stop_times (prev_entry, &start, NULL);
1057         stop =
1058             gst_util_uint64_scale_round (offset, GST_SECOND,
1059             flacparse->samplerate);
1060         gst_toc_entry_set_start_stop_times (prev_entry, start, stop);
1061       }
1062       id = g_strdup_printf ("%08x", track_num);
1063       cur_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, id);
1064       g_free (id);
1065       start =
1066           gst_util_uint64_scale_round (offset, GST_SECOND,
1067           flacparse->samplerate);
1068       gst_toc_entry_set_start_stop_times (cur_entry, start, -1);
1069       /* add ISRC as tag in track */
1070       if (strlen (isrc) != 0) {
1071         tags = gst_tag_list_new_empty ();
1072         gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ISRC, isrc, NULL);
1073         gst_toc_entry_set_tags (cur_entry, tags);
1074       }
1075       gst_toc_append_entry (toc, cur_entry);
1076       /* CUESHEET_TRACK_INDEX */
1077       /* http://flac.sourceforge.net/format.html#cuesheet_track_index */
1078       for (j = 0; j < index; j++) {
1079         if (!gst_byte_reader_skip (&reader, 12))
1080           goto error;
1081       }
1082     } else {
1083       /* set stop time in last track */
1084       stop =
1085           gst_util_uint64_scale_round (offset, GST_SECOND,
1086           flacparse->samplerate);
1087       gst_toc_entry_set_start_stop_times (cur_entry, start, stop);
1088     }
1089   }
1090
1091   /* send data as TOC */
1092   if (!flacparse->toc)
1093     flacparse->toc = toc;
1094
1095   gst_buffer_unmap (buffer, &map);
1096   return TRUE;
1097
1098 error:
1099   GST_ERROR_OBJECT (flacparse, "Error reading data");
1100   gst_buffer_unmap (buffer, &map);
1101   return FALSE;
1102 }
1103
1104 static gboolean
1105 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
1106 {
1107   GstByteReader reader;
1108   GstMapInfo map;
1109   guint32 img_len = 0, img_type = 0;
1110   guint32 img_mimetype_len = 0, img_description_len = 0;
1111
1112   gst_buffer_map (buffer, &map, GST_MAP_READ);
1113   gst_byte_reader_init (&reader, map.data, map.size);
1114
1115   if (!gst_byte_reader_skip (&reader, 4))
1116     goto error;
1117
1118   if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
1119     goto error;
1120
1121   if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
1122     goto error;
1123   if (!gst_byte_reader_skip (&reader, img_mimetype_len))
1124     goto error;
1125
1126   if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
1127     goto error;
1128   if (!gst_byte_reader_skip (&reader, img_description_len))
1129     goto error;
1130
1131   if (!gst_byte_reader_skip (&reader, 4 * 4))
1132     goto error;
1133
1134   if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
1135     goto error;
1136
1137   if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
1138     goto error;
1139
1140   GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);
1141
1142   if (img_len > 0) {
1143     if (flacparse->tags == NULL)
1144       flacparse->tags = gst_tag_list_new_empty ();
1145
1146     gst_tag_list_add_id3_image (flacparse->tags,
1147         map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
1148   }
1149
1150   gst_buffer_unmap (buffer, &map);
1151   return TRUE;
1152
1153 error:
1154   GST_ERROR_OBJECT (flacparse, "Error reading data");
1155   gst_buffer_unmap (buffer, &map);
1156   return FALSE;
1157 }
1158
1159 static gboolean
1160 gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
1161 {
1162
1163   GST_DEBUG_OBJECT (flacparse, "storing seektable");
1164   /* only store for now;
1165    * offset of the first frame is needed to get real info */
1166   if (flacparse->seektable)
1167     gst_buffer_unref (flacparse->seektable);
1168   flacparse->seektable = gst_buffer_ref (buffer);
1169
1170   return TRUE;
1171 }
1172
1173 static void
1174 gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
1175 {
1176   GstByteReader br;
1177   gint64 offset = 0, samples = 0;
1178   GstMapInfo map;
1179
1180   GST_DEBUG_OBJECT (flacparse,
1181       "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);
1182
1183   if (boffset <= 0)
1184     goto exit;
1185
1186   gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
1187   gst_byte_reader_init (&br, map.data, map.size);
1188
1189   /* skip header */
1190   if (!gst_byte_reader_skip (&br, 4))
1191     goto done;
1192
1193   /* seekpoints */
1194   while (gst_byte_reader_get_remaining (&br)) {
1195     if (!gst_byte_reader_get_int64_be (&br, &samples))
1196       break;
1197     if (!gst_byte_reader_get_int64_be (&br, &offset))
1198       break;
1199     if (!gst_byte_reader_skip (&br, 2))
1200       break;
1201
1202     GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
1203         G_GINT64_FORMAT, samples, offset);
1204
1205     /* sanity check */
1206     if (G_LIKELY (offset > 0 && samples > 0)) {
1207       gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
1208           boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
1209               flacparse->samplerate), TRUE, FALSE);
1210     }
1211   }
1212
1213 done:
1214   gst_buffer_unmap (flacparse->seektable, &map);
1215 exit:
1216   gst_buffer_unref (flacparse->seektable);
1217   flacparse->seektable = NULL;
1218 }
1219
1220 static void
1221 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
1222 {
1223   GValue value = { 0, };
1224
1225   g_value_init (&value, GST_TYPE_BUFFER);
1226   /* copy buffer to avoid problems with circular refcounts */
1227   buf = gst_buffer_copy (buf);
1228   /* again, for good measure */
1229   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1230   gst_value_set_buffer (&value, buf);
1231   gst_buffer_unref (buf);
1232   gst_value_array_append_value (array_val, &value);
1233   g_value_unset (&value);
1234 }
1235
1236 static GstFlowReturn
1237 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
1238 {
1239   GstBuffer *vorbiscomment = NULL;
1240   GstBuffer *streaminfo = NULL;
1241   GstBuffer *marker = NULL;
1242   GValue array = { 0, };
1243   GstCaps *caps;
1244   GList *l;
1245   GstFlowReturn res = GST_FLOW_OK;
1246
1247   caps = gst_caps_new_simple ("audio/x-flac",
1248       "channels", G_TYPE_INT, flacparse->channels,
1249       "framed", G_TYPE_BOOLEAN, TRUE,
1250       "rate", G_TYPE_INT, flacparse->samplerate, NULL);
1251
1252   if (!flacparse->headers)
1253     goto push_headers;
1254
1255   for (l = flacparse->headers; l; l = l->next) {
1256     GstBuffer *header = l->data;
1257     GstMapInfo map;
1258
1259     gst_buffer_map (header, &map, GST_MAP_READ);
1260
1261     GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);
1262
1263     if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
1264       marker = header;
1265     } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
1266       streaminfo = header;
1267     } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
1268       vorbiscomment = header;
1269     }
1270
1271     gst_buffer_unmap (header, &map);
1272   }
1273
1274   /* at least this one we can generate easily
1275    * to provide full headers downstream */
1276   if (vorbiscomment == NULL && streaminfo != NULL) {
1277     GST_DEBUG_OBJECT (flacparse,
1278         "missing vorbiscomment header; generating dummy");
1279     vorbiscomment = gst_flac_parse_generate_vorbiscomment (flacparse);
1280     flacparse->headers = g_list_insert (flacparse->headers, vorbiscomment,
1281         g_list_index (flacparse->headers, streaminfo) + 1);
1282   }
1283
1284   if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
1285     GST_WARNING_OBJECT (flacparse,
1286         "missing header %p %p %p, muxing into container "
1287         "formats may be broken", marker, streaminfo, vorbiscomment);
1288     goto push_headers;
1289   }
1290
1291   g_value_init (&array, GST_TYPE_ARRAY);
1292
1293   /* add marker including STREAMINFO header */
1294   {
1295     GstBuffer *buf;
1296     guint16 num;
1297     GstMapInfo sinfomap, writemap;
1298
1299     gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);
1300
1301     /* minus one for the marker that is merged with streaminfo here */
1302     num = g_list_length (flacparse->headers) - 1;
1303
1304     buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
1305     gst_buffer_map (buf, &writemap, GST_MAP_WRITE);
1306
1307     writemap.data[0] = 0x7f;
1308     memcpy (writemap.data + 1, "FLAC", 4);
1309     writemap.data[5] = 0x01;    /* mapping version major */
1310     writemap.data[6] = 0x00;    /* mapping version minor */
1311     writemap.data[7] = (num & 0xFF00) >> 8;
1312     writemap.data[8] = (num & 0x00FF) >> 0;
1313     memcpy (writemap.data + 9, "fLaC", 4);
1314     memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
1315     _value_array_append_buffer (&array, buf);
1316
1317     gst_buffer_unmap (streaminfo, &sinfomap);
1318     gst_buffer_unmap (buf, &writemap);
1319     gst_buffer_unref (buf);
1320   }
1321
1322   /* add VORBISCOMMENT header */
1323   _value_array_append_buffer (&array, vorbiscomment);
1324
1325   /* add other headers, if there are any */
1326   for (l = flacparse->headers; l; l = l->next) {
1327     if (GST_BUFFER_CAST (l->data) != marker &&
1328         GST_BUFFER_CAST (l->data) != streaminfo &&
1329         GST_BUFFER_CAST (l->data) != vorbiscomment) {
1330       _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
1331     }
1332   }
1333
1334   gst_structure_set_value (gst_caps_get_structure (caps, 0),
1335       "streamheader", &array);
1336   g_value_unset (&array);
1337
1338 push_headers:
1339
1340   gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
1341   gst_caps_unref (caps);
1342
1343   /* push header buffers; update caps, so when we push the first buffer the
1344    * negotiated caps will change to caps that include the streamheader field */
1345   while (flacparse->headers) {
1346     GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
1347     GstBaseParseFrame frame;
1348
1349     flacparse->headers =
1350         g_list_delete_link (flacparse->headers, flacparse->headers);
1351     buf = gst_buffer_make_writable (buf);
1352
1353     /* init, set and give away frame */
1354     gst_base_parse_frame_init (&frame);
1355     frame.buffer = buf;
1356     frame.overhead = -1;
1357     res = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
1358     gst_base_parse_frame_free (&frame);
1359     if (res != GST_FLOW_OK)
1360       break;
1361   }
1362   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
1363   g_list_free (flacparse->headers);
1364   flacparse->headers = NULL;
1365
1366   return res;
1367 }
1368
1369 /* empty vorbiscomment */
1370 static GstBuffer *
1371 gst_flac_parse_generate_vorbiscomment (GstFlacParse * flacparse)
1372 {
1373   GstTagList *taglist = gst_tag_list_new_empty ();
1374   guchar header[4];
1375   guint size;
1376   GstBuffer *vorbiscomment;
1377   GstMapInfo map;
1378
1379   header[0] = 0x84;             /* is_last = 1; type = 4; */
1380
1381   vorbiscomment =
1382       gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1383       sizeof (header), NULL);
1384   gst_tag_list_unref (taglist);
1385
1386   gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1387
1388   /* Get rid of framing bit */
1389   if (map.data[map.size - 1] == 1) {
1390     GstBuffer *sub;
1391
1392     sub =
1393         gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
1394         map.size - 1);
1395     gst_buffer_unmap (vorbiscomment, &map);
1396     gst_buffer_unref (vorbiscomment);
1397     vorbiscomment = sub;
1398     gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1399   }
1400
1401   size = map.size - 4;
1402   map.data[1] = ((size & 0xFF0000) >> 16);
1403   map.data[2] = ((size & 0x00FF00) >> 8);
1404   map.data[3] = (size & 0x0000FF);
1405   gst_buffer_unmap (vorbiscomment, &map);
1406   gst_flac_parse_reset_buffer_time_and_offset (vorbiscomment);
1407
1408   return vorbiscomment;
1409 }
1410
1411 static gboolean
1412 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1413 {
1414   GstBuffer *marker, *streaminfo;
1415   GstMapInfo map;
1416
1417   marker = gst_buffer_new_and_alloc (4);
1418   gst_buffer_map (marker, &map, GST_MAP_WRITE);
1419   memcpy (map.data, "fLaC", 4);
1420   gst_buffer_unmap (marker, &map);
1421   gst_flac_parse_reset_buffer_time_and_offset (marker);
1422   flacparse->headers = g_list_append (flacparse->headers, marker);
1423
1424   streaminfo = gst_buffer_new_and_alloc (4 + 34);
1425   gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
1426   memset (map.data, 0, 4 + 34);
1427
1428   /* metadata block header */
1429   map.data[0] = 0x00;           /* is_last = 0; type = 0; */
1430   map.data[1] = 0x00;           /* length = 34; */
1431   map.data[2] = 0x00;
1432   map.data[3] = 0x22;
1433
1434   /* streaminfo */
1435
1436   map.data[4] = (flacparse->block_size >> 8) & 0xff;    /* min blocksize = blocksize; */
1437   map.data[5] = (flacparse->block_size) & 0xff;
1438   map.data[6] = (flacparse->block_size >> 8) & 0xff;    /* max blocksize = blocksize; */
1439   map.data[7] = (flacparse->block_size) & 0xff;
1440
1441   map.data[8] = 0x00;           /* min framesize = 0; */
1442   map.data[9] = 0x00;
1443   map.data[10] = 0x00;
1444   map.data[11] = 0x00;          /* max framesize = 0; */
1445   map.data[12] = 0x00;
1446   map.data[13] = 0x00;
1447
1448   map.data[14] = (flacparse->samplerate >> 12) & 0xff;
1449   map.data[15] = (flacparse->samplerate >> 4) & 0xff;
1450   map.data[16] = (flacparse->samplerate >> 0) & 0xf0;
1451
1452   map.data[16] |= (flacparse->channels - 1) << 1;
1453
1454   map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1455   map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1456
1457   {
1458     gint64 duration;
1459
1460     if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
1461             GST_FORMAT_TIME, &duration) && duration != -1) {
1462       duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1463
1464       map.data[17] |= (duration >> 32) & 0xff;
1465       map.data[18] |= (duration >> 24) & 0xff;
1466       map.data[19] |= (duration >> 16) & 0xff;
1467       map.data[20] |= (duration >> 8) & 0xff;
1468       map.data[21] |= (duration >> 0) & 0xff;
1469     }
1470   }
1471   /* MD5 = 0; */
1472
1473   gst_buffer_unmap (streaminfo, &map);
1474   gst_flac_parse_reset_buffer_time_and_offset (streaminfo);
1475   flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1476
1477   flacparse->headers = g_list_append (flacparse->headers,
1478       gst_flac_parse_generate_vorbiscomment (flacparse));
1479
1480   return TRUE;
1481 }
1482
1483 static inline void
1484 gst_flac_parse_reset_buffer_time_and_offset (GstBuffer * buffer)
1485 {
1486   GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1487   GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1488   GST_BUFFER_OFFSET (buffer) = 0;
1489   GST_BUFFER_OFFSET_END (buffer) = 0;
1490 }
1491
1492 static gboolean
1493 gst_flac_parse_handle_block_type (GstFlacParse * flacparse, guint type,
1494     GstBuffer * sbuffer)
1495 {
1496   gboolean ret = TRUE;
1497
1498   switch (type) {
1499     case 0:                    /* STREAMINFO */
1500       GST_INFO_OBJECT (flacparse, "STREAMINFO header");
1501       ret = gst_flac_parse_handle_streaminfo (flacparse, sbuffer);
1502       break;
1503     case 3:                    /* SEEKTABLE */
1504       GST_INFO_OBJECT (flacparse, "SEEKTABLE header");
1505       ret = gst_flac_parse_handle_seektable (flacparse, sbuffer);
1506       break;
1507     case 4:                    /* VORBIS_COMMENT */
1508       GST_INFO_OBJECT (flacparse, "VORBISCOMMENT header");
1509       ret = gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer);
1510       break;
1511     case 5:                    /* CUESHEET */
1512       GST_INFO_OBJECT (flacparse, "CUESHEET header");
1513       ret = gst_flac_parse_handle_cuesheet (flacparse, sbuffer);
1514       break;
1515     case 6:                    /* PICTURE */
1516       GST_INFO_OBJECT (flacparse, "PICTURE header");
1517       ret = gst_flac_parse_handle_picture (flacparse, sbuffer);
1518       break;
1519     case 1:                    /* PADDING */
1520       GST_INFO_OBJECT (flacparse, "PADDING header");
1521       break;
1522     case 2:                    /* APPLICATION */
1523       GST_INFO_OBJECT (flacparse, "APPLICATION header");
1524       break;
1525     default:                   /* RESERVED */
1526       GST_INFO_OBJECT (flacparse, "unhandled header of type %u", type);
1527       break;
1528   }
1529
1530   return ret;
1531 }
1532
1533 static GstFlowReturn
1534 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
1535     gint size)
1536 {
1537   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1538   GstBuffer *buffer = frame->buffer, *sbuffer;
1539   GstMapInfo map;
1540   GstFlowReturn res = GST_FLOW_ERROR;
1541
1542   gst_buffer_map (buffer, &map, GST_MAP_READ);
1543
1544   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1545     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1546     gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1547
1548     /* 32 bits metadata block */
1549     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1550     flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1551
1552     flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1553
1554     res = GST_BASE_PARSE_FLOW_DROPPED;
1555   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1556     gboolean is_last = ((map.data[0] & 0x80) == 0x80);
1557     guint type = (map.data[0] & 0x7F);
1558
1559     if (type == 127) {
1560       GST_WARNING_OBJECT (flacparse, "Invalid metadata block type");
1561       res = GST_BASE_PARSE_FLOW_DROPPED;
1562       goto cleanup;
1563     }
1564
1565     GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1566
1567     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1568
1569     if (gst_flac_parse_handle_block_type (flacparse, type, sbuffer)) {
1570       gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1571       flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1572     } else {
1573       GST_WARNING_OBJECT (parse, "failed to parse header of type %u", type);
1574       GST_MEMDUMP_OBJECT (parse, "bad header data", map.data, size);
1575
1576       gst_buffer_unref (sbuffer);
1577
1578       /* error out unless we have a STREAMINFO header */
1579       if (flacparse->samplerate == 0 || flacparse->bps == 0)
1580         goto header_parsing_error;
1581
1582       /* .. in which case just stop header parsing and try to find audio */
1583       is_last = TRUE;
1584     }
1585
1586     if (is_last) {
1587       res = gst_flac_parse_handle_headers (flacparse);
1588
1589       /* Minimal size of a frame header */
1590       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1591               flacparse->min_framesize));
1592       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1593
1594       if (res != GST_FLOW_OK)
1595         goto cleanup;
1596     }
1597
1598     /* DROPPED because we pushed already or will push all headers manually */
1599     res = GST_BASE_PARSE_FLOW_DROPPED;
1600   } else {
1601     if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1602       FrameHeaderCheckReturn ret;
1603
1604       flacparse->offset = GST_BUFFER_OFFSET (buffer);
1605       ret =
1606           gst_flac_parse_frame_header_is_valid (flacparse,
1607           map.data, map.size, TRUE, NULL, NULL);
1608       if (ret != FRAME_HEADER_VALID) {
1609         GST_ERROR_OBJECT (flacparse,
1610             "Baseclass didn't provide a complete frame");
1611         goto cleanup;
1612       }
1613     }
1614
1615     if (flacparse->block_size == 0) {
1616       GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1617       goto cleanup;
1618     }
1619
1620     if (flacparse->seektable)
1621       gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));
1622
1623     if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1624       if (flacparse->blocking_strategy == 1) {
1625         GST_WARNING_OBJECT (flacparse,
1626             "Generating headers for variable blocksize streams not supported");
1627
1628         res = gst_flac_parse_handle_headers (flacparse);
1629       } else {
1630         GST_DEBUG_OBJECT (flacparse, "Generating headers");
1631
1632         if (!gst_flac_parse_generate_headers (flacparse))
1633           goto cleanup;
1634
1635         res = gst_flac_parse_handle_headers (flacparse);
1636       }
1637       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1638       if (res != GST_FLOW_OK)
1639         goto cleanup;
1640     }
1641
1642     /* also cater for oggmux metadata */
1643     if (flacparse->blocking_strategy == 0) {
1644       GST_BUFFER_PTS (buffer) =
1645           gst_util_uint64_scale (flacparse->sample_number,
1646           flacparse->block_size * GST_SECOND, flacparse->samplerate);
1647       GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
1648       GST_BUFFER_OFFSET_END (buffer) =
1649           flacparse->sample_number * flacparse->block_size +
1650           flacparse->block_size;
1651     } else {
1652       GST_BUFFER_PTS (buffer) =
1653           gst_util_uint64_scale (flacparse->sample_number, GST_SECOND,
1654           flacparse->samplerate);
1655       GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
1656       GST_BUFFER_OFFSET_END (buffer) =
1657           flacparse->sample_number + flacparse->block_size;
1658     }
1659     GST_BUFFER_OFFSET (buffer) =
1660         gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
1661         flacparse->samplerate);
1662     GST_BUFFER_DURATION (buffer) =
1663         GST_BUFFER_OFFSET (buffer) - GST_BUFFER_PTS (buffer);
1664
1665     /* To simplify, we just assume that it's a fixed size header and ignore
1666      * subframe headers. The first could lead us to being off by 88 bits and
1667      * the second even less, so the total inaccuracy is negligible. */
1668     frame->overhead = 7;
1669
1670     /* Minimal size of a frame header */
1671     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1672             flacparse->min_framesize));
1673
1674     flacparse->offset = -1;
1675     flacparse->blocking_strategy = 0;
1676     flacparse->sample_number = 0;
1677     res = GST_FLOW_OK;
1678   }
1679
1680 cleanup:
1681   gst_buffer_unmap (buffer, &map);
1682
1683   return res;
1684
1685 /* ERRORS */
1686 header_parsing_error:
1687   {
1688     GST_ELEMENT_ERROR (flacparse, STREAM, DECODE, (NULL),
1689         ("Failed to parse headers"));
1690     goto cleanup;
1691   }
1692 }
1693
1694 static GstFlowReturn
1695 gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1696 {
1697   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1698
1699   if (!flacparse->sent_codec_tag) {
1700     GstCaps *caps;
1701
1702     if (flacparse->tags == NULL)
1703       flacparse->tags = gst_tag_list_new_empty ();
1704
1705     /* codec tag */
1706     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1707     if (G_UNLIKELY (caps == NULL)) {
1708       if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1709         GST_INFO_OBJECT (parse, "Src pad is flushing");
1710         return GST_FLOW_FLUSHING;
1711       } else {
1712         GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1713         return GST_FLOW_NOT_NEGOTIATED;
1714       }
1715     }
1716     gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
1717         GST_TAG_AUDIO_CODEC, caps);
1718     gst_caps_unref (caps);
1719
1720     /* Announce our pending tags */
1721     gst_base_parse_merge_tags (parse, flacparse->tags, GST_TAG_MERGE_REPLACE);
1722
1723     /* also signals the end of first-frame processing */
1724     flacparse->sent_codec_tag = TRUE;
1725   }
1726
1727   /* Push toc */
1728   if (flacparse->toc) {
1729     gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
1730         gst_event_new_toc (flacparse->toc, FALSE));
1731   }
1732
1733   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1734
1735   return GST_FLOW_OK;
1736 }
1737
1738 static gboolean
1739 gst_flac_parse_convert (GstBaseParse * parse,
1740     GstFormat src_format, gint64 src_value, GstFormat dest_format,
1741     gint64 * dest_value)
1742 {
1743   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1744
1745   if (flacparse->samplerate > 0) {
1746     if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1747       if (src_value != -1)
1748         *dest_value =
1749             gst_util_uint64_scale (src_value, GST_SECOND,
1750             flacparse->samplerate);
1751       else
1752         *dest_value = -1;
1753       return TRUE;
1754     } else if (src_format == GST_FORMAT_TIME &&
1755         dest_format == GST_FORMAT_DEFAULT) {
1756       if (src_value != -1)
1757         *dest_value =
1758             gst_util_uint64_scale (src_value, flacparse->samplerate,
1759             GST_SECOND);
1760       else
1761         *dest_value = -1;
1762       return TRUE;
1763     }
1764   }
1765
1766   return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
1767       src_value, dest_format, dest_value);
1768 }
1769
1770 static gboolean
1771 gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1772 {
1773   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1774   gboolean res = FALSE;
1775
1776   switch (GST_EVENT_TYPE (event)) {
1777     case GST_EVENT_TOC_SELECT:
1778     {
1779       GstTocEntry *entry = NULL;
1780       GstEvent *seek_event;
1781       GstToc *toc = NULL;
1782       gint64 start_pos;
1783       gchar *uid = NULL;
1784
1785       /* FIXME: some locking would be good */
1786       if (flacparse->toc)
1787         toc = gst_toc_ref (flacparse->toc);
1788
1789       if (toc != NULL) {
1790         gst_event_parse_toc_select (event, &uid);
1791         if (uid != NULL) {
1792           entry = gst_toc_find_entry (toc, uid);
1793           if (entry != NULL) {
1794             gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
1795
1796             /* FIXME: use segment rate here instead? */
1797             seek_event = gst_event_new_seek (1.0,
1798                 GST_FORMAT_TIME,
1799                 GST_SEEK_FLAG_FLUSH,
1800                 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);
1801
1802             res =
1803                 GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
1804                 seek_event);
1805
1806           } else {
1807             GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
1808           }
1809           g_free (uid);
1810         }
1811         gst_toc_unref (toc);
1812       } else {
1813         GST_DEBUG_OBJECT (flacparse, "no TOC to select");
1814       }
1815       gst_event_unref (event);
1816       break;
1817     }
1818     default:
1819       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1820       break;
1821   }
1822   return res;
1823 }
1824
1825 static void
1826 remove_fields (GstCaps * caps)
1827 {
1828   guint i, n;
1829
1830   n = gst_caps_get_size (caps);
1831   for (i = 0; i < n; i++) {
1832     GstStructure *s = gst_caps_get_structure (caps, i);
1833
1834     gst_structure_remove_field (s, "framed");
1835   }
1836 }
1837
1838 static GstCaps *
1839 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
1840 {
1841   GstCaps *peercaps, *templ;
1842   GstCaps *res;
1843
1844   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1845   if (filter) {
1846     GstCaps *fcopy = gst_caps_copy (filter);
1847     /* Remove the fields we convert */
1848     remove_fields (fcopy);
1849     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1850     gst_caps_unref (fcopy);
1851   } else
1852     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1853
1854   if (peercaps) {
1855     /* Remove the framed field */
1856     peercaps = gst_caps_make_writable (peercaps);
1857     remove_fields (peercaps);
1858
1859     res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1860     gst_caps_unref (peercaps);
1861     gst_caps_unref (templ);
1862   } else {
1863     res = templ;
1864   }
1865
1866   if (filter) {
1867     GstCaps *intersection;
1868
1869     intersection =
1870         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1871     gst_caps_unref (res);
1872     res = intersection;
1873   }
1874
1875   return res;
1876 }