audioparsers: adjust to modified baseparse API
[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")
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 GstFlowReturn gst_flac_parse_handle_frame (GstBaseParse * parse,
196     GstBaseParseFrame * frame, gint * skipsize);
197 static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
198     GstBaseParseFrame * frame, gint size);
199 static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
200     GstBaseParseFrame * frame);
201 static gboolean gst_flac_parse_convert (GstBaseParse * parse,
202     GstFormat src_format, gint64 src_value, GstFormat dest_format,
203     gint64 * dest_value);
204 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
205     GstCaps * filter);
206
207 #define gst_flac_parse_parent_class parent_class
208 G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);
209
210 static void
211 gst_flac_parse_class_init (GstFlacParseClass * klass)
212 {
213   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
214   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
215   GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
216
217   GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
218       "Flac parser element");
219
220   gobject_class->finalize = gst_flac_parse_finalize;
221   gobject_class->set_property = gst_flac_parse_set_property;
222   gobject_class->get_property = gst_flac_parse_get_property;
223
224   g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
225       g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
226           "Check the overall checksums of every frame",
227           DEFAULT_CHECK_FRAME_CHECKSUMS,
228           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
229
230   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
231   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
232   baseparse_class->handle_frame =
233       GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
234   baseparse_class->pre_push_frame =
235       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
236   baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
237   baseparse_class->get_sink_caps =
238       GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
239
240   gst_element_class_add_pad_template (element_class,
241       gst_static_pad_template_get (&src_factory));
242   gst_element_class_add_pad_template (element_class,
243       gst_static_pad_template_get (&sink_factory));
244
245   gst_element_class_set_details_simple (element_class, "FLAC audio parser",
246       "Codec/Parser/Audio",
247       "Parses audio with the FLAC lossless audio codec",
248       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
249 }
250
251 static void
252 gst_flac_parse_init (GstFlacParse * flacparse)
253 {
254   flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
255 }
256
257 static void
258 gst_flac_parse_set_property (GObject * object, guint prop_id,
259     const GValue * value, GParamSpec * pspec)
260 {
261   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
262
263   switch (prop_id) {
264     case PROP_CHECK_FRAME_CHECKSUMS:
265       flacparse->check_frame_checksums = g_value_get_boolean (value);
266       break;
267     default:
268       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
269       break;
270   }
271 }
272
273 static void
274 gst_flac_parse_get_property (GObject * object, guint prop_id,
275     GValue * value, GParamSpec * pspec)
276 {
277   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
278
279   switch (prop_id) {
280     case PROP_CHECK_FRAME_CHECKSUMS:
281       g_value_set_boolean (value, flacparse->check_frame_checksums);
282       break;
283     default:
284       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
285       break;
286   }
287 }
288
289 static void
290 gst_flac_parse_finalize (GObject * object)
291 {
292   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
293
294   if (flacparse->tags) {
295     gst_tag_list_free (flacparse->tags);
296     flacparse->tags = NULL;
297   }
298
299   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
300   g_list_free (flacparse->headers);
301   flacparse->headers = NULL;
302
303   G_OBJECT_CLASS (parent_class)->finalize (object);
304 }
305
306 static gboolean
307 gst_flac_parse_start (GstBaseParse * parse)
308 {
309   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
310
311   flacparse->state = GST_FLAC_PARSE_STATE_INIT;
312   flacparse->min_blocksize = 0;
313   flacparse->max_blocksize = 0;
314   flacparse->min_framesize = 0;
315   flacparse->max_framesize = 0;
316
317   flacparse->upstream_length = -1;
318
319   flacparse->samplerate = 0;
320   flacparse->channels = 0;
321   flacparse->bps = 0;
322   flacparse->total_samples = 0;
323
324   flacparse->offset = GST_CLOCK_TIME_NONE;
325   flacparse->blocking_strategy = 0;
326   flacparse->block_size = 0;
327   flacparse->sample_number = 0;
328   flacparse->strategy_checked = FALSE;
329
330   /* "fLaC" marker */
331   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
332
333   /* inform baseclass we can come up with ts, based on counters in packets */
334   gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
335   gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);
336
337   return TRUE;
338 }
339
340 static gboolean
341 gst_flac_parse_stop (GstBaseParse * parse)
342 {
343   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
344
345   if (flacparse->tags) {
346     gst_tag_list_free (flacparse->tags);
347     flacparse->tags = NULL;
348   }
349
350   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
351   g_list_free (flacparse->headers);
352   flacparse->headers = NULL;
353
354   return TRUE;
355 }
356
357 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
358
359 static const guint16 blocksize_table[16] = {
360   0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
361   256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
362   256 << 7,
363 };
364
365 static const guint32 sample_rate_table[16] = {
366   0,
367   88200, 176400, 192000,
368   8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
369   0, 0, 0, 0,
370 };
371
372 typedef enum
373 {
374   FRAME_HEADER_VALID,
375   FRAME_HEADER_INVALID,
376   FRAME_HEADER_MORE_DATA
377 } FrameHeaderCheckReturn;
378
379 static FrameHeaderCheckReturn
380 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
381     const guint8 * data, guint size, gboolean set, guint16 * block_size_ret)
382 {
383   GstBitReader reader = GST_BIT_READER_INIT (data, size);
384   guint8 blocking_strategy;
385   guint16 block_size;
386   guint32 samplerate = 0;
387   guint64 sample_number;
388   guint8 channels, bps;
389   guint8 tmp = 0;
390   guint8 actual_crc, expected_crc = 0;
391
392   /* Skip 14 bit sync code */
393   gst_bit_reader_skip_unchecked (&reader, 14);
394
395   /* Must be 0 */
396   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
397     goto error;
398
399   /* 0 == fixed block size, 1 == variable block size */
400   blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
401   if (flacparse->force_variable_block_size)
402     blocking_strategy = 1;
403
404   /* block size index, calculation of the real blocksize below */
405   block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
406   if (block_size == 0)
407     goto error;
408
409   /* sample rate index, calculation of the real samplerate below */
410   samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
411   if (samplerate == 0x0f)
412     goto error;
413
414   /* channel assignment */
415   channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
416   if (channels < 8) {
417     channels++;
418   } else if (channels <= 10) {
419     channels = 2;
420   } else if (channels > 10) {
421     goto error;
422   }
423   if (flacparse->channels && flacparse->channels != channels)
424     goto error;
425
426   /* bits per sample */
427   bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
428   if (bps == 0x03 || bps == 0x07) {
429     goto error;
430   } else if (bps == 0 && flacparse->bps == 0) {
431     goto need_streaminfo;
432   }
433   bps = sample_size_table[bps];
434   if (flacparse->bps && bps != flacparse->bps)
435     goto error;
436
437   /* reserved, must be 0 */
438   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
439     goto error;
440
441   /* read "utf8" encoded sample/frame number */
442   {
443     gint len = 0;
444
445     len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
446
447     /* This is slightly faster than a loop */
448     if (!(len & 0x80)) {
449       sample_number = len;
450       len = 0;
451     } else if ((len & 0xc0) && !(len & 0x20)) {
452       sample_number = len & 0x1f;
453       len = 1;
454     } else if ((len & 0xe0) && !(len & 0x10)) {
455       sample_number = len & 0x0f;
456       len = 2;
457     } else if ((len & 0xf0) && !(len & 0x08)) {
458       sample_number = len & 0x07;
459       len = 3;
460     } else if ((len & 0xf8) && !(len & 0x04)) {
461       sample_number = len & 0x03;
462       len = 4;
463     } else if ((len & 0xfc) && !(len & 0x02)) {
464       sample_number = len & 0x01;
465       len = 5;
466     } else if ((len & 0xfe) && !(len & 0x01)) {
467       sample_number = len & 0x0;
468       len = 6;
469     } else {
470       goto error;
471     }
472
473     if ((blocking_strategy == 0 && len > 5) ||
474         (blocking_strategy == 1 && len > 6))
475       goto error;
476
477     while (len > 0) {
478       if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
479         goto need_more_data;
480
481       if ((tmp & 0xc0) != 0x80)
482         goto error;
483
484       sample_number <<= 6;
485       sample_number |= (tmp & 0x3f);
486       len--;
487     }
488   }
489
490   /* calculate real blocksize from the blocksize index */
491   if (block_size == 0) {
492     goto error;
493   } else if (block_size == 6) {
494     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
495       goto need_more_data;
496     block_size++;
497   } else if (block_size == 7) {
498     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
499       goto need_more_data;
500     block_size++;
501   } else {
502     block_size = blocksize_table[block_size];
503   }
504
505   /* calculate the real samplerate from the samplerate index */
506   if (samplerate == 0 && flacparse->samplerate == 0) {
507     goto need_streaminfo;
508   } else if (samplerate < 12) {
509     samplerate = sample_rate_table[samplerate];
510   } else if (samplerate == 12) {
511     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
512       goto need_more_data;
513     samplerate *= 1000;
514   } else if (samplerate == 13) {
515     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
516       goto need_more_data;
517   } else if (samplerate == 14) {
518     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
519       goto need_more_data;
520     samplerate *= 10;
521   }
522
523   if (flacparse->samplerate && flacparse->samplerate != samplerate)
524     goto error;
525
526   /* check crc-8 for the header */
527   if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
528     goto need_more_data;
529
530   actual_crc =
531       gst_flac_calculate_crc8 (data,
532       (gst_bit_reader_get_pos (&reader) / 8) - 1);
533   if (actual_crc != expected_crc)
534     goto error;
535
536   /* Sanity check sample number against blocking strategy, as it seems
537      some files claim fixed block size but supply sample numbers,
538      rather than block numbers. */
539   if (blocking_strategy == 0 && flacparse->block_size != 0) {
540     if (!flacparse->strategy_checked) {
541       if (block_size == sample_number) {
542         GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
543             "but seems to be lying: assuming variable block size");
544         flacparse->force_variable_block_size = TRUE;
545         blocking_strategy = 1;
546       }
547       flacparse->strategy_checked = TRUE;
548     }
549   }
550
551   /* 
552      The FLAC format documentation says:
553      The "blocking strategy" bit determines how to calculate the sample number
554      of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
555      frame header encodes the frame number as above, and the frame's starting
556      sample number will be the frame number times the blocksize. If it is 1
557      (variable-blocksize), the frame header encodes the frame's starting
558      sample number itself. (In the case of a fixed-blocksize stream, only the
559      last block may be shorter than the stream blocksize; its starting sample
560      number will be calculated as the frame number times the previous frame's
561      blocksize, or zero if it is the first frame). 
562
563      Therefore, when in fixed block size mode, we only update the block size
564      the first time, then reuse that block size for subsequent calls.
565      This will also fix a timestamp problem with the last block's timestamp
566      being miscalculated by scaling the block number by a "wrong" block size.
567    */
568   if (blocking_strategy == 0) {
569     if (flacparse->block_size != 0) {
570       /* after first block */
571       if (flacparse->block_size != block_size) {
572         /* TODO: can we know we're on the last frame, to avoid warning ? */
573         GST_WARNING_OBJECT (flacparse, "Block size is not constant");
574         block_size = flacparse->block_size;
575       }
576     }
577   }
578
579   if (set) {
580     flacparse->block_size = block_size;
581     if (!flacparse->samplerate)
582       flacparse->samplerate = samplerate;
583     if (!flacparse->bps)
584       flacparse->bps = bps;
585     if (!flacparse->blocking_strategy)
586       flacparse->blocking_strategy = blocking_strategy;
587     if (!flacparse->channels)
588       flacparse->channels = channels;
589     if (!flacparse->sample_number)
590       flacparse->sample_number = sample_number;
591
592     GST_DEBUG_OBJECT (flacparse,
593         "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
594         "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
595         flacparse->block_size, flacparse->sample_number);
596   }
597
598   if (block_size_ret)
599     *block_size_ret = block_size;
600
601   return FRAME_HEADER_VALID;
602
603 need_streaminfo:
604   GST_ERROR_OBJECT (flacparse, "Need STREAMINFO");
605   return FRAME_HEADER_INVALID;
606 error:
607   return FRAME_HEADER_INVALID;
608
609 need_more_data:
610   return FRAME_HEADER_MORE_DATA;
611 }
612
613 static gboolean
614 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
615     GstBaseParseFrame * frame, guint * ret)
616 {
617   GstBuffer *buffer;
618   GstMapInfo map;
619   guint max, remaining;
620   guint i, search_start, search_end;
621   FrameHeaderCheckReturn header_ret;
622   guint16 block_size;
623   gboolean result = FALSE;
624
625   buffer = frame->buffer;
626   gst_buffer_map (buffer, &map, GST_MAP_READ);
627
628   if (map.size < flacparse->min_framesize)
629     goto need_more;
630
631   header_ret =
632       gst_flac_parse_frame_header_is_valid (flacparse, map.data, map.size, TRUE,
633       &block_size);
634   if (header_ret == FRAME_HEADER_INVALID) {
635     *ret = 0;
636     goto cleanup;
637   }
638   if (header_ret == FRAME_HEADER_MORE_DATA)
639     goto need_more;
640
641   /* mind unknown framesize */
642   search_start = MAX (2, flacparse->min_framesize);
643   if (flacparse->max_framesize)
644     search_end = MIN (map.size, flacparse->max_framesize + 9 + 2);
645   else
646     search_end = map.size;
647   search_end -= 2;
648
649   remaining = map.size;
650
651   for (i = search_start; i < search_end; i++, remaining--) {
652     if ((GST_READ_UINT16_BE (map.data + i) & 0xfffe) == 0xfff8) {
653       header_ret =
654           gst_flac_parse_frame_header_is_valid (flacparse, map.data + i,
655           remaining, FALSE, NULL);
656       if (header_ret == FRAME_HEADER_VALID) {
657         if (flacparse->check_frame_checksums) {
658           guint16 actual_crc = gst_flac_calculate_crc16 (map.data, i - 2);
659           guint16 expected_crc = GST_READ_UINT16_BE (map.data + i - 2);
660
661           if (actual_crc != expected_crc)
662             continue;
663         }
664         *ret = i;
665         flacparse->block_size = block_size;
666         result = TRUE;
667         goto cleanup;
668       } else if (header_ret == FRAME_HEADER_MORE_DATA) {
669         goto need_more;
670       }
671     }
672   }
673
674   /* For the last frame output everything to the end */
675   if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
676     if (flacparse->check_frame_checksums) {
677       guint16 actual_crc = gst_flac_calculate_crc16 (map.data, map.size - 2);
678       guint16 expected_crc = GST_READ_UINT16_BE (map.data + map.size - 2);
679
680       if (actual_crc == expected_crc) {
681         *ret = map.size;
682         flacparse->block_size = block_size;
683         result = TRUE;
684         goto cleanup;
685       }
686     } else {
687       *ret = map.size;
688       flacparse->block_size = block_size;
689       result = TRUE;
690       goto cleanup;
691     }
692   }
693
694 need_more:
695   max = flacparse->max_framesize + 16;
696   if (max == 16)
697     max = 1 << 24;
698   *ret = MIN (map.size + 4096, max);
699   result = TRUE;
700
701 cleanup:
702   gst_buffer_unmap (buffer, &map);
703   return result;
704 }
705
706 static GstFlowReturn
707 gst_flac_parse_handle_frame (GstBaseParse * parse,
708     GstBaseParseFrame * frame, gint * skipsize)
709 {
710   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
711   GstBuffer *buffer = frame->buffer;
712   GstMapInfo map;
713   gboolean result = TRUE;
714   GstFlowReturn ret = GST_FLOW_OK;
715   guint framesize;
716
717   gst_buffer_map (buffer, &map, GST_MAP_READ);
718
719   *skipsize = 1;
720
721   if (G_UNLIKELY (map.size < 4)) {
722     result = FALSE;
723     goto cleanup;
724   }
725
726   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
727     if (memcmp (map.data, "fLaC", 4) == 0) {
728       GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
729       framesize = 4;
730       goto cleanup;
731     }
732     if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
733       GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
734       /* Minimal size of a frame header */
735       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
736       flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
737       *skipsize = 0;
738       result = FALSE;
739       goto cleanup;
740     }
741     GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
742     result = FALSE;
743     goto cleanup;
744   }
745
746   if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
747     guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
748
749     GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
750     framesize = size;
751     goto cleanup;
752   }
753
754   if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
755     gboolean ret;
756     guint next;
757
758     flacparse->offset = GST_BUFFER_OFFSET (buffer);
759     flacparse->blocking_strategy = 0;
760     flacparse->sample_number = 0;
761
762     GST_DEBUG_OBJECT (flacparse, "Found sync code");
763     ret = gst_flac_parse_frame_is_valid (flacparse, frame, &next);
764     if (ret) {
765       framesize = next;
766       goto cleanup;
767     } else {
768       /* If we're at EOS and the frame was not valid, drop it! */
769       if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
770         GST_WARNING_OBJECT (flacparse, "EOS");
771         result = FALSE;
772         goto cleanup;
773       }
774
775       if (next == 0) {
776       } else if (next > map.size) {
777         GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
778         *skipsize = 0;
779         gst_base_parse_set_min_frame_size (parse, next);
780         result = FALSE;
781         goto cleanup;
782       } else {
783         GST_ERROR_OBJECT (flacparse,
784             "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
785         result = FALSE;
786         goto cleanup;
787       }
788     }
789   } else {
790     GstByteReader reader;
791     gint off;
792
793     gst_byte_reader_init (&reader, map.data, map.size);
794     off =
795         gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
796         0, map.size);
797
798     if (off > 0) {
799       GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
800       *skipsize = off;
801       result = FALSE;
802       goto cleanup;
803     } else {
804       GST_DEBUG_OBJECT (flacparse, "Sync code not found");
805       *skipsize = map.size - 3;
806       result = FALSE;
807       goto cleanup;
808     }
809   }
810
811   result = FALSE;
812
813 cleanup:
814   gst_buffer_unmap (buffer, &map);
815
816   if (result)
817     *skipsize = 0;
818
819   if (result && framesize <= map.size) {
820     ret = gst_flac_parse_parse_frame (parse, frame, framesize);
821     if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
822       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
823       ret = GST_FLOW_OK;
824     }
825     if (ret == GST_FLOW_OK)
826       ret = gst_base_parse_finish_frame (parse, frame, framesize);
827   }
828
829   return ret;
830 }
831
832 static gboolean
833 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
834 {
835   GstBitReader reader;
836   GstMapInfo map;
837
838   gst_buffer_map (buffer, &map, GST_MAP_READ);
839   gst_bit_reader_init (&reader, map.data, map.size);
840
841   if (map.size != 4 + 34) {
842     GST_ERROR_OBJECT (flacparse,
843         "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
844     goto failure;
845   }
846
847   /* Skip metadata block header */
848   gst_bit_reader_skip (&reader, 32);
849
850   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
851     goto error;
852   if (flacparse->min_blocksize < 16) {
853     GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
854         flacparse->min_blocksize);
855   }
856
857   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
858     goto error;
859   if (flacparse->max_blocksize < 16) {
860     GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
861         flacparse->max_blocksize);
862   }
863
864   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
865     goto error;
866   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
867     goto error;
868
869   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
870     goto error;
871   if (flacparse->samplerate == 0) {
872     GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
873     goto failure;
874   }
875
876   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
877     goto error;
878   flacparse->channels++;
879   if (flacparse->channels > 8) {
880     GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
881         flacparse->channels);
882     goto failure;
883   }
884
885   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
886     goto error;
887   flacparse->bps++;
888
889   if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
890     goto error;
891   if (flacparse->total_samples) {
892     gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
893         GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
894   }
895
896   gst_buffer_unmap (buffer, &map);
897
898   GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
899       "\tmin/max blocksize: %u/%u,\n"
900       "\tmin/max framesize: %u/%u,\n"
901       "\tsamplerate: %u,\n"
902       "\tchannels: %u,\n"
903       "\tbits per sample: %u,\n"
904       "\ttotal samples: %" G_GUINT64_FORMAT,
905       flacparse->min_blocksize, flacparse->max_blocksize,
906       flacparse->min_framesize, flacparse->max_framesize,
907       flacparse->samplerate,
908       flacparse->channels, flacparse->bps, flacparse->total_samples);
909
910   return TRUE;
911
912 error:
913   GST_ERROR_OBJECT (flacparse, "Failed to read data");
914 failure:
915   gst_buffer_unmap (buffer, &map);
916   return FALSE;
917 }
918
919 static gboolean
920 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
921     GstBuffer * buffer)
922 {
923   GstMapInfo map;
924
925   gst_buffer_map (buffer, &map, GST_MAP_READ);
926
927   flacparse->tags =
928       gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
929   gst_buffer_unmap (buffer, &map);
930
931   if (flacparse->tags == NULL) {
932     GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
933   } else if (gst_tag_list_is_empty (flacparse->tags)) {
934     gst_tag_list_free (flacparse->tags);
935     flacparse->tags = NULL;
936   }
937
938   return TRUE;
939 }
940
941 static gboolean
942 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
943 {
944   GstByteReader reader;
945   GstMapInfo map;
946   guint32 img_len = 0, img_type = 0;
947   guint32 img_mimetype_len = 0, img_description_len = 0;
948
949   gst_buffer_map (buffer, &map, GST_MAP_READ);
950   gst_byte_reader_init (&reader, map.data, map.size);
951
952   if (!gst_byte_reader_skip (&reader, 4))
953     goto error;
954
955   if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
956     goto error;
957
958   if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
959     goto error;
960   if (!gst_byte_reader_skip (&reader, img_mimetype_len))
961     goto error;
962
963   if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
964     goto error;
965   if (!gst_byte_reader_skip (&reader, img_description_len))
966     goto error;
967
968   if (!gst_byte_reader_skip (&reader, 4 * 4))
969     goto error;
970
971   if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
972     goto error;
973
974   if (!flacparse->tags)
975     flacparse->tags = gst_tag_list_new_empty ();
976
977   gst_tag_list_add_id3_image (flacparse->tags,
978       map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
979
980   if (gst_tag_list_is_empty (flacparse->tags)) {
981     gst_tag_list_free (flacparse->tags);
982     flacparse->tags = NULL;
983   }
984
985   gst_buffer_unmap (buffer, &map);
986   return TRUE;
987
988 error:
989   GST_ERROR_OBJECT (flacparse, "Error reading data");
990   gst_buffer_unmap (buffer, &map);
991   return FALSE;
992 }
993
994 static gboolean
995 gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
996 {
997
998   GST_DEBUG_OBJECT (flacparse, "storing seektable");
999   /* only store for now;
1000    * offset of the first frame is needed to get real info */
1001   flacparse->seektable = gst_buffer_ref (buffer);
1002
1003   return TRUE;
1004 }
1005
1006 static void
1007 gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
1008 {
1009   GstByteReader br;
1010   gint64 offset = 0, samples = 0;
1011   GstMapInfo map;
1012
1013   GST_DEBUG_OBJECT (flacparse,
1014       "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);
1015
1016   if (boffset <= 0)
1017     goto exit;
1018
1019   gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
1020   gst_byte_reader_init (&br, map.data, map.size);
1021
1022   /* skip header */
1023   if (!gst_byte_reader_skip (&br, 4))
1024     goto done;
1025
1026   /* seekpoints */
1027   while (gst_byte_reader_get_remaining (&br)) {
1028     if (!gst_byte_reader_get_int64_be (&br, &samples))
1029       break;
1030     if (!gst_byte_reader_get_int64_be (&br, &offset))
1031       break;
1032     if (!gst_byte_reader_skip (&br, 2))
1033       break;
1034
1035     GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
1036         G_GINT64_FORMAT, samples, offset);
1037
1038     /* sanity check */
1039     if (G_LIKELY (offset > 0 && samples > 0)) {
1040       gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
1041           boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
1042               flacparse->samplerate), TRUE, FALSE);
1043     }
1044   }
1045
1046 done:
1047   gst_buffer_unmap (flacparse->seektable, &map);
1048 exit:
1049   gst_buffer_unref (flacparse->seektable);
1050   flacparse->seektable = NULL;
1051 }
1052
1053 static void
1054 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
1055 {
1056   GValue value = { 0, };
1057
1058   g_value_init (&value, GST_TYPE_BUFFER);
1059   /* copy buffer to avoid problems with circular refcounts */
1060   buf = gst_buffer_copy (buf);
1061   /* again, for good measure */
1062   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1063   gst_value_set_buffer (&value, buf);
1064   gst_buffer_unref (buf);
1065   gst_value_array_append_value (array_val, &value);
1066   g_value_unset (&value);
1067 }
1068
1069 static gboolean
1070 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
1071 {
1072   GstBuffer *vorbiscomment = NULL;
1073   GstBuffer *streaminfo = NULL;
1074   GstBuffer *marker = NULL;
1075   GValue array = { 0, };
1076   GstCaps *caps;
1077   GList *l;
1078   gboolean res = TRUE;
1079
1080   caps = gst_caps_new_simple ("audio/x-flac",
1081       "channels", G_TYPE_INT, flacparse->channels,
1082       "framed", G_TYPE_BOOLEAN, TRUE,
1083       "rate", G_TYPE_INT, flacparse->samplerate, NULL);
1084
1085   if (!flacparse->headers)
1086     goto push_headers;
1087
1088   for (l = flacparse->headers; l; l = l->next) {
1089     GstBuffer *header = l->data;
1090     GstMapInfo map;
1091
1092     gst_buffer_map (header, &map, GST_MAP_READ);
1093
1094     GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);
1095
1096     if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
1097       marker = header;
1098     } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
1099       streaminfo = header;
1100     } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
1101       vorbiscomment = header;
1102     }
1103
1104     gst_buffer_unmap (header, &map);
1105   }
1106
1107   if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
1108     GST_WARNING_OBJECT (flacparse,
1109         "missing header %p %p %p, muxing into container "
1110         "formats may be broken", marker, streaminfo, vorbiscomment);
1111     goto push_headers;
1112   }
1113
1114   g_value_init (&array, GST_TYPE_ARRAY);
1115
1116   /* add marker including STREAMINFO header */
1117   {
1118     GstBuffer *buf;
1119     guint16 num;
1120     GstMapInfo sinfomap, writemap;
1121
1122     gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);
1123
1124     /* minus one for the marker that is merged with streaminfo here */
1125     num = g_list_length (flacparse->headers) - 1;
1126
1127     buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
1128     gst_buffer_map (buf, &writemap, GST_MAP_WRITE);
1129
1130     writemap.data[0] = 0x7f;
1131     memcpy (writemap.data + 1, "FLAC", 4);
1132     writemap.data[5] = 0x01;    /* mapping version major */
1133     writemap.data[6] = 0x00;    /* mapping version minor */
1134     writemap.data[7] = (num & 0xFF00) >> 8;
1135     writemap.data[8] = (num & 0x00FF) >> 0;
1136     memcpy (writemap.data + 9, "fLaC", 4);
1137     memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
1138     _value_array_append_buffer (&array, buf);
1139
1140     gst_buffer_unmap (streaminfo, &sinfomap);
1141     gst_buffer_unmap (buf, &writemap);
1142     gst_buffer_unref (buf);
1143   }
1144
1145   /* add VORBISCOMMENT header */
1146   _value_array_append_buffer (&array, vorbiscomment);
1147
1148   /* add other headers, if there are any */
1149   for (l = flacparse->headers; l; l = l->next) {
1150     if (GST_BUFFER_CAST (l->data) != marker &&
1151         GST_BUFFER_CAST (l->data) != streaminfo &&
1152         GST_BUFFER_CAST (l->data) != vorbiscomment) {
1153       _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
1154     }
1155   }
1156
1157   gst_structure_set_value (gst_caps_get_structure (caps, 0),
1158       "streamheader", &array);
1159   g_value_unset (&array);
1160
1161 push_headers:
1162
1163   gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
1164   gst_caps_unref (caps);
1165
1166   /* push header buffers; update caps, so when we push the first buffer the
1167    * negotiated caps will change to caps that include the streamheader field */
1168   while (flacparse->headers) {
1169     GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
1170     GstFlowReturn ret;
1171     GstBaseParseFrame frame;
1172
1173     flacparse->headers =
1174         g_list_delete_link (flacparse->headers, flacparse->headers);
1175     buf = gst_buffer_make_writable (buf);
1176
1177     /* init, set and give away frame */
1178     gst_base_parse_frame_init (&frame);
1179     frame.buffer = buf;
1180     frame.overhead = -1;
1181     ret = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
1182     if (ret != GST_FLOW_OK) {
1183       res = FALSE;
1184       break;
1185     }
1186     gst_base_parse_frame_free (&frame);
1187   }
1188   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
1189   g_list_free (flacparse->headers);
1190   flacparse->headers = NULL;
1191
1192   return res;
1193 }
1194
1195 static gboolean
1196 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1197 {
1198   GstBuffer *marker, *streaminfo, *vorbiscomment;
1199   GstMapInfo map;
1200
1201   marker = gst_buffer_new_and_alloc (4);
1202   gst_buffer_map (marker, &map, GST_MAP_WRITE);
1203   memcpy (map.data, "fLaC", 4);
1204   gst_buffer_unmap (marker, &map);
1205   GST_BUFFER_TIMESTAMP (marker) = GST_CLOCK_TIME_NONE;
1206   GST_BUFFER_DURATION (marker) = GST_CLOCK_TIME_NONE;
1207   GST_BUFFER_OFFSET (marker) = 0;
1208   GST_BUFFER_OFFSET_END (marker) = 0;
1209   flacparse->headers = g_list_append (flacparse->headers, marker);
1210
1211   streaminfo = gst_buffer_new_and_alloc (4 + 34);
1212   gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
1213   memset (map.data, 0, 4 + 34);
1214
1215   /* metadata block header */
1216   map.data[0] = 0x00;           /* is_last = 0; type = 0; */
1217   map.data[1] = 0x00;           /* length = 34; */
1218   map.data[2] = 0x00;
1219   map.data[3] = 0x22;
1220
1221   /* streaminfo */
1222
1223   map.data[4] = (flacparse->block_size >> 8) & 0xff;    /* min blocksize = blocksize; */
1224   map.data[5] = (flacparse->block_size) & 0xff;
1225   map.data[6] = (flacparse->block_size >> 8) & 0xff;    /* max blocksize = blocksize; */
1226   map.data[7] = (flacparse->block_size) & 0xff;
1227
1228   map.data[8] = 0x00;           /* min framesize = 0; */
1229   map.data[9] = 0x00;
1230   map.data[10] = 0x00;
1231   map.data[11] = 0x00;          /* max framesize = 0; */
1232   map.data[12] = 0x00;
1233   map.data[13] = 0x00;
1234
1235   map.data[14] = (flacparse->samplerate >> 12) & 0xff;
1236   map.data[15] = (flacparse->samplerate >> 4) & 0xff;
1237   map.data[16] = (flacparse->samplerate >> 0) & 0xf0;
1238
1239   map.data[16] |= (flacparse->channels - 1) << 1;
1240
1241   map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1242   map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1243
1244   {
1245     gint64 duration;
1246
1247     if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
1248             GST_FORMAT_TIME, &duration)) {
1249       duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1250
1251       map.data[17] |= (duration >> 32) & 0xff;
1252       map.data[18] |= (duration >> 24) & 0xff;
1253       map.data[19] |= (duration >> 16) & 0xff;
1254       map.data[20] |= (duration >> 8) & 0xff;
1255       map.data[21] |= (duration >> 0) & 0xff;
1256     }
1257   }
1258   /* MD5 = 0; */
1259
1260   gst_buffer_unmap (streaminfo, &map);
1261   GST_BUFFER_TIMESTAMP (streaminfo) = GST_CLOCK_TIME_NONE;
1262   GST_BUFFER_DURATION (streaminfo) = GST_CLOCK_TIME_NONE;
1263   GST_BUFFER_OFFSET (streaminfo) = 0;
1264   GST_BUFFER_OFFSET_END (streaminfo) = 0;
1265   flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1266
1267   /* empty vorbiscomment */
1268   {
1269     GstTagList *taglist = gst_tag_list_new_empty ();
1270     guchar header[4];
1271     guint size;
1272
1273     header[0] = 0x84;           /* is_last = 1; type = 4; */
1274
1275     vorbiscomment =
1276         gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1277         sizeof (header), NULL);
1278     gst_tag_list_free (taglist);
1279
1280     gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1281
1282     /* Get rid of framing bit */
1283     if (map.data[map.size - 1] == 1) {
1284       GstBuffer *sub;
1285
1286       sub =
1287           gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
1288           map.size - 1);
1289       gst_buffer_unmap (vorbiscomment, &map);
1290       gst_buffer_unref (vorbiscomment);
1291       vorbiscomment = sub;
1292       gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1293     }
1294
1295     size = map.size - 4;
1296     map.data[1] = ((size & 0xFF0000) >> 16);
1297     map.data[2] = ((size & 0x00FF00) >> 8);
1298     map.data[3] = (size & 0x0000FF);
1299     gst_buffer_unmap (vorbiscomment, &map);
1300
1301     GST_BUFFER_TIMESTAMP (vorbiscomment) = GST_CLOCK_TIME_NONE;
1302     GST_BUFFER_DURATION (vorbiscomment) = GST_CLOCK_TIME_NONE;
1303     GST_BUFFER_OFFSET (vorbiscomment) = 0;
1304     GST_BUFFER_OFFSET_END (vorbiscomment) = 0;
1305     flacparse->headers = g_list_append (flacparse->headers, vorbiscomment);
1306   }
1307
1308   return TRUE;
1309 }
1310
1311 static GstFlowReturn
1312 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
1313     gint size)
1314 {
1315   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1316   GstBuffer *buffer = frame->buffer, *sbuffer;
1317   GstMapInfo map;
1318   GstFlowReturn res = GST_FLOW_ERROR;
1319
1320   gst_buffer_map (buffer, &map, GST_MAP_READ);
1321
1322   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1323     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1324     GST_BUFFER_TIMESTAMP (sbuffer) = GST_CLOCK_TIME_NONE;
1325     GST_BUFFER_DURATION (sbuffer) = GST_CLOCK_TIME_NONE;
1326     GST_BUFFER_OFFSET (sbuffer) = 0;
1327     GST_BUFFER_OFFSET_END (sbuffer) = 0;
1328
1329     /* 32 bits metadata block */
1330     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1331     flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1332
1333     flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1334
1335     res = GST_BASE_PARSE_FLOW_DROPPED;
1336   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1337     gboolean is_last = ((map.data[0] & 0x80) == 0x80);
1338     guint type = (map.data[0] & 0x7F);
1339
1340     if (type == 127) {
1341       GST_WARNING_OBJECT (flacparse, "Invalid metadata block type");
1342       res = GST_BASE_PARSE_FLOW_DROPPED;
1343       goto cleanup;
1344     }
1345
1346     GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1347
1348     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1349
1350     switch (type) {
1351       case 0:                  /* STREAMINFO */
1352         if (!gst_flac_parse_handle_streaminfo (flacparse, sbuffer))
1353           goto cleanup;
1354         break;
1355       case 3:                  /* SEEKTABLE */
1356         if (!gst_flac_parse_handle_seektable (flacparse, sbuffer))
1357           goto cleanup;
1358         break;
1359       case 4:                  /* VORBIS_COMMENT */
1360         if (!gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer))
1361           goto cleanup;
1362         break;
1363       case 6:                  /* PICTURE */
1364         if (!gst_flac_parse_handle_picture (flacparse, sbuffer))
1365           goto cleanup;
1366         break;
1367       case 1:                  /* PADDING */
1368       case 2:                  /* APPLICATION */
1369       case 5:                  /* CUESHEET */
1370       default:                 /* RESERVED */
1371         break;
1372     }
1373
1374     GST_BUFFER_TIMESTAMP (sbuffer) = GST_CLOCK_TIME_NONE;
1375     GST_BUFFER_DURATION (sbuffer) = GST_CLOCK_TIME_NONE;
1376     GST_BUFFER_OFFSET (sbuffer) = 0;
1377     GST_BUFFER_OFFSET_END (sbuffer) = 0;
1378
1379     flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1380
1381     if (is_last) {
1382       if (!gst_flac_parse_handle_headers (flacparse))
1383         goto cleanup;
1384
1385       /* Minimal size of a frame header */
1386       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1387               flacparse->min_framesize));
1388       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1389     }
1390
1391     /* DROPPED because we pushed already or will push all headers manually */
1392     res = GST_BASE_PARSE_FLOW_DROPPED;
1393   } else {
1394     if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1395       FrameHeaderCheckReturn ret;
1396
1397       flacparse->offset = GST_BUFFER_OFFSET (buffer);
1398       ret =
1399           gst_flac_parse_frame_header_is_valid (flacparse,
1400           map.data, map.size, TRUE, NULL);
1401       if (ret != FRAME_HEADER_VALID) {
1402         GST_ERROR_OBJECT (flacparse,
1403             "Baseclass didn't provide a complete frame");
1404         goto cleanup;
1405       }
1406     }
1407
1408     if (flacparse->block_size == 0) {
1409       GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1410       goto cleanup;
1411     }
1412
1413     if (flacparse->seektable)
1414       gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));
1415
1416     if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1417       if (flacparse->blocking_strategy == 1) {
1418         GST_WARNING_OBJECT (flacparse,
1419             "Generating headers for variable blocksize streams not supported");
1420
1421         if (!gst_flac_parse_handle_headers (flacparse))
1422           goto cleanup;
1423       } else {
1424         GST_DEBUG_OBJECT (flacparse, "Generating headers");
1425
1426         if (!gst_flac_parse_generate_headers (flacparse))
1427           goto cleanup;
1428
1429         if (!gst_flac_parse_handle_headers (flacparse))
1430           goto cleanup;
1431       }
1432       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1433     }
1434
1435     /* also cater for oggmux metadata */
1436     if (flacparse->blocking_strategy == 0) {
1437       GST_BUFFER_TIMESTAMP (buffer) =
1438           gst_util_uint64_scale (flacparse->sample_number,
1439           flacparse->block_size * GST_SECOND, flacparse->samplerate);
1440       GST_BUFFER_OFFSET_END (buffer) =
1441           flacparse->sample_number * flacparse->block_size +
1442           flacparse->block_size;
1443     } else {
1444       GST_BUFFER_TIMESTAMP (buffer) =
1445           gst_util_uint64_scale (flacparse->sample_number, GST_SECOND,
1446           flacparse->samplerate);
1447       GST_BUFFER_OFFSET_END (buffer) =
1448           flacparse->sample_number + flacparse->block_size;
1449     }
1450     GST_BUFFER_OFFSET (buffer) =
1451         gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
1452         flacparse->samplerate);
1453     GST_BUFFER_DURATION (buffer) =
1454         GST_BUFFER_OFFSET (buffer) - GST_BUFFER_TIMESTAMP (buffer);
1455
1456     /* To simplify, we just assume that it's a fixed size header and ignore
1457      * subframe headers. The first could lead us to being off by 88 bits and
1458      * the second even less, so the total inaccuracy is negligible. */
1459     frame->overhead = 7;
1460
1461     /* Minimal size of a frame header */
1462     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1463             flacparse->min_framesize));
1464
1465     flacparse->offset = -1;
1466     flacparse->blocking_strategy = 0;
1467     flacparse->sample_number = 0;
1468     res = GST_FLOW_OK;
1469   }
1470
1471 cleanup:
1472   gst_buffer_unmap (buffer, &map);
1473
1474   return res;
1475 }
1476
1477 static GstFlowReturn
1478 gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1479 {
1480   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1481
1482   /* Push tags */
1483   if (flacparse->tags) {
1484     gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
1485         gst_event_new_tag (flacparse->tags));
1486     flacparse->tags = NULL;
1487   }
1488
1489   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1490
1491   return GST_FLOW_OK;
1492 }
1493
1494 static gboolean
1495 gst_flac_parse_convert (GstBaseParse * parse,
1496     GstFormat src_format, gint64 src_value, GstFormat dest_format,
1497     gint64 * dest_value)
1498 {
1499   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1500
1501   if (flacparse->samplerate > 0) {
1502     if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1503       if (src_value != -1)
1504         *dest_value =
1505             gst_util_uint64_scale (src_value, GST_SECOND,
1506             flacparse->samplerate);
1507       else
1508         *dest_value = -1;
1509       return TRUE;
1510     } else if (src_format == GST_FORMAT_TIME &&
1511         dest_format == GST_FORMAT_DEFAULT) {
1512       if (src_value != -1)
1513         *dest_value =
1514             gst_util_uint64_scale (src_value, flacparse->samplerate,
1515             GST_SECOND);
1516       else
1517         *dest_value = -1;
1518       return TRUE;
1519     }
1520   }
1521
1522   return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
1523       src_value, dest_format, dest_value);
1524 }
1525
1526 static GstCaps *
1527 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
1528 {
1529   GstCaps *peercaps;
1530   GstCaps *res;
1531
1532   /* FIXME: handle filter caps */
1533
1534   peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
1535   if (peercaps) {
1536     guint i, n;
1537
1538     /* Remove the framed field */
1539     peercaps = gst_caps_make_writable (peercaps);
1540     n = gst_caps_get_size (peercaps);
1541     for (i = 0; i < n; i++) {
1542       GstStructure *s = gst_caps_get_structure (peercaps, i);
1543
1544       gst_structure_remove_field (s, "framed");
1545     }
1546
1547     res =
1548         gst_caps_intersect_full (peercaps,
1549         gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
1550         GST_CAPS_INTERSECT_FIRST);
1551     gst_caps_unref (peercaps);
1552   } else {
1553     res =
1554         gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD
1555             (parse)));
1556   }
1557
1558   return res;
1559 }