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