flacparse: Don't drop the last frame if it is followed by garbage
[platform/upstream/gstreamer.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., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, 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 -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
62 #include <gst/base/gstbitreader.h>
63 #include <gst/base/gstbytereader.h>
64
65 GST_DEBUG_CATEGORY_STATIC (flacparse_debug);
66 #define GST_CAT_DEFAULT flacparse_debug
67
68 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
69 static const guint8 crc8_table[256] = {
70   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
71   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
72   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
73   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
74   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
75   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
76   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
77   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
78   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
79   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
80   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
81   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
82   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
83   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
84   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
85   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
86   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
87   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
88   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
89   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
90   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
91   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
92   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
93   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
94   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
95   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
96   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
97   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
98   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
99   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
100   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
101   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
102 };
103
104 static guint8
105 gst_flac_calculate_crc8 (const guint8 * data, guint length)
106 {
107   guint8 crc = 0;
108
109   while (length--) {
110     crc = crc8_table[crc ^ *data];
111     ++data;
112   }
113
114   return crc;
115 }
116
117 /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
118 static const guint16 crc16_table[256] = {
119   0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
120   0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
121   0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
122   0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
123   0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
124   0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
125   0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
126   0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
127   0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
128   0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
129   0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
130   0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
131   0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
132   0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
133   0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
134   0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
135   0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
136   0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
137   0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
138   0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
139   0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
140   0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
141   0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
142   0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
143   0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
144   0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
145   0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
146   0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
147   0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
148   0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
149   0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
150   0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
151 };
152
153 static guint16
154 gst_flac_calculate_crc16 (const guint8 * data, guint length)
155 {
156   guint16 crc = 0;
157
158   while (length--) {
159     crc = ((crc << 8) ^ crc16_table[(crc >> 8) ^ *data]) & 0xffff;
160     data++;
161   }
162
163   return crc;
164 }
165
166 enum
167 {
168   PROP_0,
169   PROP_CHECK_FRAME_CHECKSUMS
170 };
171
172 #define DEFAULT_CHECK_FRAME_CHECKSUMS FALSE
173
174 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
175     GST_PAD_SRC,
176     GST_PAD_ALWAYS,
177     GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) true, "
178         "channels = (int) [ 1, 8 ], " "rate = (int) [ 1, 655350 ]")
179     );
180
181 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
182     GST_PAD_SINK,
183     GST_PAD_ALWAYS,
184     GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) false")
185     );
186
187 static void gst_flac_parse_finalize (GObject * object);
188 static void gst_flac_parse_set_property (GObject * object, guint prop_id,
189     const GValue * value, GParamSpec * pspec);
190 static void gst_flac_parse_get_property (GObject * object, guint prop_id,
191     GValue * value, GParamSpec * pspec);
192
193 static gboolean gst_flac_parse_start (GstBaseParse * parse);
194 static gboolean gst_flac_parse_stop (GstBaseParse * parse);
195 static gboolean gst_flac_parse_check_valid_frame (GstBaseParse * parse,
196     GstBuffer * buffer, guint * framesize, gint * skipsize);
197 static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
198     GstBuffer * buffer);
199 static gint gst_flac_parse_get_frame_overhead (GstBaseParse * parse,
200     GstBuffer * buffer);
201 static GstFlowReturn gst_flac_parse_pre_push_buffer (GstBaseParse * parse,
202     GstBuffer * buf);
203
204 GST_BOILERPLATE (GstFlacParse, gst_flac_parse, GstBaseParse,
205     GST_TYPE_BASE_PARSE);
206
207 static void
208 gst_flac_parse_base_init (gpointer g_class)
209 {
210   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
211
212   gst_element_class_add_pad_template (element_class,
213       gst_static_pad_template_get (&src_factory));
214   gst_element_class_add_pad_template (element_class,
215       gst_static_pad_template_get (&sink_factory));
216
217   gst_element_class_set_details_simple (element_class, "FLAC audio parser",
218       "Codec/Parser/Audio",
219       "Parses audio with the FLAC lossless audio codec",
220       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
221
222   GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
223       "Flac parser element");
224 }
225
226 static void
227 gst_flac_parse_class_init (GstFlacParseClass * klass)
228 {
229   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
230   GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
231
232   gobject_class->finalize = gst_flac_parse_finalize;
233   gobject_class->set_property = gst_flac_parse_set_property;
234   gobject_class->get_property = gst_flac_parse_get_property;
235
236   g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
237       g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
238           "Check the overall checksums of every frame",
239           DEFAULT_CHECK_FRAME_CHECKSUMS,
240           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
241
242   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
243   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
244   baseparse_class->check_valid_frame =
245       GST_DEBUG_FUNCPTR (gst_flac_parse_check_valid_frame);
246   baseparse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_flac_parse_parse_frame);
247   baseparse_class->get_frame_overhead =
248       GST_DEBUG_FUNCPTR (gst_flac_parse_get_frame_overhead);
249   baseparse_class->pre_push_buffer =
250       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_buffer);
251 }
252
253 static void
254 gst_flac_parse_init (GstFlacParse * flacparse, GstFlacParseClass * klass)
255 {
256   flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
257 }
258
259 static void
260 gst_flac_parse_set_property (GObject * object, guint prop_id,
261     const GValue * value, GParamSpec * pspec)
262 {
263   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
264
265   switch (prop_id) {
266     case PROP_CHECK_FRAME_CHECKSUMS:
267       flacparse->check_frame_checksums = g_value_get_boolean (value);
268       break;
269     default:
270       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
271       break;
272   }
273 }
274
275 static void
276 gst_flac_parse_get_property (GObject * object, guint prop_id,
277     GValue * value, GParamSpec * pspec)
278 {
279   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
280
281   switch (prop_id) {
282     case PROP_CHECK_FRAME_CHECKSUMS:
283       g_value_set_boolean (value, flacparse->check_frame_checksums);
284       break;
285     default:
286       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
287       break;
288   }
289 }
290
291 static void
292 gst_flac_parse_finalize (GObject * object)
293 {
294   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
295
296   if (flacparse->tags) {
297     gst_tag_list_free (flacparse->tags);
298     flacparse->tags = NULL;
299   }
300
301   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
302   g_list_free (flacparse->headers);
303   flacparse->headers = NULL;
304
305   G_OBJECT_CLASS (parent_class)->finalize (object);
306 }
307
308 static gboolean
309 gst_flac_parse_start (GstBaseParse * parse)
310 {
311   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
312
313   flacparse->state = GST_FLAC_PARSE_STATE_INIT;
314   flacparse->min_blocksize = 0;
315   flacparse->max_blocksize = 0;
316   flacparse->min_framesize = 0;
317   flacparse->max_framesize = 0;
318
319   flacparse->upstream_length = -1;
320
321   flacparse->samplerate = 0;
322   flacparse->channels = 0;
323   flacparse->bps = 0;
324   flacparse->total_samples = 0;
325
326   flacparse->offset = GST_CLOCK_TIME_NONE;
327   flacparse->blocking_strategy = 0;
328   flacparse->block_size = 0;
329   flacparse->sample_number = 0;
330
331   /* "fLaC" marker */
332   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
333
334   return TRUE;
335 }
336
337 static gboolean
338 gst_flac_parse_stop (GstBaseParse * parse)
339 {
340   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
341
342   if (flacparse->tags) {
343     gst_tag_list_free (flacparse->tags);
344     flacparse->tags = NULL;
345   }
346
347   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
348   g_list_free (flacparse->headers);
349   flacparse->headers = NULL;
350
351   return TRUE;
352 }
353
354 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
355
356 static const guint16 blocksize_table[16] = {
357   0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
358   256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
359   256 << 7,
360 };
361
362 static const guint32 sample_rate_table[16] = {
363   0,
364   88200, 176400, 192000,
365   8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
366   0, 0, 0, 0,
367 };
368
369 typedef enum
370 {
371   FRAME_HEADER_VALID,
372   FRAME_HEADER_INVALID,
373   FRAME_HEADER_MORE_DATA
374 } FrameHeaderCheckReturn;
375
376 static FrameHeaderCheckReturn
377 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
378     const guint8 * data, guint size, gboolean set, guint16 * block_size_ret)
379 {
380   GstBitReader reader = GST_BIT_READER_INIT (data, size);
381   guint8 blocking_strategy;
382   guint16 block_size;
383   guint32 samplerate = 0;
384   guint64 sample_number;
385   guint8 channels, bps;
386   guint8 tmp = 0;
387   guint8 actual_crc, expected_crc = 0;
388
389   /* Skip 14 bit sync code */
390   gst_bit_reader_skip_unchecked (&reader, 14);
391
392   /* Must be 0 */
393   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
394     goto error;
395
396   /* 0 == fixed block size, 1 == variable block size */
397   blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
398
399   /* block size index, calculation of the real blocksize below */
400   block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
401   if (block_size == 0)
402     goto error;
403
404   /* sample rate index, calculation of the real samplerate below */
405   samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
406   if (samplerate == 0x0f)
407     goto error;
408
409   /* channel assignment */
410   channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
411   if (channels < 8) {
412     channels++;
413   } else if (channels <= 10) {
414     channels = 2;
415   } else if (channels > 10) {
416     goto error;
417   }
418   if (flacparse->channels && flacparse->channels != channels)
419     goto error;
420
421   /* bits per sample */
422   bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
423   if (bps == 0x03 || bps == 0x07) {
424     goto error;
425   } else if (bps == 0 && flacparse->bps == 0) {
426     goto need_streaminfo;
427   }
428   bps = sample_size_table[bps];
429   if (flacparse->bps && bps != flacparse->bps)
430     goto error;
431
432   /* reserved, must be 0 */
433   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
434     goto error;
435
436   /* read "utf8" encoded sample/frame number */
437   {
438     gint len = 0;
439
440     len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
441
442     /* This is slightly faster than a loop */
443     if (!(len & 0x80)) {
444       sample_number = len;
445       len = 0;
446     } else if ((len & 0xc0) && !(len & 0x20)) {
447       sample_number = len & 0x1f;
448       len = 1;
449     } else if ((len & 0xe0) && !(len & 0x10)) {
450       sample_number = len & 0x0f;
451       len = 2;
452     } else if ((len & 0xf0) && !(len & 0x08)) {
453       sample_number = len & 0x07;
454       len = 3;
455     } else if ((len & 0xf8) && !(len & 0x04)) {
456       sample_number = len & 0x03;
457       len = 4;
458     } else if ((len & 0xfc) && !(len & 0x02)) {
459       sample_number = len & 0x01;
460       len = 5;
461     } else if ((len & 0xfe) && !(len & 0x01)) {
462       sample_number = len & 0x0;
463       len = 6;
464     } else {
465       goto error;
466     }
467
468     if ((blocking_strategy == 0 && len > 5) ||
469         (blocking_strategy == 1 && len > 6))
470       goto error;
471
472     while (len > 0) {
473       if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
474         goto need_more_data;
475
476       if ((tmp & 0xc0) != 0x80)
477         goto error;
478
479       sample_number <<= 6;
480       sample_number |= (tmp & 0x3f);
481       len--;
482     }
483   }
484
485   /* calculate real blocksize from the blocksize index */
486   if (block_size == 0) {
487     goto error;
488   } else if (block_size == 6) {
489     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
490       goto need_more_data;
491     block_size++;
492   } else if (block_size == 7) {
493     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
494       goto need_more_data;
495     block_size++;
496   } else {
497     block_size = blocksize_table[block_size];
498   }
499
500   /* calculate the real samplerate from the samplerate index */
501   if (samplerate == 0 && flacparse->samplerate == 0) {
502     goto need_streaminfo;
503   } else if (samplerate < 12) {
504     samplerate = sample_rate_table[samplerate];
505   } else if (samplerate == 12) {
506     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
507       goto need_more_data;
508     samplerate *= 1000;
509   } else if (samplerate == 13) {
510     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
511       goto need_more_data;
512   } else if (samplerate == 14) {
513     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
514       goto need_more_data;
515     samplerate *= 10;
516   }
517
518   if (flacparse->samplerate && flacparse->samplerate != samplerate)
519     goto error;
520
521   /* check crc-8 for the header */
522   if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
523     goto need_more_data;
524
525   actual_crc =
526       gst_flac_calculate_crc8 (data,
527       (gst_bit_reader_get_pos (&reader) / 8) - 1);
528   if (actual_crc != expected_crc)
529     goto error;
530
531   if (set) {
532     flacparse->block_size = block_size;
533     if (!flacparse->samplerate)
534       flacparse->samplerate = samplerate;
535     if (!flacparse->bps)
536       flacparse->bps = bps;
537     if (!flacparse->blocking_strategy)
538       flacparse->blocking_strategy = blocking_strategy;
539     if (!flacparse->channels)
540       flacparse->channels = channels;
541     if (!flacparse->sample_number)
542       flacparse->sample_number = sample_number;
543
544     GST_DEBUG_OBJECT (flacparse,
545         "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
546         "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
547         flacparse->block_size, flacparse->sample_number);
548   }
549
550   if (block_size_ret)
551     *block_size_ret = block_size;
552
553   return FRAME_HEADER_VALID;
554
555 need_streaminfo:
556   GST_ERROR_OBJECT (flacparse, "Need STREAMINFO");
557   return FRAME_HEADER_INVALID;
558 error:
559   return FRAME_HEADER_INVALID;
560
561 need_more_data:
562   return FRAME_HEADER_MORE_DATA;
563 }
564
565 static gboolean
566 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse, GstBuffer * buffer,
567     guint * ret)
568 {
569   const guint8 *data;
570   guint max, size, remaining;
571   guint i, search_start, search_end;
572   FrameHeaderCheckReturn header_ret;
573   guint16 block_size;
574
575   data = GST_BUFFER_DATA (buffer);
576   size = GST_BUFFER_SIZE (buffer);
577
578   if (size <= flacparse->min_framesize)
579     goto need_more;
580
581   header_ret =
582       gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
583       &block_size);
584   if (header_ret == FRAME_HEADER_INVALID) {
585     *ret = 0;
586     return FALSE;
587   } else if (header_ret == FRAME_HEADER_MORE_DATA) {
588     goto need_more;
589   }
590
591   /* mind unknown framesize */
592   search_start = MAX (2, flacparse->min_framesize);
593   if (flacparse->max_framesize)
594     search_end = MIN (size, flacparse->max_framesize + 9 + 2);
595   else
596     search_end = size;
597   search_end -= 2;
598
599   remaining = size;
600
601   for (i = search_start; i < search_end; i++, remaining--) {
602     if ((GST_READ_UINT16_BE (data + i) & 0xfffe) == 0xfff8) {
603       header_ret =
604           gst_flac_parse_frame_header_is_valid (flacparse, data + i, remaining,
605           FALSE, NULL);
606       if (header_ret == FRAME_HEADER_VALID) {
607         if (flacparse->check_frame_checksums) {
608           guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
609           guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);
610
611           if (actual_crc != expected_crc)
612             continue;
613         }
614         *ret = i;
615         flacparse->block_size = block_size;
616         return TRUE;
617       } else if (header_ret == FRAME_HEADER_MORE_DATA) {
618         goto need_more;
619       }
620     }
621   }
622
623   /* For the last frame output everything to the end */
624   if (G_UNLIKELY (gst_base_parse_get_drain (GST_BASE_PARSE (flacparse)))) {
625     if (flacparse->check_frame_checksums) {
626       guint16 actual_crc = gst_flac_calculate_crc16 (data, size - 2);
627       guint16 expected_crc = GST_READ_UINT16_BE (data + size - 2);
628
629       if (actual_crc == expected_crc) {
630         *ret = size;
631         flacparse->block_size = block_size;
632         return TRUE;
633       }
634     } else {
635       *ret = size;
636       flacparse->block_size = block_size;
637       return TRUE;
638     }
639   }
640
641 need_more:
642   max = flacparse->max_framesize + 16;
643   if (max == 16)
644     max = 1 << 24;
645   *ret = MIN (size + 4096, max);
646   return FALSE;
647 }
648
649 static gboolean
650 gst_flac_parse_check_valid_frame (GstBaseParse * parse,
651     GstBuffer * buffer, guint * framesize, gint * skipsize)
652 {
653   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
654   const guint8 *data = GST_BUFFER_DATA (buffer);
655
656   if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 4))
657     return FALSE;
658
659   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
660     if (memcmp (GST_BUFFER_DATA (buffer), "fLaC", 4) == 0) {
661       GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
662       *framesize = 4;
663       return TRUE;
664     } else if (data[0] == 0xff && (data[1] >> 2) == 0x3e) {
665       GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
666       /* Minimal size of a frame header */
667       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
668       flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
669       *skipsize = 0;
670       return FALSE;
671     } else {
672       GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
673       return FALSE;
674     }
675   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
676     guint size = 4 + ((data[1] << 16) | (data[2] << 8) | (data[3]));
677
678     GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
679     *framesize = size;
680     return TRUE;
681   } else {
682     if ((GST_READ_UINT16_BE (data) & 0xfffe) == 0xfff8) {
683       gboolean ret;
684       guint next;
685
686       flacparse->offset = GST_BUFFER_OFFSET (buffer);
687       flacparse->blocking_strategy = 0;
688       flacparse->block_size = 0;
689       flacparse->sample_number = 0;
690
691       GST_DEBUG_OBJECT (flacparse, "Found sync code");
692       ret = gst_flac_parse_frame_is_valid (flacparse, buffer, &next);
693       if (ret) {
694         *framesize = next;
695         return TRUE;
696       } else {
697         /* If we're at EOS and the frame was not valid, drop it! */
698         if (G_UNLIKELY (gst_base_parse_get_drain (parse))) {
699           GST_WARNING_OBJECT (flacparse, "EOS");
700           return FALSE;
701         }
702
703         if (next == 0) {
704         } else if (next > GST_BUFFER_SIZE (buffer)) {
705           GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
706           *skipsize = 0;
707           gst_base_parse_set_min_frame_size (parse, next);
708           return FALSE;
709         } else {
710           GST_ERROR_OBJECT (flacparse,
711               "Giving up on invalid frame (%d bytes)",
712               GST_BUFFER_SIZE (buffer));
713           return FALSE;
714         }
715       }
716     } else {
717       GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer);
718       gint off;
719
720       off =
721           gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
722           0, GST_BUFFER_SIZE (buffer));
723
724       if (off > 0) {
725         GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
726         *skipsize = off;
727         return FALSE;
728       } else {
729         GST_DEBUG_OBJECT (flacparse, "Sync code not found");
730         *skipsize = GST_BUFFER_SIZE (buffer) - 3;
731         return FALSE;
732       }
733     }
734   }
735
736   return FALSE;
737 }
738
739 static gboolean
740 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
741 {
742   GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);
743
744   if (GST_BUFFER_SIZE (buffer) != 4 + 34) {
745     GST_ERROR_OBJECT (flacparse, "Invalid metablock size for STREAMINFO: %u",
746         GST_BUFFER_SIZE (buffer));
747     return FALSE;
748   }
749
750   /* Skip metadata block header */
751   gst_bit_reader_skip (&reader, 32);
752
753   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
754     goto error;
755   if (flacparse->min_blocksize < 16) {
756     GST_ERROR_OBJECT (flacparse, "Invalid minimum block size: %u",
757         flacparse->min_blocksize);
758     return FALSE;
759   }
760
761   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
762     goto error;
763   if (flacparse->max_blocksize < 16) {
764     GST_ERROR_OBJECT (flacparse, "Invalid maximum block size: %u",
765         flacparse->max_blocksize);
766     return FALSE;
767   }
768
769   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
770     goto error;
771   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
772     goto error;
773
774   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
775     goto error;
776   if (flacparse->samplerate == 0) {
777     GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
778     return FALSE;
779   }
780
781   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
782     goto error;
783   flacparse->channels++;
784   if (flacparse->channels > 8) {
785     GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
786         flacparse->channels);
787     return FALSE;
788   }
789
790   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
791     goto error;
792   flacparse->bps++;
793
794   if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
795     goto error;
796   if (flacparse->total_samples)
797     gst_base_parse_set_duration (GST_BASE_PARSE (flacparse), GST_FORMAT_TIME,
798         GST_FRAMES_TO_CLOCK_TIME (flacparse->total_samples,
799             flacparse->samplerate), 0);
800
801   GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
802       "\tmin/max blocksize: %u/%u,\n"
803       "\tmin/max framesize: %u/%u,\n"
804       "\tsamplerate: %u,\n"
805       "\tchannels: %u,\n"
806       "\tbits per sample: %u,\n"
807       "\ttotal samples: %" G_GUINT64_FORMAT,
808       flacparse->min_blocksize, flacparse->max_blocksize,
809       flacparse->min_framesize, flacparse->max_framesize,
810       flacparse->samplerate,
811       flacparse->channels, flacparse->bps, flacparse->total_samples);
812
813   return TRUE;
814
815 error:
816   GST_ERROR_OBJECT (flacparse, "Failed to read data");
817   return FALSE;
818 }
819
820 static gboolean
821 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
822     GstBuffer * buffer)
823 {
824   flacparse->tags = gst_tag_list_from_vorbiscomment_buffer (buffer,
825       GST_BUFFER_DATA (buffer), 4, NULL);
826
827   if (flacparse->tags == NULL) {
828     GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
829   } else if (gst_tag_list_is_empty (flacparse->tags)) {
830     gst_tag_list_free (flacparse->tags);
831     flacparse->tags = NULL;
832   }
833
834   return TRUE;
835 }
836
837 static gboolean
838 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
839 {
840   GstByteReader reader = GST_BYTE_READER_INIT_FROM_BUFFER (buffer);
841   const guint8 *data = GST_BUFFER_DATA (buffer);
842   guint32 img_len = 0, img_type = 0;
843   guint32 img_mimetype_len = 0, img_description_len = 0;
844
845   if (!gst_byte_reader_skip (&reader, 4))
846     goto error;
847
848   if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
849     goto error;
850
851   if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
852     goto error;
853   if (!gst_byte_reader_skip (&reader, img_mimetype_len))
854     goto error;
855
856   if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
857     goto error;
858   if (!gst_byte_reader_skip (&reader, img_description_len))
859     goto error;
860
861   if (!gst_byte_reader_skip (&reader, 4 * 4))
862     goto error;
863
864   if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
865     goto error;
866
867   if (!flacparse->tags)
868     flacparse->tags = gst_tag_list_new ();
869
870   gst_tag_list_add_id3_image (flacparse->tags,
871       data + gst_byte_reader_get_pos (&reader), img_len, img_type);
872
873   if (gst_tag_list_is_empty (flacparse->tags)) {
874     gst_tag_list_free (flacparse->tags);
875     flacparse->tags = NULL;
876   }
877
878   return TRUE;
879
880 error:
881   GST_ERROR_OBJECT (flacparse, "Error reading data");
882   return FALSE;
883 }
884
885 static void
886 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
887 {
888   GValue value = { 0, };
889
890   g_value_init (&value, GST_TYPE_BUFFER);
891   /* copy buffer to avoid problems with circular refcounts */
892   buf = gst_buffer_copy (buf);
893   /* again, for good measure */
894   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
895   gst_value_set_buffer (&value, buf);
896   gst_buffer_unref (buf);
897   gst_value_array_append_value (array_val, &value);
898   g_value_unset (&value);
899 }
900
901 static gboolean
902 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
903 {
904   GstBuffer *vorbiscomment = NULL;
905   GstBuffer *streaminfo = NULL;
906   GstBuffer *marker = NULL;
907   GValue array = { 0, };
908   GstCaps *caps;
909   GList *l;
910
911   caps = gst_caps_new_simple ("audio/x-flac",
912       "channels", G_TYPE_INT, flacparse->channels,
913       "framed", G_TYPE_BOOLEAN, TRUE,
914       "rate", G_TYPE_INT, flacparse->samplerate, NULL);
915
916   if (!flacparse->headers)
917     goto push_headers;
918
919   for (l = flacparse->headers; l; l = l->next) {
920     GstBuffer *header = l->data;
921     const guint8 *data = GST_BUFFER_DATA (header);
922     guint size = GST_BUFFER_SIZE (header);
923
924     GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_IN_CAPS);
925
926     if (size == 4 && memcmp (data, "fLaC", 4) == 0) {
927       marker = header;
928     } else if (size > 1 && (data[0] & 0x7f) == 0) {
929       streaminfo = header;
930     } else if (size > 1 && (data[0] & 0x7f) == 4) {
931       vorbiscomment = header;
932     }
933   }
934
935   if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
936     GST_WARNING_OBJECT (flacparse,
937         "missing header %p %p %p, muxing into container "
938         "formats may be broken", marker, streaminfo, vorbiscomment);
939     goto push_headers;
940   }
941
942   g_value_init (&array, GST_TYPE_ARRAY);
943
944   /* add marker including STREAMINFO header */
945   {
946     GstBuffer *buf;
947     guint16 num;
948
949     /* minus one for the marker that is merged with streaminfo here */
950     num = g_list_length (flacparse->headers) - 1;
951
952     buf = gst_buffer_new_and_alloc (13 + GST_BUFFER_SIZE (streaminfo));
953     GST_BUFFER_DATA (buf)[0] = 0x7f;
954     memcpy (GST_BUFFER_DATA (buf) + 1, "FLAC", 4);
955     GST_BUFFER_DATA (buf)[5] = 0x01;    /* mapping version major */
956     GST_BUFFER_DATA (buf)[6] = 0x00;    /* mapping version minor */
957     GST_BUFFER_DATA (buf)[7] = (num & 0xFF00) >> 8;
958     GST_BUFFER_DATA (buf)[8] = (num & 0x00FF) >> 0;
959     memcpy (GST_BUFFER_DATA (buf) + 9, "fLaC", 4);
960     memcpy (GST_BUFFER_DATA (buf) + 13, GST_BUFFER_DATA (streaminfo),
961         GST_BUFFER_SIZE (streaminfo));
962     _value_array_append_buffer (&array, buf);
963     gst_buffer_unref (buf);
964   }
965
966   /* add VORBISCOMMENT header */
967   _value_array_append_buffer (&array, vorbiscomment);
968
969   /* add other headers, if there are any */
970   for (l = flacparse->headers; l; l = l->next) {
971     if (GST_BUFFER_CAST (l->data) != marker &&
972         GST_BUFFER_CAST (l->data) != streaminfo &&
973         GST_BUFFER_CAST (l->data) != vorbiscomment) {
974       _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
975     }
976   }
977
978   gst_structure_set_value (gst_caps_get_structure (caps, 0),
979       "streamheader", &array);
980   g_value_unset (&array);
981
982 push_headers:
983
984   gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
985   gst_caps_unref (caps);
986
987   /* push header buffers; update caps, so when we push the first buffer the
988    * negotiated caps will change to caps that include the streamheader field */
989   for (l = flacparse->headers; l != NULL; l = l->next) {
990     GstBuffer *buf = GST_BUFFER (l->data);
991     GstFlowReturn ret;
992
993     l->data = NULL;
994     buf = gst_buffer_make_metadata_writable (buf);
995     gst_buffer_set_caps (buf,
996         GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse))));
997
998     ret = gst_base_parse_push_buffer (GST_BASE_PARSE (flacparse), buf);
999     if (ret != GST_FLOW_OK)
1000       return FALSE;
1001   }
1002   g_list_free (flacparse->headers);
1003   flacparse->headers = NULL;
1004
1005   return TRUE;
1006 }
1007
1008 static gboolean
1009 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1010 {
1011   GstBuffer *marker, *streaminfo, *vorbiscomment;
1012   guint8 *data;
1013
1014   marker = gst_buffer_new_and_alloc (4);
1015   memcpy (GST_BUFFER_DATA (marker), "fLaC", 4);
1016   GST_BUFFER_TIMESTAMP (marker) = GST_CLOCK_TIME_NONE;
1017   GST_BUFFER_DURATION (marker) = GST_CLOCK_TIME_NONE;
1018   GST_BUFFER_OFFSET (marker) = 0;
1019   GST_BUFFER_OFFSET_END (marker) = 0;
1020   flacparse->headers = g_list_append (flacparse->headers, marker);
1021
1022   streaminfo = gst_buffer_new_and_alloc (4 + 34);
1023   data = GST_BUFFER_DATA (streaminfo);
1024   memset (data, 0, 4 + 34);
1025
1026   /* metadata block header */
1027   data[0] = 0x00;               /* is_last = 0; type = 0; */
1028   data[1] = 0x00;               /* length = 34; */
1029   data[2] = 0x00;
1030   data[3] = 0x22;
1031
1032   /* streaminfo */
1033
1034   data[4] = (flacparse->block_size >> 8) & 0xff;        /* min blocksize = blocksize; */
1035   data[5] = (flacparse->block_size) & 0xff;
1036   data[6] = (flacparse->block_size >> 8) & 0xff;        /* max blocksize = blocksize; */
1037   data[7] = (flacparse->block_size) & 0xff;
1038
1039   data[8] = 0x00;               /* min framesize = 0; */
1040   data[9] = 0x00;
1041   data[10] = 0x00;
1042   data[11] = 0x00;              /* max framesize = 0; */
1043   data[12] = 0x00;
1044   data[13] = 0x00;
1045
1046   data[14] = (flacparse->samplerate >> 12) & 0xff;
1047   data[15] = (flacparse->samplerate >> 4) & 0xff;
1048   data[16] = (flacparse->samplerate >> 0) & 0xf0;
1049
1050   data[16] |= (flacparse->channels - 1) << 1;
1051
1052   data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1053   data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1054
1055   {
1056     gint64 duration;
1057     GstFormat fmt = GST_FORMAT_TIME;
1058
1059     if (gst_pad_query_peer_duration (GST_BASE_PARSE_SINK_PAD (GST_BASE_PARSE
1060                 (flacparse)), &fmt, &duration) && fmt == GST_FORMAT_TIME) {
1061       duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1062
1063       data[17] |= (duration >> 32) & 0xff;
1064       data[18] |= (duration >> 24) & 0xff;
1065       data[19] |= (duration >> 16) & 0xff;
1066       data[20] |= (duration >> 8) & 0xff;
1067       data[21] |= (duration >> 0) & 0xff;
1068     }
1069   }
1070   /* MD5 = 0; */
1071
1072   GST_BUFFER_TIMESTAMP (streaminfo) = GST_CLOCK_TIME_NONE;
1073   GST_BUFFER_DURATION (streaminfo) = GST_CLOCK_TIME_NONE;
1074   GST_BUFFER_OFFSET (streaminfo) = 0;
1075   GST_BUFFER_OFFSET_END (streaminfo) = 0;
1076   flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1077
1078   /* empty vorbiscomment */
1079   {
1080     GstTagList *taglist = gst_tag_list_new ();
1081     guchar header[4];
1082     guint size;
1083
1084     header[0] = 0x84;           /* is_last = 1; type = 4; */
1085
1086     vorbiscomment =
1087         gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1088         sizeof (header), NULL);
1089     gst_tag_list_free (taglist);
1090
1091     /* Get rid of framing bit */
1092     if (GST_BUFFER_DATA (vorbiscomment)[GST_BUFFER_SIZE (vorbiscomment) -
1093             1] == 1) {
1094       GstBuffer *sub;
1095
1096       sub =
1097           gst_buffer_create_sub (vorbiscomment, 0,
1098           GST_BUFFER_SIZE (vorbiscomment) - 1);
1099       gst_buffer_unref (vorbiscomment);
1100       vorbiscomment = sub;
1101     }
1102
1103     size = GST_BUFFER_SIZE (vorbiscomment) - 4;
1104     GST_BUFFER_DATA (vorbiscomment)[1] = ((size & 0xFF0000) >> 16);
1105     GST_BUFFER_DATA (vorbiscomment)[2] = ((size & 0x00FF00) >> 8);
1106     GST_BUFFER_DATA (vorbiscomment)[3] = (size & 0x0000FF);
1107
1108     GST_BUFFER_TIMESTAMP (vorbiscomment) = GST_CLOCK_TIME_NONE;
1109     GST_BUFFER_DURATION (vorbiscomment) = GST_CLOCK_TIME_NONE;
1110     GST_BUFFER_OFFSET (vorbiscomment) = 0;
1111     GST_BUFFER_OFFSET_END (vorbiscomment) = 0;
1112     flacparse->headers = g_list_append (flacparse->headers, vorbiscomment);
1113   }
1114
1115   return TRUE;
1116 }
1117
1118 static GstFlowReturn
1119 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBuffer * buffer)
1120 {
1121   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1122   const guint8 *data = GST_BUFFER_DATA (buffer);
1123
1124   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1125     GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1126     GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1127     GST_BUFFER_OFFSET (buffer) = 0;
1128     GST_BUFFER_OFFSET_END (buffer) = 0;
1129
1130     /* 32 bits metadata block */
1131     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1132     flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1133
1134     flacparse->headers =
1135         g_list_append (flacparse->headers, gst_buffer_ref (buffer));
1136
1137     return GST_BASE_PARSE_FLOW_DROPPED;
1138   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1139     gboolean is_last = ((data[0] & 0x80) == 0x80);
1140     guint type = (data[0] & 0x7F);
1141
1142     if (type == 127) {
1143       GST_WARNING_OBJECT (flacparse, "Invalid metadata block type");
1144       return GST_BASE_PARSE_FLOW_DROPPED;
1145     }
1146
1147     GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1148
1149     switch (type) {
1150       case 0:                  /* STREAMINFO */
1151         if (!gst_flac_parse_handle_streaminfo (flacparse, buffer))
1152           return GST_FLOW_ERROR;
1153         break;
1154       case 3:                  /* SEEKTABLE */
1155         /* TODO: handle seektables */
1156         break;
1157       case 4:                  /* VORBIS_COMMENT */
1158         if (!gst_flac_parse_handle_vorbiscomment (flacparse, buffer))
1159           return GST_FLOW_ERROR;
1160         break;
1161       case 6:                  /* PICTURE */
1162         if (!gst_flac_parse_handle_picture (flacparse, buffer))
1163           return GST_FLOW_ERROR;
1164         break;
1165       case 1:                  /* PADDING */
1166       case 2:                  /* APPLICATION */
1167       case 5:                  /* CUESHEET */
1168       default:                 /* RESERVED */
1169         break;
1170     }
1171
1172     GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1173     GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1174     GST_BUFFER_OFFSET (buffer) = 0;
1175     GST_BUFFER_OFFSET_END (buffer) = 0;
1176
1177     if (is_last) {
1178       flacparse->headers =
1179           g_list_append (flacparse->headers, gst_buffer_ref (buffer));
1180
1181       if (!gst_flac_parse_handle_headers (flacparse))
1182         return GST_FLOW_ERROR;
1183
1184       /* Minimal size of a frame header */
1185       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1186               flacparse->min_framesize));
1187       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1188
1189       /* DROPPED because we pushed all headers manually already */
1190       return GST_BASE_PARSE_FLOW_DROPPED;
1191     } else {
1192       flacparse->headers =
1193           g_list_append (flacparse->headers, gst_buffer_ref (buffer));
1194       return GST_BASE_PARSE_FLOW_DROPPED;
1195     }
1196   } else {
1197     if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1198       FrameHeaderCheckReturn ret;
1199
1200       flacparse->offset = GST_BUFFER_OFFSET (buffer);
1201       ret =
1202           gst_flac_parse_frame_header_is_valid (flacparse,
1203           GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), TRUE, NULL);
1204       if (ret != FRAME_HEADER_VALID) {
1205         GST_ERROR_OBJECT (flacparse,
1206             "Baseclass didn't provide a complete frame");
1207         return GST_FLOW_ERROR;
1208       }
1209     }
1210
1211     if (flacparse->block_size == 0) {
1212       GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1213       return GST_FLOW_ERROR;
1214     }
1215
1216     if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1217       if (flacparse->blocking_strategy == 1) {
1218         GST_WARNING_OBJECT (flacparse,
1219             "Generating headers for variable blocksize streams not supported");
1220
1221         if (!gst_flac_parse_handle_headers (flacparse))
1222           return GST_FLOW_ERROR;
1223       } else {
1224         GST_DEBUG_OBJECT (flacparse, "Generating headers");
1225
1226         if (!gst_flac_parse_generate_headers (flacparse))
1227           return GST_FLOW_ERROR;
1228
1229         if (!gst_flac_parse_handle_headers (flacparse))
1230           return GST_FLOW_ERROR;
1231       }
1232       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1233     }
1234
1235     /* also cater for oggmux metadata */
1236     if (flacparse->blocking_strategy == 0) {
1237       GST_BUFFER_TIMESTAMP (buffer) =
1238           gst_util_uint64_scale (flacparse->sample_number,
1239           flacparse->block_size * GST_SECOND, flacparse->samplerate);
1240       GST_BUFFER_OFFSET_END (buffer) =
1241           flacparse->sample_number * flacparse->block_size +
1242           flacparse->block_size;
1243     } else {
1244       GST_BUFFER_TIMESTAMP (buffer) =
1245           gst_util_uint64_scale (flacparse->sample_number, GST_SECOND,
1246           flacparse->samplerate);
1247       GST_BUFFER_OFFSET_END (buffer) =
1248           flacparse->sample_number + flacparse->block_size;
1249     }
1250     GST_BUFFER_DURATION (buffer) =
1251         GST_FRAMES_TO_CLOCK_TIME (flacparse->block_size, flacparse->samplerate);
1252     GST_BUFFER_OFFSET (buffer) =
1253         GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
1254
1255     /* Minimal size of a frame header */
1256     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1257             flacparse->min_framesize));
1258
1259     flacparse->offset = -1;
1260     flacparse->blocking_strategy = 0;
1261     flacparse->block_size = 0;
1262     flacparse->sample_number = 0;
1263     return GST_FLOW_OK;
1264   }
1265 }
1266
1267 static gint
1268 gst_flac_parse_get_frame_overhead (GstBaseParse * parse, GstBuffer * buffer)
1269 {
1270   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1271
1272   if (flacparse->state != GST_FLAC_PARSE_STATE_DATA)
1273     return -1;
1274   else
1275     /* To simplify, we just assume that it's a fixed size header and ignore
1276      * subframe headers. The first could lead us to being off by 88 bits and
1277      * the second even less, so the total inaccuracy is negligible. */
1278     return 7;
1279 }
1280
1281 static GstFlowReturn
1282 gst_flac_parse_pre_push_buffer (GstBaseParse * parse, GstBuffer * buf)
1283 {
1284   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1285
1286   /* Push tags */
1287   if (flacparse->tags) {
1288     gst_element_found_tags (GST_ELEMENT (flacparse), flacparse->tags);
1289     flacparse->tags = NULL;
1290   }
1291
1292   return GST_FLOW_OK;
1293 }