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