aacparse: Reject raw AAC if no codec_data is found in the caps
[platform/upstream/gst-plugins-good.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., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, 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-1.0 -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 #include <gst/base/base.h>
62 #include <gst/pbutils/pbutils.h>
63
64 GST_DEBUG_CATEGORY_STATIC (flacparse_debug);
65 #define GST_CAT_DEFAULT flacparse_debug
66
67 /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
68 static const guint8 crc8_table[256] = {
69   0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
70   0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
71   0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
72   0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
73   0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
74   0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
75   0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
76   0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
77   0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
78   0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
79   0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
80   0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
81   0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
82   0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
83   0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
84   0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
85   0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
86   0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
87   0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
88   0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
89   0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
90   0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
91   0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
92   0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
93   0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
94   0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
95   0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
96   0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
97   0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
98   0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
99   0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
100   0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
101 };
102
103 static guint8
104 gst_flac_calculate_crc8 (const guint8 * data, guint length)
105 {
106   guint8 crc = 0;
107
108   while (length--) {
109     crc = crc8_table[crc ^ *data];
110     ++data;
111   }
112
113   return crc;
114 }
115
116 /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
117 static const guint16 crc16_table[256] = {
118   0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
119   0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
120   0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
121   0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
122   0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
123   0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
124   0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
125   0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
126   0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
127   0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
128   0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
129   0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
130   0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
131   0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
132   0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
133   0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
134   0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
135   0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
136   0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
137   0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
138   0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
139   0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
140   0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
141   0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
142   0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
143   0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
144   0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
145   0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
146   0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
147   0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
148   0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
149   0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
150 };
151
152 static guint16
153 gst_flac_calculate_crc16 (const guint8 * data, guint length)
154 {
155   guint16 crc = 0;
156
157   while (length--) {
158     crc = ((crc << 8) ^ crc16_table[(crc >> 8) ^ *data]) & 0xffff;
159     data++;
160   }
161
162   return crc;
163 }
164
165 enum
166 {
167   PROP_0,
168   PROP_CHECK_FRAME_CHECKSUMS
169 };
170
171 #define DEFAULT_CHECK_FRAME_CHECKSUMS FALSE
172
173 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
174     GST_PAD_SRC,
175     GST_PAD_ALWAYS,
176     GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) true, "
177         "channels = (int) [ 1, 8 ], " "rate = (int) [ 1, 655350 ]")
178     );
179
180 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
181     GST_PAD_SINK,
182     GST_PAD_ALWAYS,
183     GST_STATIC_CAPS ("audio/x-flac")
184     );
185
186 static GstBuffer *gst_flac_parse_generate_vorbiscomment (GstFlacParse *
187     flacparse);
188
189 static inline void gst_flac_parse_reset_buffer_time_and_offset (GstBuffer *
190     buffer);
191 static void gst_flac_parse_reset (GstFlacParse * parser);
192 static gboolean gst_flac_parse_handle_block_type (GstFlacParse * flacparse,
193     guint type, GstBuffer * sbuffer);
194 static void gst_flac_parse_finalize (GObject * object);
195 static void gst_flac_parse_set_property (GObject * object, guint prop_id,
196     const GValue * value, GParamSpec * pspec);
197 static void gst_flac_parse_get_property (GObject * object, guint prop_id,
198     GValue * value, GParamSpec * pspec);
199
200 static gboolean gst_flac_parse_start (GstBaseParse * parse);
201 static gboolean gst_flac_parse_stop (GstBaseParse * parse);
202 static GstFlowReturn gst_flac_parse_handle_frame (GstBaseParse * parse,
203     GstBaseParseFrame * frame, gint * skipsize);
204 static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
205     GstBaseParseFrame * frame, gint size);
206 static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
207     GstBaseParseFrame * frame);
208 static gboolean gst_flac_parse_convert (GstBaseParse * parse,
209     GstFormat src_format, gint64 src_value, GstFormat dest_format,
210     gint64 * dest_value);
211 static gboolean gst_flac_parse_src_event (GstBaseParse * parse,
212     GstEvent * event);
213 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
214     GstCaps * filter);
215
216 #define gst_flac_parse_parent_class parent_class
217 G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);
218
219 static void
220 gst_flac_parse_class_init (GstFlacParseClass * klass)
221 {
222   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
223   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
224   GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
225
226   GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
227       "Flac parser element");
228
229   gobject_class->finalize = gst_flac_parse_finalize;
230   gobject_class->set_property = gst_flac_parse_set_property;
231   gobject_class->get_property = gst_flac_parse_get_property;
232
233   g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
234       g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
235           "Check the overall checksums of every frame",
236           DEFAULT_CHECK_FRAME_CHECKSUMS,
237           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
238
239   baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
240   baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
241   baseparse_class->handle_frame =
242       GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
243   baseparse_class->pre_push_frame =
244       GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
245   baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
246   baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
247   baseparse_class->get_sink_caps =
248       GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
249
250   gst_element_class_add_static_pad_template (element_class, &src_factory);
251   gst_element_class_add_static_pad_template (element_class, &sink_factory);
252
253   gst_element_class_set_static_metadata (element_class, "FLAC audio parser",
254       "Codec/Parser/Audio",
255       "Parses audio with the FLAC lossless audio codec",
256       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
257 }
258
259 static void
260 gst_flac_parse_init (GstFlacParse * flacparse)
261 {
262   flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
263   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (flacparse));
264   GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (flacparse));
265 }
266
267 static void
268 gst_flac_parse_set_property (GObject * object, guint prop_id,
269     const GValue * value, GParamSpec * pspec)
270 {
271   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
272
273   switch (prop_id) {
274     case PROP_CHECK_FRAME_CHECKSUMS:
275       flacparse->check_frame_checksums = g_value_get_boolean (value);
276       break;
277     default:
278       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
279       break;
280   }
281 }
282
283 static void
284 gst_flac_parse_get_property (GObject * object, guint prop_id,
285     GValue * value, GParamSpec * pspec)
286 {
287   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
288
289   switch (prop_id) {
290     case PROP_CHECK_FRAME_CHECKSUMS:
291       g_value_set_boolean (value, flacparse->check_frame_checksums);
292       break;
293     default:
294       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
295       break;
296   }
297 }
298
299 static void
300 gst_flac_parse_reset (GstFlacParse * parser)
301 {
302   if (parser->tags) {
303     gst_tag_list_unref (parser->tags);
304     parser->tags = NULL;
305   }
306   if (parser->toc) {
307     gst_toc_unref (parser->toc);
308     parser->toc = NULL;
309   }
310   if (parser->seektable) {
311     gst_buffer_unref (parser->seektable);
312     parser->seektable = NULL;
313   }
314
315   g_list_foreach (parser->headers, (GFunc) gst_mini_object_unref, NULL);
316   g_list_free (parser->headers);
317   parser->headers = NULL;
318 }
319
320 static void
321 gst_flac_parse_finalize (GObject * object)
322 {
323   GstFlacParse *flacparse = GST_FLAC_PARSE (object);
324
325   gst_flac_parse_reset (flacparse);
326   G_OBJECT_CLASS (parent_class)->finalize (object);
327 }
328
329 static gboolean
330 gst_flac_parse_start (GstBaseParse * parse)
331 {
332   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
333
334   flacparse->state = GST_FLAC_PARSE_STATE_INIT;
335   flacparse->min_blocksize = 0;
336   flacparse->max_blocksize = 0;
337   flacparse->min_framesize = 0;
338   flacparse->max_framesize = 0;
339
340   flacparse->upstream_length = -1;
341
342   flacparse->samplerate = 0;
343   flacparse->channels = 0;
344   flacparse->bps = 0;
345   flacparse->total_samples = 0;
346
347   flacparse->offset = GST_CLOCK_TIME_NONE;
348   flacparse->blocking_strategy = 0;
349   flacparse->block_size = 0;
350   flacparse->sample_number = 0;
351   flacparse->strategy_checked = FALSE;
352
353   flacparse->sent_codec_tag = FALSE;
354
355   /* "fLaC" marker */
356   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
357
358   /* inform baseclass we can come up with ts, based on counters in packets */
359   gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
360   gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);
361
362   return TRUE;
363 }
364
365 static gboolean
366 gst_flac_parse_stop (GstBaseParse * parse)
367 {
368   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
369
370   gst_flac_parse_reset (flacparse);
371   return TRUE;
372 }
373
374 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
375
376 static const guint16 blocksize_table[16] = {
377   0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
378   256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
379   256 << 7,
380 };
381
382 static const guint32 sample_rate_table[16] = {
383   0,
384   88200, 176400, 192000,
385   8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
386   0, 0, 0, 0,
387 };
388
389 typedef enum
390 {
391   FRAME_HEADER_VALID,
392   FRAME_HEADER_INVALID,
393   FRAME_HEADER_MORE_DATA
394 } FrameHeaderCheckReturn;
395
396 static FrameHeaderCheckReturn
397 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
398     const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
399     gboolean * suspect)
400 {
401   GstBitReader reader = GST_BIT_READER_INIT (data, size);
402   guint8 blocking_strategy;
403   guint16 block_size;
404   guint32 samplerate = 0;
405   guint64 sample_number;
406   guint8 channels, bps;
407   guint8 tmp = 0;
408   guint8 actual_crc, expected_crc = 0;
409
410   /* Skip 14 bit sync code */
411   gst_bit_reader_skip_unchecked (&reader, 14);
412
413   /* Must be 0 */
414   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
415     goto error;
416
417   /* 0 == fixed block size, 1 == variable block size */
418   blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
419   if (flacparse->force_variable_block_size)
420     blocking_strategy = 1;
421
422   /* block size index, calculation of the real blocksize below */
423   block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
424   if (block_size == 0)
425     goto error;
426
427   /* sample rate index, calculation of the real samplerate below */
428   samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
429   if (samplerate == 0x0f)
430     goto error;
431
432   /* channel assignment */
433   channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
434   if (channels < 8) {
435     channels++;
436   } else if (channels <= 10) {
437     channels = 2;
438   } else if (channels > 10) {
439     goto error;
440   }
441   if (flacparse->channels && flacparse->channels != channels)
442     goto error;
443
444   /* bits per sample */
445   bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
446   if (bps == 0x03 || bps == 0x07) {
447     goto error;
448   } else if (bps == 0 && flacparse->bps == 0) {
449     goto need_streaminfo;
450   }
451   bps = sample_size_table[bps];
452   if (flacparse->bps && bps != flacparse->bps)
453     goto error;
454
455   /* reserved, must be 0 */
456   if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
457     goto error;
458
459   /* read "utf8" encoded sample/frame number */
460   {
461     gint len = 0;
462
463     len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
464
465     /* This is slightly faster than a loop */
466     if (!(len & 0x80)) {
467       sample_number = len;
468       len = 0;
469     } else if ((len & 0xc0) && !(len & 0x20)) {
470       sample_number = len & 0x1f;
471       len = 1;
472     } else if ((len & 0xe0) && !(len & 0x10)) {
473       sample_number = len & 0x0f;
474       len = 2;
475     } else if ((len & 0xf0) && !(len & 0x08)) {
476       sample_number = len & 0x07;
477       len = 3;
478     } else if ((len & 0xf8) && !(len & 0x04)) {
479       sample_number = len & 0x03;
480       len = 4;
481     } else if ((len & 0xfc) && !(len & 0x02)) {
482       sample_number = len & 0x01;
483       len = 5;
484     } else if ((len & 0xfe) && !(len & 0x01)) {
485       sample_number = len & 0x0;
486       len = 6;
487     } else {
488       goto error;
489     }
490
491     if ((blocking_strategy == 0 && len > 5) ||
492         (blocking_strategy == 1 && len > 6))
493       goto error;
494
495     while (len > 0) {
496       if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
497         goto need_more_data;
498
499       if ((tmp & 0xc0) != 0x80)
500         goto error;
501
502       sample_number <<= 6;
503       sample_number |= (tmp & 0x3f);
504       len--;
505     }
506   }
507
508   /* calculate real blocksize from the blocksize index */
509   if (block_size == 6) {
510     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
511       goto need_more_data;
512     block_size++;
513   } else if (block_size == 7) {
514     if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
515       goto need_more_data;
516     block_size++;
517   } else {
518     block_size = blocksize_table[block_size];
519   }
520
521   /* calculate the real samplerate from the samplerate index */
522   if (samplerate == 0 && flacparse->samplerate == 0) {
523     goto need_streaminfo;
524   } else if (samplerate < 12) {
525     samplerate = sample_rate_table[samplerate];
526   } else if (samplerate == 12) {
527     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
528       goto need_more_data;
529     samplerate *= 1000;
530   } else if (samplerate == 13) {
531     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
532       goto need_more_data;
533   } else if (samplerate == 14) {
534     if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
535       goto need_more_data;
536     samplerate *= 10;
537   }
538
539   if (flacparse->samplerate && flacparse->samplerate != samplerate)
540     goto error;
541
542   /* check crc-8 for the header */
543   if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
544     goto need_more_data;
545
546   actual_crc =
547       gst_flac_calculate_crc8 (data,
548       (gst_bit_reader_get_pos (&reader) / 8) - 1);
549   if (actual_crc != expected_crc) {
550     GST_DEBUG_OBJECT (flacparse,
551         "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
552         expected_crc, actual_crc);
553     goto error;
554   }
555
556   /* Sanity check sample number against blocking strategy, as it seems
557      some files claim fixed block size but supply sample numbers,
558      rather than block numbers. */
559   if (blocking_strategy == 0 && flacparse->block_size != 0) {
560     if (!flacparse->strategy_checked) {
561       if (block_size == sample_number) {
562         GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
563             "but seems to be lying: assuming variable block size");
564         flacparse->force_variable_block_size = TRUE;
565         blocking_strategy = 1;
566       }
567       flacparse->strategy_checked = TRUE;
568     }
569   }
570
571   /* documentation says:
572    * The "blocking strategy" bit must be the same throughout the entire stream. */
573   if (flacparse->blocking_strategy != blocking_strategy) {
574     if (flacparse->block_size != 0) {
575       GST_WARNING_OBJECT (flacparse, "blocking strategy is not constant");
576       if (suspect)
577         *suspect = TRUE;
578     }
579   }
580
581   /*
582      The FLAC format documentation says:
583      The "blocking strategy" bit determines how to calculate the sample number
584      of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
585      frame header encodes the frame number as above, and the frame's starting
586      sample number will be the frame number times the blocksize. If it is 1
587      (variable-blocksize), the frame header encodes the frame's starting
588      sample number itself. (In the case of a fixed-blocksize stream, only the
589      last block may be shorter than the stream blocksize; its starting sample
590      number will be calculated as the frame number times the previous frame's
591      blocksize, or zero if it is the first frame).
592
593      Therefore, when in fixed block size mode, we only update the block size
594      the first time, then reuse that block size for subsequent calls.
595      This will also fix a timestamp problem with the last block's timestamp
596      being miscalculated by scaling the block number by a "wrong" block size.
597    */
598   if (blocking_strategy == 0) {
599     if (flacparse->block_size != 0) {
600       /* after first block */
601       if (flacparse->block_size != block_size) {
602         /* TODO: can we know we're on the last frame, to avoid warning ? */
603         GST_WARNING_OBJECT (flacparse, "Block size is not constant");
604         block_size = flacparse->block_size;
605         if (suspect)
606           *suspect = TRUE;
607       }
608     }
609   }
610
611   if (set) {
612     flacparse->block_size = block_size;
613     if (!flacparse->samplerate)
614       flacparse->samplerate = samplerate;
615     if (!flacparse->bps)
616       flacparse->bps = bps;
617     if (!flacparse->blocking_strategy)
618       flacparse->blocking_strategy = blocking_strategy;
619     if (!flacparse->channels)
620       flacparse->channels = channels;
621     if (!flacparse->sample_number)
622       flacparse->sample_number = sample_number;
623
624     GST_DEBUG_OBJECT (flacparse,
625         "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
626         "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
627         flacparse->block_size, flacparse->sample_number);
628   }
629
630   if (block_size_ret)
631     *block_size_ret = block_size;
632
633   return FRAME_HEADER_VALID;
634
635 need_streaminfo:
636   GST_ERROR_OBJECT (flacparse, "Need STREAMINFO metadata. Bits per sample "
637       "or sample rate not in frame header");
638 error:
639   return FRAME_HEADER_INVALID;
640
641 need_more_data:
642   return FRAME_HEADER_MORE_DATA;
643 }
644
645 static gboolean
646 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
647     const guint8 * data, gsize size, guint * ret)
648 {
649   guint max, remaining;
650   guint i, search_start, search_end;
651   FrameHeaderCheckReturn header_ret;
652   guint16 block_size;
653   gboolean suspect_start = FALSE, suspect_end = FALSE;
654
655   if (size < flacparse->min_framesize)
656     goto need_more;
657
658   header_ret =
659       gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
660       &block_size, &suspect_start);
661   if (header_ret == FRAME_HEADER_INVALID) {
662     *ret = 0;
663     return FALSE;
664   }
665   if (header_ret == FRAME_HEADER_MORE_DATA)
666     goto need_more;
667
668   /* mind unknown framesize */
669   search_start = MAX (2, flacparse->min_framesize);
670   if (flacparse->max_framesize)
671     search_end = MIN (size, flacparse->max_framesize + 9 + 2);
672   else
673     search_end = size;
674   search_end -= 2;
675
676   remaining = size;
677
678   for (i = search_start; i < search_end; i++, remaining--) {
679
680     if ((GST_READ_UINT16_BE (data + i) & 0xfffe) != 0xfff8)
681       continue;
682
683     GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
684     suspect_end = FALSE;
685     header_ret =
686         gst_flac_parse_frame_header_is_valid (flacparse, data + i,
687         remaining, FALSE, NULL, &suspect_end);
688     if (header_ret == FRAME_HEADER_VALID) {
689       if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
690         guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
691         guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);
692
693         GST_LOG_OBJECT (flacparse,
694             "Found possible frame (%d, %d). Checking for CRC match",
695             suspect_start, suspect_end);
696         if (actual_crc != expected_crc) {
697           GST_DEBUG_OBJECT (flacparse,
698               "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
699               expected_crc, actual_crc);
700           continue;
701         }
702       }
703       *ret = i;
704       flacparse->block_size = block_size;
705       return TRUE;
706     } else if (header_ret == FRAME_HEADER_MORE_DATA) {
707       goto need_more;
708     }
709   }
710
711   /* For the last frame output everything to the end */
712   if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
713     if (flacparse->check_frame_checksums) {
714       guint16 actual_crc = gst_flac_calculate_crc16 (data, size - 2);
715       guint16 expected_crc = GST_READ_UINT16_BE (data + size - 2);
716
717       if (actual_crc == expected_crc) {
718         *ret = size;
719         flacparse->block_size = block_size;
720         return TRUE;
721       }
722     } else {
723       *ret = size;
724       flacparse->block_size = block_size;
725       return TRUE;
726     }
727   }
728
729   /* so we searched to expected end and found nothing,
730    * give up on this frame (start) */
731   if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
732     GST_LOG_OBJECT (flacparse,
733         "could not determine valid frame end, discarding frame (start)");
734     *ret = 1;
735     return FALSE;
736   }
737
738 need_more:
739   max = flacparse->max_framesize + 16;
740   if (max == 16)
741     max = 1 << 24;
742   *ret = MIN (size + 4096, max);
743   return TRUE;
744 }
745
746 static GstFlowReturn
747 gst_flac_parse_handle_frame (GstBaseParse * parse,
748     GstBaseParseFrame * frame, gint * skipsize)
749 {
750   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
751   GstBuffer *buffer = frame->buffer;
752   GstMapInfo map;
753   gboolean result = TRUE;
754   GstFlowReturn ret = GST_FLOW_OK;
755   guint framesize = 0;
756
757   gst_buffer_map (buffer, &map, GST_MAP_READ);
758
759   *skipsize = 1;
760
761   if (G_UNLIKELY (map.size < 4)) {
762     result = FALSE;
763     goto cleanup;
764   }
765
766   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
767     if (memcmp (map.data, "fLaC", 4) == 0) {
768       GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
769       framesize = 4;
770       goto cleanup;
771     }
772     if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
773       GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
774       /* Minimal size of a frame header */
775       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
776       flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
777       *skipsize = 0;
778       result = FALSE;
779       goto cleanup;
780     }
781     GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
782     result = FALSE;
783     goto cleanup;
784   }
785
786   if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
787     guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
788
789     GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
790     framesize = size;
791     goto cleanup;
792   }
793
794   if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
795     gboolean ret;
796     guint next;
797
798     flacparse->offset = GST_BUFFER_OFFSET (buffer);
799     flacparse->blocking_strategy = 0;
800     flacparse->sample_number = 0;
801
802     GST_DEBUG_OBJECT (flacparse, "Found sync code");
803     ret = gst_flac_parse_frame_is_valid (flacparse, map.data, map.size, &next);
804     if (ret) {
805       framesize = next;
806       goto cleanup;
807     }
808     /* If we're at EOS and the frame was not valid, drop it! */
809     if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
810       GST_WARNING_OBJECT (flacparse, "EOS");
811       result = FALSE;
812       goto cleanup;
813     }
814
815     if (next == 0) {
816     } else if (next > map.size) {
817       GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
818       *skipsize = 0;
819       gst_base_parse_set_min_frame_size (parse, next);
820       result = FALSE;
821       goto cleanup;
822     } else {
823       GST_ERROR_OBJECT (flacparse,
824           "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
825       result = FALSE;
826       goto cleanup;
827     }
828   } else {
829     GstByteReader reader;
830     gint off;
831
832     gst_byte_reader_init (&reader, map.data, map.size);
833     off =
834         gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
835         0, map.size);
836
837     if (off > 0) {
838       GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
839       *skipsize = off;
840       result = FALSE;
841       goto cleanup;
842     }
843
844     GST_DEBUG_OBJECT (flacparse, "Sync code not found");
845     *skipsize = map.size - 3;
846     result = FALSE;
847     goto cleanup;
848   }
849
850   result = FALSE;
851
852 cleanup:
853   gst_buffer_unmap (buffer, &map);
854
855   if (result)
856     *skipsize = 0;
857
858   if (result && framesize <= map.size) {
859     ret = gst_flac_parse_parse_frame (parse, frame, framesize);
860     if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
861       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
862       ret = GST_FLOW_OK;
863     }
864     if (ret == GST_FLOW_OK)
865       ret = gst_base_parse_finish_frame (parse, frame, framesize);
866   }
867
868   return ret;
869 }
870
871 static gboolean
872 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
873 {
874   GstBitReader reader;
875   GstMapInfo map;
876
877   gst_buffer_map (buffer, &map, GST_MAP_READ);
878   gst_bit_reader_init (&reader, map.data, map.size);
879
880   if (map.size != 4 + 34) {
881     GST_ERROR_OBJECT (flacparse,
882         "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
883     goto failure;
884   }
885
886   /* Skip metadata block header */
887   if (!gst_bit_reader_skip (&reader, 32))
888     goto error;
889
890   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
891     goto error;
892   if (flacparse->min_blocksize < 16) {
893     GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
894         flacparse->min_blocksize);
895   }
896
897   if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
898     goto error;
899   if (flacparse->max_blocksize < 16) {
900     GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
901         flacparse->max_blocksize);
902   }
903
904   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
905     goto error;
906   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
907     goto error;
908
909   if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
910     goto error;
911   if (flacparse->samplerate == 0) {
912     GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
913     goto failure;
914   }
915
916   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
917     goto error;
918   flacparse->channels++;
919   if (flacparse->channels > 8) {
920     GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
921         flacparse->channels);
922     goto failure;
923   }
924
925   if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
926     goto error;
927   flacparse->bps++;
928
929   if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
930     goto error;
931   if (flacparse->total_samples) {
932     gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
933         GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
934   }
935
936   gst_buffer_unmap (buffer, &map);
937
938   GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
939       "\tmin/max blocksize: %u/%u,\n"
940       "\tmin/max framesize: %u/%u,\n"
941       "\tsamplerate: %u,\n"
942       "\tchannels: %u,\n"
943       "\tbits per sample: %u,\n"
944       "\ttotal samples: %" G_GUINT64_FORMAT,
945       flacparse->min_blocksize, flacparse->max_blocksize,
946       flacparse->min_framesize, flacparse->max_framesize,
947       flacparse->samplerate,
948       flacparse->channels, flacparse->bps, flacparse->total_samples);
949
950   return TRUE;
951
952 error:
953   GST_ERROR_OBJECT (flacparse, "Failed to read data");
954 failure:
955   gst_buffer_unmap (buffer, &map);
956   return FALSE;
957 }
958
959 static gboolean
960 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
961     GstBuffer * buffer)
962 {
963   GstTagList *tags;
964   GstMapInfo map;
965
966   gst_buffer_map (buffer, &map, GST_MAP_READ);
967
968   tags =
969       gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
970   gst_buffer_unmap (buffer, &map);
971
972   if (tags == NULL) {
973     GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
974   } else if (gst_tag_list_is_empty (tags)) {
975     gst_tag_list_unref (tags);
976   } else if (flacparse->tags == NULL) {
977     flacparse->tags = tags;
978   } else {
979     gst_tag_list_insert (flacparse->tags, tags, GST_TAG_MERGE_APPEND);
980     gst_tag_list_unref (tags);
981   }
982
983   return TRUE;
984 }
985
986 static gboolean
987 gst_flac_parse_handle_cuesheet (GstFlacParse * flacparse, GstBuffer * buffer)
988 {
989   GstByteReader reader;
990   GstMapInfo map;
991   guint i, j;
992   guint8 n_tracks, track_num, index;
993   guint64 offset;
994   gint64 start, stop;
995   gchar *id;
996   gchar isrc[13];
997   GstTagList *tags;
998   GstToc *toc;
999   GstTocEntry *cur_entry = NULL, *prev_entry = NULL;
1000
1001   gst_buffer_map (buffer, &map, GST_MAP_READ);
1002   gst_byte_reader_init (&reader, map.data, map.size);
1003
1004   toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1005
1006   /* skip 4 bytes METADATA_BLOCK_HEADER */
1007   /* https://xiph.org/flac/format.html#metadata_block_header */
1008   if (!gst_byte_reader_skip (&reader, 4))
1009     goto error;
1010
1011   /* skip 395 bytes from METADATA_BLOCK_CUESHEET */
1012   /* https://xiph.org/flac/format.html#metadata_block_cuesheet */
1013   if (!gst_byte_reader_skip (&reader, 395))
1014     goto error;
1015
1016   if (!gst_byte_reader_get_uint8 (&reader, &n_tracks))
1017     goto error;
1018
1019   /* CUESHEET_TRACK */
1020   /* https://xiph.org/flac/format.html#cuesheet_track */
1021   for (i = 0; i < n_tracks; i++) {
1022     if (!gst_byte_reader_get_uint64_be (&reader, &offset))
1023       goto error;
1024     if (!gst_byte_reader_get_uint8 (&reader, &track_num))
1025       goto error;
1026
1027     if (gst_byte_reader_get_remaining (&reader) < 12)
1028       goto error;
1029     memcpy (isrc, map.data + gst_byte_reader_get_pos (&reader), 12);
1030     /* \0-terminate the string */
1031     isrc[12] = '\0';
1032     if (!gst_byte_reader_skip (&reader, 12))
1033       goto error;
1034
1035     /* skip 14 bytes from CUESHEET_TRACK */
1036     if (!gst_byte_reader_skip (&reader, 14))
1037       goto error;
1038     if (!gst_byte_reader_get_uint8 (&reader, &index))
1039       goto error;
1040     /* add tracks in TOC */
1041     /* lead-out tack has number 170 or 255 */
1042     if (track_num != 170 && track_num != 255) {
1043       prev_entry = cur_entry;
1044       /* previous track stop time = current track start time */
1045       if (prev_entry != NULL) {
1046         gst_toc_entry_get_start_stop_times (prev_entry, &start, NULL);
1047         stop =
1048             gst_util_uint64_scale_round (offset, GST_SECOND,
1049             flacparse->samplerate);
1050         gst_toc_entry_set_start_stop_times (prev_entry, start, stop);
1051       }
1052       id = g_strdup_printf ("%08x", track_num);
1053       cur_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, id);
1054       g_free (id);
1055       start =
1056           gst_util_uint64_scale_round (offset, GST_SECOND,
1057           flacparse->samplerate);
1058       gst_toc_entry_set_start_stop_times (cur_entry, start, -1);
1059       /* add ISRC as tag in track */
1060       if (strlen (isrc) != 0) {
1061         tags = gst_tag_list_new_empty ();
1062         gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ISRC, isrc, NULL);
1063         gst_toc_entry_set_tags (cur_entry, tags);
1064       }
1065       gst_toc_append_entry (toc, cur_entry);
1066       /* CUESHEET_TRACK_INDEX */
1067       /* https://xiph.org/flac/format.html#cuesheet_track_index */
1068       for (j = 0; j < index; j++) {
1069         if (!gst_byte_reader_skip (&reader, 12))
1070           goto error;
1071       }
1072     } else {
1073       /* set stop time in last track */
1074       stop =
1075           gst_util_uint64_scale_round (offset, GST_SECOND,
1076           flacparse->samplerate);
1077       gst_toc_entry_set_start_stop_times (cur_entry, start, stop);
1078     }
1079   }
1080
1081   /* send data as TOC */
1082   if (!flacparse->toc)
1083     flacparse->toc = toc;
1084
1085   gst_buffer_unmap (buffer, &map);
1086   return TRUE;
1087
1088 error:
1089   GST_ERROR_OBJECT (flacparse, "Error reading data");
1090   gst_buffer_unmap (buffer, &map);
1091   return FALSE;
1092 }
1093
1094 static gboolean
1095 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
1096 {
1097   GstByteReader reader;
1098   GstMapInfo map;
1099   guint32 img_len = 0, img_type = 0;
1100   guint32 img_mimetype_len = 0, img_description_len = 0;
1101
1102   gst_buffer_map (buffer, &map, GST_MAP_READ);
1103   gst_byte_reader_init (&reader, map.data, map.size);
1104
1105   if (!gst_byte_reader_skip (&reader, 4))
1106     goto error;
1107
1108   if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
1109     goto error;
1110
1111   if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
1112     goto error;
1113   if (!gst_byte_reader_skip (&reader, img_mimetype_len))
1114     goto error;
1115
1116   if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
1117     goto error;
1118   if (!gst_byte_reader_skip (&reader, img_description_len))
1119     goto error;
1120
1121   if (!gst_byte_reader_skip (&reader, 4 * 4))
1122     goto error;
1123
1124   if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
1125     goto error;
1126
1127   if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
1128     goto error;
1129
1130   GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);
1131
1132   if (img_len > 0) {
1133     if (flacparse->tags == NULL)
1134       flacparse->tags = gst_tag_list_new_empty ();
1135
1136     gst_tag_list_add_id3_image (flacparse->tags,
1137         map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
1138   }
1139
1140   gst_buffer_unmap (buffer, &map);
1141   return TRUE;
1142
1143 error:
1144   GST_ERROR_OBJECT (flacparse, "Error reading data");
1145   gst_buffer_unmap (buffer, &map);
1146   return FALSE;
1147 }
1148
1149 static gboolean
1150 gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
1151 {
1152
1153   GST_DEBUG_OBJECT (flacparse, "storing seektable");
1154   /* only store for now;
1155    * offset of the first frame is needed to get real info */
1156   if (flacparse->seektable)
1157     gst_buffer_unref (flacparse->seektable);
1158   flacparse->seektable = gst_buffer_ref (buffer);
1159
1160   return TRUE;
1161 }
1162
1163 static void
1164 gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
1165 {
1166   GstByteReader br;
1167   gint64 offset = 0, samples = 0;
1168   GstMapInfo map;
1169
1170   GST_DEBUG_OBJECT (flacparse,
1171       "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);
1172
1173   if (boffset <= 0)
1174     goto exit;
1175
1176   gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
1177   gst_byte_reader_init (&br, map.data, map.size);
1178
1179   /* skip header */
1180   if (!gst_byte_reader_skip (&br, 4))
1181     goto done;
1182
1183   /* seekpoints */
1184   while (gst_byte_reader_get_remaining (&br)) {
1185     if (!gst_byte_reader_get_int64_be (&br, &samples))
1186       break;
1187     if (!gst_byte_reader_get_int64_be (&br, &offset))
1188       break;
1189     if (!gst_byte_reader_skip (&br, 2))
1190       break;
1191
1192     GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
1193         G_GINT64_FORMAT, samples, offset);
1194
1195     /* sanity check */
1196     if (G_LIKELY (offset > 0 && samples > 0)) {
1197       gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
1198           boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
1199               flacparse->samplerate), TRUE, FALSE);
1200     }
1201   }
1202
1203 done:
1204   gst_buffer_unmap (flacparse->seektable, &map);
1205 exit:
1206   gst_buffer_unref (flacparse->seektable);
1207   flacparse->seektable = NULL;
1208 }
1209
1210 static void
1211 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
1212 {
1213   GValue value = { 0, };
1214
1215   g_value_init (&value, GST_TYPE_BUFFER);
1216   /* copy buffer to avoid problems with circular refcounts */
1217   buf = gst_buffer_copy (buf);
1218   /* again, for good measure */
1219   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1220   gst_value_set_buffer (&value, buf);
1221   gst_buffer_unref (buf);
1222   gst_value_array_append_value (array_val, &value);
1223   g_value_unset (&value);
1224 }
1225
1226 static GstFlowReturn
1227 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
1228 {
1229   GstBuffer *vorbiscomment = NULL;
1230   GstBuffer *streaminfo = NULL;
1231   GstBuffer *marker = NULL;
1232   GValue array = { 0, };
1233   GstCaps *caps;
1234   GList *l;
1235   GstFlowReturn res = GST_FLOW_OK;
1236
1237   caps = gst_caps_new_simple ("audio/x-flac",
1238       "channels", G_TYPE_INT, flacparse->channels,
1239       "framed", G_TYPE_BOOLEAN, TRUE,
1240       "rate", G_TYPE_INT, flacparse->samplerate, NULL);
1241
1242   if (!flacparse->headers)
1243     goto push_headers;
1244
1245   for (l = flacparse->headers; l; l = l->next) {
1246     GstBuffer *header = l->data;
1247     GstMapInfo map;
1248
1249     gst_buffer_map (header, &map, GST_MAP_READ);
1250
1251     GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);
1252
1253     if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
1254       marker = header;
1255     } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
1256       streaminfo = header;
1257     } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
1258       vorbiscomment = header;
1259     }
1260
1261     gst_buffer_unmap (header, &map);
1262   }
1263
1264   /* at least this one we can generate easily
1265    * to provide full headers downstream */
1266   if (vorbiscomment == NULL && streaminfo != NULL) {
1267     GST_DEBUG_OBJECT (flacparse,
1268         "missing vorbiscomment header; generating dummy");
1269     vorbiscomment = gst_flac_parse_generate_vorbiscomment (flacparse);
1270     flacparse->headers = g_list_insert (flacparse->headers, vorbiscomment,
1271         g_list_index (flacparse->headers, streaminfo) + 1);
1272   }
1273
1274   if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
1275     GST_WARNING_OBJECT (flacparse,
1276         "missing header %p %p %p, muxing into container "
1277         "formats may be broken", marker, streaminfo, vorbiscomment);
1278     goto push_headers;
1279   }
1280
1281   g_value_init (&array, GST_TYPE_ARRAY);
1282
1283   /* add marker including STREAMINFO header */
1284   {
1285     GstBuffer *buf;
1286     guint16 num;
1287     GstMapInfo sinfomap, writemap;
1288
1289     gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);
1290
1291     /* minus one for the marker that is merged with streaminfo here */
1292     num = g_list_length (flacparse->headers) - 1;
1293
1294     buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
1295     gst_buffer_map (buf, &writemap, GST_MAP_WRITE);
1296
1297     writemap.data[0] = 0x7f;
1298     memcpy (writemap.data + 1, "FLAC", 4);
1299     writemap.data[5] = 0x01;    /* mapping version major */
1300     writemap.data[6] = 0x00;    /* mapping version minor */
1301     writemap.data[7] = (num & 0xFF00) >> 8;
1302     writemap.data[8] = (num & 0x00FF) >> 0;
1303     memcpy (writemap.data + 9, "fLaC", 4);
1304     memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
1305     _value_array_append_buffer (&array, buf);
1306
1307     gst_buffer_unmap (streaminfo, &sinfomap);
1308     gst_buffer_unmap (buf, &writemap);
1309     gst_buffer_unref (buf);
1310   }
1311
1312   /* add VORBISCOMMENT header */
1313   _value_array_append_buffer (&array, vorbiscomment);
1314
1315   /* add other headers, if there are any */
1316   for (l = flacparse->headers; l; l = l->next) {
1317     if (GST_BUFFER_CAST (l->data) != marker &&
1318         GST_BUFFER_CAST (l->data) != streaminfo &&
1319         GST_BUFFER_CAST (l->data) != vorbiscomment) {
1320       _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
1321     }
1322   }
1323
1324   gst_structure_set_value (gst_caps_get_structure (caps, 0),
1325       "streamheader", &array);
1326   g_value_unset (&array);
1327
1328 push_headers:
1329
1330   gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
1331   gst_caps_unref (caps);
1332
1333   /* push header buffers; update caps, so when we push the first buffer the
1334    * negotiated caps will change to caps that include the streamheader field */
1335   while (flacparse->headers) {
1336     GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
1337     GstBaseParseFrame frame;
1338
1339     flacparse->headers =
1340         g_list_delete_link (flacparse->headers, flacparse->headers);
1341     buf = gst_buffer_make_writable (buf);
1342
1343     /* init, set and give away frame */
1344     gst_base_parse_frame_init (&frame);
1345     frame.buffer = buf;
1346     frame.overhead = -1;
1347     res = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
1348     gst_base_parse_frame_free (&frame);
1349     if (res != GST_FLOW_OK)
1350       break;
1351   }
1352   g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
1353   g_list_free (flacparse->headers);
1354   flacparse->headers = NULL;
1355
1356   return res;
1357 }
1358
1359 /* empty vorbiscomment */
1360 static GstBuffer *
1361 gst_flac_parse_generate_vorbiscomment (GstFlacParse * flacparse)
1362 {
1363   GstTagList *taglist = gst_tag_list_new_empty ();
1364   guchar header[4];
1365   guint size;
1366   GstBuffer *vorbiscomment;
1367   GstMapInfo map;
1368
1369   header[0] = 0x84;             /* is_last = 1; type = 4; */
1370
1371   vorbiscomment =
1372       gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1373       sizeof (header), NULL);
1374   gst_tag_list_unref (taglist);
1375
1376   gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1377
1378   /* Get rid of framing bit */
1379   if (map.data[map.size - 1] == 1) {
1380     GstBuffer *sub;
1381
1382     sub =
1383         gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
1384         map.size - 1);
1385     gst_buffer_unmap (vorbiscomment, &map);
1386     gst_buffer_unref (vorbiscomment);
1387     vorbiscomment = sub;
1388     gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1389   }
1390
1391   size = map.size - 4;
1392   map.data[1] = ((size & 0xFF0000) >> 16);
1393   map.data[2] = ((size & 0x00FF00) >> 8);
1394   map.data[3] = (size & 0x0000FF);
1395   gst_buffer_unmap (vorbiscomment, &map);
1396   gst_flac_parse_reset_buffer_time_and_offset (vorbiscomment);
1397
1398   return vorbiscomment;
1399 }
1400
1401 static gboolean
1402 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1403 {
1404   GstBuffer *marker, *streaminfo;
1405   GstMapInfo map;
1406
1407   marker = gst_buffer_new_and_alloc (4);
1408   gst_buffer_map (marker, &map, GST_MAP_WRITE);
1409   memcpy (map.data, "fLaC", 4);
1410   gst_buffer_unmap (marker, &map);
1411   gst_flac_parse_reset_buffer_time_and_offset (marker);
1412   flacparse->headers = g_list_append (flacparse->headers, marker);
1413
1414   streaminfo = gst_buffer_new_and_alloc (4 + 34);
1415   gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
1416   memset (map.data, 0, 4 + 34);
1417
1418   /* metadata block header */
1419   map.data[0] = 0x00;           /* is_last = 0; type = 0; */
1420   map.data[1] = 0x00;           /* length = 34; */
1421   map.data[2] = 0x00;
1422   map.data[3] = 0x22;
1423
1424   /* streaminfo */
1425
1426   map.data[4] = (flacparse->block_size >> 8) & 0xff;    /* min blocksize = blocksize; */
1427   map.data[5] = (flacparse->block_size) & 0xff;
1428   map.data[6] = (flacparse->block_size >> 8) & 0xff;    /* max blocksize = blocksize; */
1429   map.data[7] = (flacparse->block_size) & 0xff;
1430
1431   map.data[8] = 0x00;           /* min framesize = 0; */
1432   map.data[9] = 0x00;
1433   map.data[10] = 0x00;
1434   map.data[11] = 0x00;          /* max framesize = 0; */
1435   map.data[12] = 0x00;
1436   map.data[13] = 0x00;
1437
1438   map.data[14] = (flacparse->samplerate >> 12) & 0xff;
1439   map.data[15] = (flacparse->samplerate >> 4) & 0xff;
1440   map.data[16] = (flacparse->samplerate >> 0) & 0xf0;
1441
1442   map.data[16] |= (flacparse->channels - 1) << 1;
1443
1444   map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1445   map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1446
1447   {
1448     gint64 duration;
1449
1450     if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
1451             GST_FORMAT_TIME, &duration) && duration != -1) {
1452       duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1453
1454       map.data[17] |= (duration >> 32) & 0xff;
1455       map.data[18] |= (duration >> 24) & 0xff;
1456       map.data[19] |= (duration >> 16) & 0xff;
1457       map.data[20] |= (duration >> 8) & 0xff;
1458       map.data[21] |= (duration >> 0) & 0xff;
1459     }
1460   }
1461   /* MD5 = 0; */
1462
1463   gst_buffer_unmap (streaminfo, &map);
1464   gst_flac_parse_reset_buffer_time_and_offset (streaminfo);
1465   flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1466
1467   flacparse->headers = g_list_append (flacparse->headers,
1468       gst_flac_parse_generate_vorbiscomment (flacparse));
1469
1470   return TRUE;
1471 }
1472
1473 static inline void
1474 gst_flac_parse_reset_buffer_time_and_offset (GstBuffer * buffer)
1475 {
1476   GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1477   GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1478   GST_BUFFER_OFFSET (buffer) = 0;
1479   GST_BUFFER_OFFSET_END (buffer) = 0;
1480 }
1481
1482 /* Type 127 is invalid for a metadata block header & should
1483  * be discarded _before_ calling this function */
1484 static gboolean
1485 gst_flac_parse_handle_block_type (GstFlacParse * flacparse, guint type,
1486     GstBuffer * sbuffer)
1487 {
1488   gboolean ret = TRUE;
1489
1490   switch (type) {
1491     case 0:                    /* STREAMINFO */
1492       GST_INFO_OBJECT (flacparse, "STREAMINFO header");
1493       ret = gst_flac_parse_handle_streaminfo (flacparse, sbuffer);
1494       break;
1495     case 3:                    /* SEEKTABLE */
1496       GST_INFO_OBJECT (flacparse, "SEEKTABLE header");
1497       ret = gst_flac_parse_handle_seektable (flacparse, sbuffer);
1498       break;
1499     case 4:                    /* VORBIS_COMMENT */
1500       GST_INFO_OBJECT (flacparse, "VORBISCOMMENT header");
1501       ret = gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer);
1502       break;
1503     case 5:                    /* CUESHEET */
1504       GST_INFO_OBJECT (flacparse, "CUESHEET header");
1505       ret = gst_flac_parse_handle_cuesheet (flacparse, sbuffer);
1506       break;
1507     case 6:                    /* PICTURE */
1508       GST_INFO_OBJECT (flacparse, "PICTURE header");
1509       ret = gst_flac_parse_handle_picture (flacparse, sbuffer);
1510       break;
1511     case 1:                    /* PADDING */
1512       GST_INFO_OBJECT (flacparse, "PADDING header");
1513       break;
1514     case 2:                    /* APPLICATION */
1515       GST_INFO_OBJECT (flacparse, "APPLICATION header");
1516       break;
1517     default:                   /* RESERVED */
1518       GST_INFO_OBJECT (flacparse, "Unhandled metadata header type '%u'", type);
1519       GST_FIXME_OBJECT (flacparse, "FLAC version might not be fully supported");
1520       break;
1521   }
1522
1523   return ret;
1524 }
1525
1526 static GstFlowReturn
1527 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
1528     gint size)
1529 {
1530   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1531   GstBuffer *buffer = frame->buffer, *sbuffer;
1532   GstMapInfo map;
1533   GstFlowReturn res = GST_FLOW_ERROR;
1534
1535   gst_buffer_map (buffer, &map, GST_MAP_READ);
1536
1537   if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1538     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1539     gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1540
1541     /* 32 bits metadata block */
1542     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1543     flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1544
1545     flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1546
1547     res = GST_BASE_PARSE_FLOW_DROPPED;
1548   } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1549     gboolean is_last = map.data[0] >> 7;
1550     guint type = (map.data[0] & 0x7F);
1551
1552     if (type == 127) {
1553       GST_WARNING_OBJECT (flacparse, "Invalid metadata block type 127");
1554       res = GST_BASE_PARSE_FLOW_DROPPED;
1555       goto cleanup;
1556     }
1557
1558     GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1559
1560     sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1561
1562     if (gst_flac_parse_handle_block_type (flacparse, type, sbuffer)) {
1563       gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1564       flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1565     } else {
1566       GST_WARNING_OBJECT (parse, "failed to parse header of type %u", type);
1567       GST_MEMDUMP_OBJECT (parse, "bad header data", map.data, size);
1568
1569       gst_buffer_unref (sbuffer);
1570
1571       /* error out unless we have a STREAMINFO header */
1572       if (flacparse->samplerate == 0 || flacparse->bps == 0)
1573         goto header_parsing_error;
1574
1575       /* .. in which case just stop header parsing and try to find audio */
1576       is_last = TRUE;
1577     }
1578
1579     if (is_last) {
1580       res = gst_flac_parse_handle_headers (flacparse);
1581
1582       /* Minimal size of a frame header */
1583       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1584               flacparse->min_framesize));
1585       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1586
1587       if (res != GST_FLOW_OK)
1588         goto cleanup;
1589     }
1590
1591     /* DROPPED because we pushed already or will push all headers manually */
1592     res = GST_BASE_PARSE_FLOW_DROPPED;
1593   } else {
1594     if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1595       FrameHeaderCheckReturn ret;
1596
1597       flacparse->offset = GST_BUFFER_OFFSET (buffer);
1598       ret =
1599           gst_flac_parse_frame_header_is_valid (flacparse,
1600           map.data, map.size, TRUE, NULL, NULL);
1601       if (ret != FRAME_HEADER_VALID) {
1602         GST_ERROR_OBJECT (flacparse,
1603             "Baseclass didn't provide a complete frame");
1604         goto cleanup;
1605       }
1606     }
1607
1608     if (flacparse->block_size == 0) {
1609       GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1610       goto cleanup;
1611     }
1612
1613     if (flacparse->seektable)
1614       gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));
1615
1616     if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1617       if (flacparse->blocking_strategy == 1) {
1618         GST_WARNING_OBJECT (flacparse,
1619             "Generating headers for variable blocksize streams not supported");
1620
1621         res = gst_flac_parse_handle_headers (flacparse);
1622       } else {
1623         GST_DEBUG_OBJECT (flacparse, "Generating headers");
1624
1625         if (!gst_flac_parse_generate_headers (flacparse))
1626           goto cleanup;
1627
1628         res = gst_flac_parse_handle_headers (flacparse);
1629       }
1630       flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1631       if (res != GST_FLOW_OK)
1632         goto cleanup;
1633     }
1634
1635     /* also cater for oggmux metadata */
1636     if (flacparse->blocking_strategy == 0) {
1637       GST_BUFFER_PTS (buffer) =
1638           gst_util_uint64_scale (flacparse->sample_number,
1639           flacparse->block_size * GST_SECOND, flacparse->samplerate);
1640       GST_BUFFER_OFFSET_END (buffer) =
1641           flacparse->sample_number * flacparse->block_size +
1642           flacparse->block_size;
1643     } else {
1644       GST_BUFFER_PTS (buffer) =
1645           gst_util_uint64_scale (flacparse->sample_number, GST_SECOND,
1646           flacparse->samplerate);
1647       GST_BUFFER_OFFSET_END (buffer) =
1648           flacparse->sample_number + flacparse->block_size;
1649     }
1650
1651     GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
1652     GST_BUFFER_OFFSET (buffer) =
1653         gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
1654         flacparse->samplerate);
1655     GST_BUFFER_DURATION (buffer) =
1656         GST_BUFFER_OFFSET (buffer) - GST_BUFFER_PTS (buffer);
1657
1658     /* To simplify, we just assume that it's a fixed size header and ignore
1659      * subframe headers. The first could lead us to be off by 88 bits and
1660      * the second even less, so the total inaccuracy is negligible. */
1661     frame->overhead = 7;
1662
1663     /* Minimal size of a frame header */
1664     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1665             flacparse->min_framesize));
1666
1667     flacparse->offset = -1;
1668     flacparse->blocking_strategy = 0;
1669     flacparse->sample_number = 0;
1670     res = GST_FLOW_OK;
1671   }
1672
1673 cleanup:
1674   gst_buffer_unmap (buffer, &map);
1675   return res;
1676
1677 header_parsing_error:
1678   GST_ELEMENT_ERROR (flacparse, STREAM, DECODE, (NULL),
1679       ("Failed to parse headers"));
1680   goto cleanup;
1681 }
1682
1683 static GstFlowReturn
1684 gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1685 {
1686   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1687
1688   if (!flacparse->sent_codec_tag) {
1689     GstCaps *caps;
1690
1691     if (flacparse->tags == NULL)
1692       flacparse->tags = gst_tag_list_new_empty ();
1693
1694     /* codec tag */
1695     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1696     if (G_UNLIKELY (caps == NULL)) {
1697       if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1698         GST_INFO_OBJECT (parse, "Src pad is flushing");
1699         return GST_FLOW_FLUSHING;
1700       }
1701       GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1702       return GST_FLOW_NOT_NEGOTIATED;
1703     }
1704     gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
1705         GST_TAG_AUDIO_CODEC, caps);
1706     gst_caps_unref (caps);
1707
1708     /* Announce our pending tags */
1709     gst_base_parse_merge_tags (parse, flacparse->tags, GST_TAG_MERGE_REPLACE);
1710
1711     /* also signals the end of first-frame processing */
1712     flacparse->sent_codec_tag = TRUE;
1713   }
1714
1715   /* Push toc */
1716   if (flacparse->toc) {
1717     gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
1718         gst_event_new_toc (flacparse->toc, FALSE));
1719   }
1720
1721   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1722
1723   return GST_FLOW_OK;
1724 }
1725
1726 static gboolean
1727 gst_flac_parse_convert (GstBaseParse * parse,
1728     GstFormat src_format, gint64 src_value, GstFormat dest_format,
1729     gint64 * dest_value)
1730 {
1731   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1732
1733   if (flacparse->samplerate > 0) {
1734     if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1735       if (src_value != -1)
1736         *dest_value =
1737             gst_util_uint64_scale (src_value, GST_SECOND,
1738             flacparse->samplerate);
1739       else
1740         *dest_value = -1;
1741       return TRUE;
1742     } else if (src_format == GST_FORMAT_TIME &&
1743         dest_format == GST_FORMAT_DEFAULT) {
1744       if (src_value != -1)
1745         *dest_value =
1746             gst_util_uint64_scale (src_value, flacparse->samplerate,
1747             GST_SECOND);
1748       else
1749         *dest_value = -1;
1750       return TRUE;
1751     }
1752   }
1753
1754   return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
1755       src_value, dest_format, dest_value);
1756 }
1757
1758 static gboolean
1759 gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1760 {
1761   GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1762   gboolean res = FALSE;
1763
1764   switch (GST_EVENT_TYPE (event)) {
1765     case GST_EVENT_TOC_SELECT:
1766     {
1767       GstTocEntry *entry = NULL;
1768       GstEvent *seek_event;
1769       GstToc *toc = NULL;
1770       gint64 start_pos;
1771       gchar *uid = NULL;
1772
1773       /* FIXME: some locking would be good */
1774       if (flacparse->toc)
1775         toc = gst_toc_ref (flacparse->toc);
1776
1777       if (toc != NULL) {
1778         gst_event_parse_toc_select (event, &uid);
1779         if (uid != NULL) {
1780           entry = gst_toc_find_entry (toc, uid);
1781           if (entry != NULL) {
1782             gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
1783
1784             /* FIXME: use segment rate here instead? */
1785             seek_event = gst_event_new_seek (1.0,
1786                 GST_FORMAT_TIME,
1787                 GST_SEEK_FLAG_FLUSH,
1788                 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);
1789
1790             res =
1791                 GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
1792                 seek_event);
1793
1794           } else {
1795             GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
1796           }
1797           g_free (uid);
1798         }
1799         gst_toc_unref (toc);
1800       } else {
1801         GST_DEBUG_OBJECT (flacparse, "no TOC to select");
1802       }
1803       gst_event_unref (event);
1804       break;
1805     }
1806     default:
1807       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1808       break;
1809   }
1810   return res;
1811 }
1812
1813 static void
1814 remove_fields (GstCaps * caps)
1815 {
1816   guint i, n;
1817
1818   n = gst_caps_get_size (caps);
1819   for (i = 0; i < n; i++) {
1820     GstStructure *s = gst_caps_get_structure (caps, i);
1821
1822     gst_structure_remove_field (s, "framed");
1823   }
1824 }
1825
1826 static GstCaps *
1827 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
1828 {
1829   GstCaps *peercaps, *templ;
1830   GstCaps *res;
1831
1832   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1833   if (filter) {
1834     GstCaps *fcopy = gst_caps_copy (filter);
1835     /* Remove the fields we convert */
1836     remove_fields (fcopy);
1837     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1838     gst_caps_unref (fcopy);
1839   } else
1840     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1841
1842   if (peercaps) {
1843     /* Remove the framed field */
1844     peercaps = gst_caps_make_writable (peercaps);
1845     remove_fields (peercaps);
1846
1847     res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1848     gst_caps_unref (peercaps);
1849     gst_caps_unref (templ);
1850   } else {
1851     res = templ;
1852   }
1853
1854   if (filter) {
1855     GstCaps *intersection;
1856
1857     intersection =
1858         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1859     gst_caps_unref (res);
1860     res = intersection;
1861   }
1862
1863   return res;
1864 }