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