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