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>
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.
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.
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.
25 * SECTION:element-flacparse
26 * @see_also: flacdec, oggdemux, vorbisparse
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.
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.
41 * <title>Example pipelines</title>
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.
56 #include "gstflacparse.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>
64 GST_DEBUG_CATEGORY_STATIC (flacparse_debug);
65 #define GST_CAT_DEFAULT flacparse_debug
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
104 gst_flac_calculate_crc8 (const guint8 * data, guint length)
109 crc = crc8_table[crc ^ *data];
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
153 gst_flac_calculate_crc16 (const guint8 * data, guint length)
158 crc = ((crc << 8) ^ crc16_table[(crc >> 8) ^ *data]) & 0xffff;
168 PROP_CHECK_FRAME_CHECKSUMS
171 #define DEFAULT_CHECK_FRAME_CHECKSUMS FALSE
173 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
176 GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) true, "
177 "channels = (int) [ 1, 8 ], " "rate = (int) [ 1, 655350 ]")
180 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
183 GST_STATIC_CAPS ("audio/x-flac")
186 static GstBuffer *gst_flac_parse_generate_vorbiscomment (GstFlacParse *
189 static inline void gst_flac_parse_reset_buffer_time_and_offset (GstBuffer *
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);
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_sink_event (GstBaseParse * parse,
213 static gboolean gst_flac_parse_src_event (GstBaseParse * parse,
215 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
218 #define gst_flac_parse_parent_class parent_class
219 G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);
222 gst_flac_parse_class_init (GstFlacParseClass * klass)
224 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
225 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
226 GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
228 GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
229 "Flac parser element");
231 gobject_class->finalize = gst_flac_parse_finalize;
232 gobject_class->set_property = gst_flac_parse_set_property;
233 gobject_class->get_property = gst_flac_parse_get_property;
235 g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
236 g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
237 "Check the overall checksums of every frame",
238 DEFAULT_CHECK_FRAME_CHECKSUMS,
239 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
241 baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
242 baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
243 baseparse_class->handle_frame =
244 GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
245 baseparse_class->pre_push_frame =
246 GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
247 baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
248 baseparse_class->sink_event = GST_DEBUG_FUNCPTR (gst_flac_parse_sink_event);
249 baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
250 baseparse_class->get_sink_caps =
251 GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
253 gst_element_class_add_static_pad_template (element_class, &src_factory);
254 gst_element_class_add_static_pad_template (element_class, &sink_factory);
256 gst_element_class_set_static_metadata (element_class, "FLAC audio parser",
257 "Codec/Parser/Audio",
258 "Parses audio with the FLAC lossless audio codec",
259 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
263 gst_flac_parse_init (GstFlacParse * flacparse)
265 flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
266 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (flacparse));
267 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (flacparse));
271 gst_flac_parse_set_property (GObject * object, guint prop_id,
272 const GValue * value, GParamSpec * pspec)
274 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
277 case PROP_CHECK_FRAME_CHECKSUMS:
278 flacparse->check_frame_checksums = g_value_get_boolean (value);
281 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
287 gst_flac_parse_get_property (GObject * object, guint prop_id,
288 GValue * value, GParamSpec * pspec)
290 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
293 case PROP_CHECK_FRAME_CHECKSUMS:
294 g_value_set_boolean (value, flacparse->check_frame_checksums);
297 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
303 gst_flac_parse_reset (GstFlacParse * parser)
306 gst_tag_list_unref (parser->tags);
310 gst_toc_unref (parser->toc);
313 if (parser->seektable) {
314 gst_buffer_unref (parser->seektable);
315 parser->seektable = NULL;
318 g_list_foreach (parser->headers, (GFunc) gst_mini_object_unref, NULL);
319 g_list_free (parser->headers);
320 parser->headers = NULL;
321 parser->header_size = 0;
322 parser->byte_mode = FALSE;
326 gst_flac_parse_finalize (GObject * object)
328 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
330 gst_flac_parse_reset (flacparse);
331 G_OBJECT_CLASS (parent_class)->finalize (object);
335 gst_flac_parse_start (GstBaseParse * parse)
337 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
339 flacparse->state = GST_FLAC_PARSE_STATE_INIT;
340 flacparse->min_blocksize = 0;
341 flacparse->max_blocksize = 0;
342 flacparse->min_framesize = 0;
343 flacparse->max_framesize = 0;
345 flacparse->upstream_length = -1;
347 flacparse->samplerate = 0;
348 flacparse->channels = 0;
350 flacparse->total_samples = 0;
352 flacparse->offset = GST_CLOCK_TIME_NONE;
353 flacparse->blocking_strategy = 0;
354 flacparse->block_size = 0;
355 flacparse->sample_number = 0;
356 flacparse->strategy_checked = FALSE;
358 flacparse->sent_codec_tag = FALSE;
361 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
363 /* inform baseclass we can come up with ts, based on counters in packets */
364 gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
365 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);
371 gst_flac_parse_stop (GstBaseParse * parse)
373 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
375 gst_flac_parse_reset (flacparse);
379 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
381 static const guint16 blocksize_table[16] = {
382 0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
383 256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
387 static const guint32 sample_rate_table[16] = {
389 88200, 176400, 192000,
390 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
397 FRAME_HEADER_INVALID,
398 FRAME_HEADER_MORE_DATA
399 } FrameHeaderCheckReturn;
401 static FrameHeaderCheckReturn
402 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
403 const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
406 GstBitReader reader = GST_BIT_READER_INIT (data, size);
407 guint8 blocking_strategy;
409 guint32 samplerate = 0;
410 guint64 sample_number;
411 guint8 channels, bps;
413 guint8 actual_crc, expected_crc = 0;
415 /* Skip 14 bit sync code */
416 gst_bit_reader_skip_unchecked (&reader, 14);
419 if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
422 /* 0 == fixed block size, 1 == variable block size */
423 blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
424 if (flacparse->force_variable_block_size)
425 blocking_strategy = 1;
427 /* block size index, calculation of the real blocksize below */
428 block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
432 /* sample rate index, calculation of the real samplerate below */
433 samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
434 if (samplerate == 0x0f)
437 /* channel assignment */
438 channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
441 } else if (channels <= 10) {
443 } else if (channels > 10) {
446 if (flacparse->channels && flacparse->channels != channels)
449 /* bits per sample */
450 bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
451 if (bps == 0x03 || bps == 0x07) {
453 } else if (bps == 0 && flacparse->bps == 0) {
454 goto need_streaminfo;
456 bps = sample_size_table[bps];
457 if (flacparse->bps && bps != flacparse->bps)
460 /* reserved, must be 0 */
461 if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
464 /* read "utf8" encoded sample/frame number */
468 len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
470 /* This is slightly faster than a loop */
474 } else if ((len & 0xc0) && !(len & 0x20)) {
475 sample_number = len & 0x1f;
477 } else if ((len & 0xe0) && !(len & 0x10)) {
478 sample_number = len & 0x0f;
480 } else if ((len & 0xf0) && !(len & 0x08)) {
481 sample_number = len & 0x07;
483 } else if ((len & 0xf8) && !(len & 0x04)) {
484 sample_number = len & 0x03;
486 } else if ((len & 0xfc) && !(len & 0x02)) {
487 sample_number = len & 0x01;
489 } else if ((len & 0xfe) && !(len & 0x01)) {
490 sample_number = len & 0x0;
496 if ((blocking_strategy == 0 && len > 5) ||
497 (blocking_strategy == 1 && len > 6))
501 if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
504 if ((tmp & 0xc0) != 0x80)
508 sample_number |= (tmp & 0x3f);
513 /* calculate real blocksize from the blocksize index */
514 if (block_size == 6) {
515 if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
518 } else if (block_size == 7) {
519 if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
523 block_size = blocksize_table[block_size];
526 /* calculate the real samplerate from the samplerate index */
527 if (samplerate == 0 && flacparse->samplerate == 0) {
528 goto need_streaminfo;
529 } else if (samplerate < 12) {
530 samplerate = sample_rate_table[samplerate];
531 } else if (samplerate == 12) {
532 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
535 } else if (samplerate == 13) {
536 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
538 } else if (samplerate == 14) {
539 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
544 if (flacparse->samplerate && flacparse->samplerate != samplerate)
547 /* check crc-8 for the header */
548 if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
552 gst_flac_calculate_crc8 (data,
553 (gst_bit_reader_get_pos (&reader) / 8) - 1);
554 if (actual_crc != expected_crc) {
555 GST_DEBUG_OBJECT (flacparse,
556 "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
557 expected_crc, actual_crc);
561 /* Sanity check sample number against blocking strategy, as it seems
562 some files claim fixed block size but supply sample numbers,
563 rather than block numbers. */
564 if (blocking_strategy == 0 && flacparse->block_size != 0) {
565 if (!flacparse->strategy_checked) {
566 if (block_size == sample_number) {
567 GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
568 "but seems to be lying: assuming variable block size");
569 flacparse->force_variable_block_size = TRUE;
570 blocking_strategy = 1;
572 flacparse->strategy_checked = TRUE;
576 /* documentation says:
577 * The "blocking strategy" bit must be the same throughout the entire stream. */
578 if (flacparse->blocking_strategy != blocking_strategy) {
579 if (flacparse->block_size != 0) {
580 GST_WARNING_OBJECT (flacparse, "blocking strategy is not constant");
587 The FLAC format documentation says:
588 The "blocking strategy" bit determines how to calculate the sample number
589 of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
590 frame header encodes the frame number as above, and the frame's starting
591 sample number will be the frame number times the blocksize. If it is 1
592 (variable-blocksize), the frame header encodes the frame's starting
593 sample number itself. (In the case of a fixed-blocksize stream, only the
594 last block may be shorter than the stream blocksize; its starting sample
595 number will be calculated as the frame number times the previous frame's
596 blocksize, or zero if it is the first frame).
598 Therefore, when in fixed block size mode, we only update the block size
599 the first time, then reuse that block size for subsequent calls.
600 This will also fix a timestamp problem with the last block's timestamp
601 being miscalculated by scaling the block number by a "wrong" block size.
603 if (blocking_strategy == 0) {
604 if (flacparse->block_size != 0) {
605 /* after first block */
606 if (flacparse->block_size != block_size) {
607 /* TODO: can we know we're on the last frame, to avoid warning ? */
608 GST_WARNING_OBJECT (flacparse, "Block size is not constant");
609 block_size = flacparse->block_size;
617 flacparse->block_size = block_size;
618 if (!flacparse->samplerate)
619 flacparse->samplerate = samplerate;
621 flacparse->bps = bps;
622 if (!flacparse->blocking_strategy)
623 flacparse->blocking_strategy = blocking_strategy;
624 if (!flacparse->channels)
625 flacparse->channels = channels;
626 if (!flacparse->sample_number)
627 flacparse->sample_number = sample_number;
629 GST_DEBUG_OBJECT (flacparse,
630 "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
631 "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
632 flacparse->block_size, flacparse->sample_number);
636 *block_size_ret = block_size;
638 return FRAME_HEADER_VALID;
641 GST_ERROR_OBJECT (flacparse, "Need STREAMINFO metadata. Bits per sample "
642 "or sample rate not in frame header");
644 return FRAME_HEADER_INVALID;
647 return FRAME_HEADER_MORE_DATA;
651 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
652 const guint8 * data, gsize size, guint * ret)
654 guint max, remaining;
655 guint i, search_start, search_end;
656 FrameHeaderCheckReturn header_ret;
658 gboolean suspect_start = FALSE, suspect_end = FALSE;
660 if (size < flacparse->min_framesize)
664 gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
665 &block_size, &suspect_start);
666 if (header_ret == FRAME_HEADER_INVALID) {
670 if (header_ret == FRAME_HEADER_MORE_DATA)
673 /* mind unknown framesize */
674 search_start = MAX (2, flacparse->min_framesize);
675 if (flacparse->max_framesize)
676 search_end = MIN (size, flacparse->max_framesize + 9 + 2);
683 for (i = search_start; i < search_end; i++, remaining--) {
685 if ((GST_READ_UINT16_BE (data + i) & 0xfffe) != 0xfff8)
688 GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
691 gst_flac_parse_frame_header_is_valid (flacparse, data + i,
692 remaining, FALSE, NULL, &suspect_end);
693 if (header_ret == FRAME_HEADER_VALID) {
694 if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
695 guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
696 guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);
698 GST_LOG_OBJECT (flacparse,
699 "Found possible frame (%d, %d). Checking for CRC match",
700 suspect_start, suspect_end);
701 if (actual_crc != expected_crc) {
702 GST_DEBUG_OBJECT (flacparse,
703 "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
704 expected_crc, actual_crc);
709 flacparse->block_size = block_size;
711 } else if (header_ret == FRAME_HEADER_MORE_DATA) {
716 /* For the last frame output everything to the end */
717 if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
718 if (flacparse->check_frame_checksums) {
719 guint16 actual_crc = gst_flac_calculate_crc16 (data, size - 2);
720 guint16 expected_crc = GST_READ_UINT16_BE (data + size - 2);
722 if (actual_crc == expected_crc) {
724 flacparse->block_size = block_size;
729 flacparse->block_size = block_size;
734 /* so we searched to expected end and found nothing,
735 * give up on this frame (start) */
736 if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
737 GST_LOG_OBJECT (flacparse,
738 "could not determine valid frame end, discarding frame (start)");
744 max = flacparse->max_framesize + 16;
747 *ret = MIN (size + 4096, max);
752 gst_flac_parse_handle_frame (GstBaseParse * parse,
753 GstBaseParseFrame * frame, gint * skipsize)
755 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
756 GstBuffer *buffer = frame->buffer;
758 gboolean result = TRUE;
759 GstFlowReturn ret = GST_FLOW_OK;
762 gst_buffer_map (buffer, &map, GST_MAP_READ);
766 if (G_UNLIKELY (map.size < 4)) {
771 if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
772 if (memcmp (map.data, "fLaC", 4) == 0) {
773 GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
777 if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
778 GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
779 /* Minimal size of a frame header */
780 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
781 flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
786 GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
791 if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
792 guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
794 GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
796 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), framesize);
800 if (flacparse->byte_mode && flacparse->byte_offset < flacparse->header_size) {
802 framesize = map.size;
804 } else if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
805 gboolean ret, is_first = !flacparse->strategy_checked;
808 flacparse->offset = GST_BUFFER_OFFSET (buffer);
809 flacparse->blocking_strategy = 0;
810 flacparse->sample_number = 0;
812 GST_DEBUG_OBJECT (flacparse, "Found sync code");
813 ret = gst_flac_parse_frame_is_valid (flacparse, map.data, map.size, &next);
816 GST_INFO_OBJECT (flacparse, "First sample number is %" G_GUINT64_FORMAT,
817 flacparse->sample_number);
818 flacparse->first_sample_number = flacparse->sample_number;
824 /* If we're at EOS and the frame was not valid, drop it! */
825 if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
826 GST_WARNING_OBJECT (flacparse, "EOS");
832 } else if (next > map.size) {
833 GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
835 gst_base_parse_set_min_frame_size (parse, next);
839 GST_ERROR_OBJECT (flacparse,
840 "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
845 GstByteReader reader;
848 gst_byte_reader_init (&reader, map.data, map.size);
850 gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
854 GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
860 GST_DEBUG_OBJECT (flacparse, "Sync code not found");
861 *skipsize = map.size - 3;
869 gst_buffer_unmap (buffer, &map);
874 if (result && framesize <= map.size) {
875 ret = gst_flac_parse_parse_frame (parse, frame, framesize);
876 if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
877 frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
880 if (ret == GST_FLOW_OK)
881 ret = gst_base_parse_finish_frame (parse, frame, framesize);
888 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
893 gst_buffer_map (buffer, &map, GST_MAP_READ);
894 gst_bit_reader_init (&reader, map.data, map.size);
896 if (map.size != 4 + 34) {
897 GST_ERROR_OBJECT (flacparse,
898 "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
902 /* Skip metadata block header */
903 if (!gst_bit_reader_skip (&reader, 32))
906 if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
908 if (flacparse->min_blocksize < 16) {
909 GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
910 flacparse->min_blocksize);
913 if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
915 if (flacparse->max_blocksize < 16) {
916 GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
917 flacparse->max_blocksize);
920 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
922 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
925 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
927 if (flacparse->samplerate == 0) {
928 GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
932 if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
934 flacparse->channels++;
935 if (flacparse->channels > 8) {
936 GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
937 flacparse->channels);
941 if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
945 if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
947 if (flacparse->total_samples) {
948 gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
949 GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
952 gst_buffer_unmap (buffer, &map);
954 GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
955 "\tmin/max blocksize: %u/%u,\n"
956 "\tmin/max framesize: %u/%u,\n"
957 "\tsamplerate: %u,\n"
959 "\tbits per sample: %u,\n"
960 "\ttotal samples: %" G_GUINT64_FORMAT,
961 flacparse->min_blocksize, flacparse->max_blocksize,
962 flacparse->min_framesize, flacparse->max_framesize,
963 flacparse->samplerate,
964 flacparse->channels, flacparse->bps, flacparse->total_samples);
969 GST_ERROR_OBJECT (flacparse, "Failed to read data");
971 gst_buffer_unmap (buffer, &map);
976 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
982 gst_buffer_map (buffer, &map, GST_MAP_READ);
985 gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
986 gst_buffer_unmap (buffer, &map);
989 GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
990 } else if (gst_tag_list_is_empty (tags)) {
991 gst_tag_list_unref (tags);
992 } else if (flacparse->tags == NULL) {
993 flacparse->tags = tags;
995 gst_tag_list_insert (flacparse->tags, tags, GST_TAG_MERGE_APPEND);
996 gst_tag_list_unref (tags);
1003 gst_flac_parse_handle_cuesheet (GstFlacParse * flacparse, GstBuffer * buffer)
1005 GstByteReader reader;
1008 guint8 n_tracks, track_num, index;
1015 GstTocEntry *cur_entry = NULL, *prev_entry = NULL;
1017 gst_buffer_map (buffer, &map, GST_MAP_READ);
1018 gst_byte_reader_init (&reader, map.data, map.size);
1020 toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1022 /* skip 4 bytes METADATA_BLOCK_HEADER */
1023 /* https://xiph.org/flac/format.html#metadata_block_header */
1024 if (!gst_byte_reader_skip (&reader, 4))
1027 /* skip 395 bytes from METADATA_BLOCK_CUESHEET */
1028 /* https://xiph.org/flac/format.html#metadata_block_cuesheet */
1029 if (!gst_byte_reader_skip (&reader, 395))
1032 if (!gst_byte_reader_get_uint8 (&reader, &n_tracks))
1035 /* CUESHEET_TRACK */
1036 /* https://xiph.org/flac/format.html#cuesheet_track */
1037 for (i = 0; i < n_tracks; i++) {
1038 if (!gst_byte_reader_get_uint64_be (&reader, &offset))
1040 if (!gst_byte_reader_get_uint8 (&reader, &track_num))
1043 if (gst_byte_reader_get_remaining (&reader) < 12)
1045 memcpy (isrc, map.data + gst_byte_reader_get_pos (&reader), 12);
1046 /* \0-terminate the string */
1048 if (!gst_byte_reader_skip (&reader, 12))
1051 /* skip 14 bytes from CUESHEET_TRACK */
1052 if (!gst_byte_reader_skip (&reader, 14))
1054 if (!gst_byte_reader_get_uint8 (&reader, &index))
1056 /* add tracks in TOC */
1057 /* lead-out tack has number 170 or 255 */
1058 if (track_num != 170 && track_num != 255) {
1059 prev_entry = cur_entry;
1060 /* previous track stop time = current track start time */
1061 if (prev_entry != NULL) {
1062 gst_toc_entry_get_start_stop_times (prev_entry, &start, NULL);
1064 gst_util_uint64_scale_round (offset, GST_SECOND,
1065 flacparse->samplerate);
1066 gst_toc_entry_set_start_stop_times (prev_entry, start, stop);
1068 id = g_strdup_printf ("%08x", track_num);
1069 cur_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, id);
1072 gst_util_uint64_scale_round (offset, GST_SECOND,
1073 flacparse->samplerate);
1074 gst_toc_entry_set_start_stop_times (cur_entry, start, -1);
1075 /* add ISRC as tag in track */
1076 if (strlen (isrc) != 0) {
1077 tags = gst_tag_list_new_empty ();
1078 gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ISRC, isrc, NULL);
1079 gst_toc_entry_set_tags (cur_entry, tags);
1081 gst_toc_append_entry (toc, cur_entry);
1082 /* CUESHEET_TRACK_INDEX */
1083 /* https://xiph.org/flac/format.html#cuesheet_track_index */
1084 for (j = 0; j < index; j++) {
1085 if (!gst_byte_reader_skip (&reader, 12))
1089 /* set stop time in last track */
1091 gst_util_uint64_scale_round (offset, GST_SECOND,
1092 flacparse->samplerate);
1093 gst_toc_entry_set_start_stop_times (cur_entry, start, stop);
1097 /* send data as TOC */
1098 if (!flacparse->toc)
1099 flacparse->toc = toc;
1101 gst_buffer_unmap (buffer, &map);
1105 GST_ERROR_OBJECT (flacparse, "Error reading data");
1106 gst_buffer_unmap (buffer, &map);
1111 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
1113 GstByteReader reader;
1115 guint32 img_len = 0, img_type = 0;
1116 guint32 img_mimetype_len = 0, img_description_len = 0;
1118 gst_buffer_map (buffer, &map, GST_MAP_READ);
1119 gst_byte_reader_init (&reader, map.data, map.size);
1121 if (!gst_byte_reader_skip (&reader, 4))
1124 if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
1127 if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
1129 if (!gst_byte_reader_skip (&reader, img_mimetype_len))
1132 if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
1134 if (!gst_byte_reader_skip (&reader, img_description_len))
1137 if (!gst_byte_reader_skip (&reader, 4 * 4))
1140 if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
1143 if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
1146 GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);
1149 if (flacparse->tags == NULL)
1150 flacparse->tags = gst_tag_list_new_empty ();
1152 gst_tag_list_add_id3_image (flacparse->tags,
1153 map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
1156 gst_buffer_unmap (buffer, &map);
1160 GST_ERROR_OBJECT (flacparse, "Error reading data");
1161 gst_buffer_unmap (buffer, &map);
1166 gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
1169 GST_DEBUG_OBJECT (flacparse, "storing seektable");
1170 /* only store for now;
1171 * offset of the first frame is needed to get real info */
1172 if (flacparse->seektable)
1173 gst_buffer_unref (flacparse->seektable);
1174 flacparse->seektable = gst_buffer_ref (buffer);
1180 gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
1183 gint64 offset = 0, samples = 0;
1186 GST_DEBUG_OBJECT (flacparse,
1187 "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);
1192 gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
1193 gst_byte_reader_init (&br, map.data, map.size);
1196 if (!gst_byte_reader_skip (&br, 4))
1200 while (gst_byte_reader_get_remaining (&br)) {
1201 if (!gst_byte_reader_get_int64_be (&br, &samples))
1203 if (!gst_byte_reader_get_int64_be (&br, &offset))
1205 if (!gst_byte_reader_skip (&br, 2))
1208 GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
1209 G_GINT64_FORMAT, samples, offset);
1212 if (G_LIKELY (offset > 0 && samples > 0)) {
1213 gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
1214 boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
1215 flacparse->samplerate), TRUE, FALSE);
1220 gst_buffer_unmap (flacparse->seektable, &map);
1222 gst_buffer_unref (flacparse->seektable);
1223 flacparse->seektable = NULL;
1227 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
1229 GValue value = { 0, };
1231 g_value_init (&value, GST_TYPE_BUFFER);
1232 /* copy buffer to avoid problems with circular refcounts */
1233 buf = gst_buffer_copy (buf);
1234 /* again, for good measure */
1235 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1236 gst_value_set_buffer (&value, buf);
1237 gst_buffer_unref (buf);
1238 gst_value_array_append_value (array_val, &value);
1239 g_value_unset (&value);
1242 static GstFlowReturn
1243 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
1245 GstBuffer *vorbiscomment = NULL;
1246 GstBuffer *streaminfo = NULL;
1247 GstBuffer *marker = NULL;
1248 GValue array = { 0, };
1251 GstFlowReturn res = GST_FLOW_OK;
1253 caps = gst_caps_new_simple ("audio/x-flac",
1254 "channels", G_TYPE_INT, flacparse->channels,
1255 "framed", G_TYPE_BOOLEAN, TRUE,
1256 "rate", G_TYPE_INT, flacparse->samplerate, NULL);
1258 if (!flacparse->headers)
1261 for (l = flacparse->headers; l; l = l->next) {
1262 GstBuffer *header = l->data;
1265 gst_buffer_map (header, &map, GST_MAP_READ);
1267 GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);
1269 if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
1271 } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
1272 streaminfo = header;
1273 } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
1274 vorbiscomment = header;
1277 gst_buffer_unmap (header, &map);
1280 /* at least this one we can generate easily
1281 * to provide full headers downstream */
1282 if (vorbiscomment == NULL && streaminfo != NULL) {
1283 GST_DEBUG_OBJECT (flacparse,
1284 "missing vorbiscomment header; generating dummy");
1285 vorbiscomment = gst_flac_parse_generate_vorbiscomment (flacparse);
1286 flacparse->headers = g_list_insert (flacparse->headers, vorbiscomment,
1287 g_list_index (flacparse->headers, streaminfo) + 1);
1290 if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
1291 GST_WARNING_OBJECT (flacparse,
1292 "missing header %p %p %p, muxing into container "
1293 "formats may be broken", marker, streaminfo, vorbiscomment);
1297 g_value_init (&array, GST_TYPE_ARRAY);
1299 /* add marker including STREAMINFO header */
1303 GstMapInfo sinfomap, writemap;
1305 gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);
1307 /* minus one for the marker that is merged with streaminfo here */
1308 num = g_list_length (flacparse->headers) - 1;
1310 buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
1311 gst_buffer_map (buf, &writemap, GST_MAP_WRITE);
1313 writemap.data[0] = 0x7f;
1314 memcpy (writemap.data + 1, "FLAC", 4);
1315 writemap.data[5] = 0x01; /* mapping version major */
1316 writemap.data[6] = 0x00; /* mapping version minor */
1317 writemap.data[7] = (num & 0xFF00) >> 8;
1318 writemap.data[8] = (num & 0x00FF) >> 0;
1319 memcpy (writemap.data + 9, "fLaC", 4);
1320 memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
1321 _value_array_append_buffer (&array, buf);
1323 gst_buffer_unmap (streaminfo, &sinfomap);
1324 gst_buffer_unmap (buf, &writemap);
1325 gst_buffer_unref (buf);
1328 /* add VORBISCOMMENT header */
1329 _value_array_append_buffer (&array, vorbiscomment);
1331 /* add other headers, if there are any */
1332 for (l = flacparse->headers; l; l = l->next) {
1333 if (GST_BUFFER_CAST (l->data) != marker &&
1334 GST_BUFFER_CAST (l->data) != streaminfo &&
1335 GST_BUFFER_CAST (l->data) != vorbiscomment) {
1336 _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
1340 gst_structure_set_value (gst_caps_get_structure (caps, 0),
1341 "streamheader", &array);
1342 g_value_unset (&array);
1346 gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
1347 gst_caps_unref (caps);
1349 /* push header buffers; update caps, so when we push the first buffer the
1350 * negotiated caps will change to caps that include the streamheader field */
1351 flacparse->header_size = 0;
1352 while (flacparse->headers) {
1353 GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
1354 GstBaseParseFrame frame;
1356 flacparse->headers =
1357 g_list_delete_link (flacparse->headers, flacparse->headers);
1358 buf = gst_buffer_make_writable (buf);
1360 /* init, set and give away frame */
1361 gst_base_parse_frame_init (&frame);
1363 frame.overhead = -1;
1364 flacparse->header_size += gst_buffer_get_size (frame.buffer);
1365 res = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
1366 gst_base_parse_frame_free (&frame);
1367 if (res != GST_FLOW_OK)
1370 g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
1371 g_list_free (flacparse->headers);
1372 flacparse->headers = NULL;
1373 flacparse->byte_offset = flacparse->header_size;
1378 /* empty vorbiscomment */
1380 gst_flac_parse_generate_vorbiscomment (GstFlacParse * flacparse)
1382 GstTagList *taglist = gst_tag_list_new_empty ();
1385 GstBuffer *vorbiscomment;
1388 header[0] = 0x84; /* is_last = 1; type = 4; */
1391 gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1392 sizeof (header), NULL);
1393 gst_tag_list_unref (taglist);
1395 gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1397 /* Get rid of framing bit */
1398 if (map.data[map.size - 1] == 1) {
1402 gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
1404 gst_buffer_unmap (vorbiscomment, &map);
1405 gst_buffer_unref (vorbiscomment);
1406 vorbiscomment = sub;
1407 gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1410 size = map.size - 4;
1411 map.data[1] = ((size & 0xFF0000) >> 16);
1412 map.data[2] = ((size & 0x00FF00) >> 8);
1413 map.data[3] = (size & 0x0000FF);
1414 gst_buffer_unmap (vorbiscomment, &map);
1415 gst_flac_parse_reset_buffer_time_and_offset (vorbiscomment);
1417 return vorbiscomment;
1421 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1423 GstBuffer *marker, *streaminfo;
1426 marker = gst_buffer_new_and_alloc (4);
1427 gst_buffer_map (marker, &map, GST_MAP_WRITE);
1428 memcpy (map.data, "fLaC", 4);
1429 gst_buffer_unmap (marker, &map);
1430 gst_flac_parse_reset_buffer_time_and_offset (marker);
1431 flacparse->headers = g_list_append (flacparse->headers, marker);
1433 streaminfo = gst_buffer_new_and_alloc (4 + 34);
1434 gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
1435 memset (map.data, 0, 4 + 34);
1437 /* metadata block header */
1438 map.data[0] = 0x00; /* is_last = 0; type = 0; */
1439 map.data[1] = 0x00; /* length = 34; */
1445 map.data[4] = (flacparse->block_size >> 8) & 0xff; /* min blocksize = blocksize; */
1446 map.data[5] = (flacparse->block_size) & 0xff;
1447 map.data[6] = (flacparse->block_size >> 8) & 0xff; /* max blocksize = blocksize; */
1448 map.data[7] = (flacparse->block_size) & 0xff;
1450 map.data[8] = 0x00; /* min framesize = 0; */
1452 map.data[10] = 0x00;
1453 map.data[11] = 0x00; /* max framesize = 0; */
1454 map.data[12] = 0x00;
1455 map.data[13] = 0x00;
1457 map.data[14] = (flacparse->samplerate >> 12) & 0xff;
1458 map.data[15] = (flacparse->samplerate >> 4) & 0xff;
1459 map.data[16] = (flacparse->samplerate >> 0) & 0xf0;
1461 map.data[16] |= (flacparse->channels - 1) << 1;
1463 map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1464 map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1469 if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
1470 GST_FORMAT_TIME, &duration) && duration != -1) {
1471 duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1473 map.data[17] |= (duration >> 32) & 0xff;
1474 map.data[18] |= (duration >> 24) & 0xff;
1475 map.data[19] |= (duration >> 16) & 0xff;
1476 map.data[20] |= (duration >> 8) & 0xff;
1477 map.data[21] |= (duration >> 0) & 0xff;
1482 gst_buffer_unmap (streaminfo, &map);
1483 gst_flac_parse_reset_buffer_time_and_offset (streaminfo);
1484 flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1486 flacparse->headers = g_list_append (flacparse->headers,
1487 gst_flac_parse_generate_vorbiscomment (flacparse));
1493 gst_flac_parse_reset_buffer_time_and_offset (GstBuffer * buffer)
1495 GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1496 GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1497 GST_BUFFER_OFFSET (buffer) = 0;
1498 GST_BUFFER_OFFSET_END (buffer) = 0;
1501 /* Type 127 is invalid for a metadata block header & should
1502 * be discarded _before_ calling this function */
1504 gst_flac_parse_handle_block_type (GstFlacParse * flacparse, guint type,
1505 GstBuffer * sbuffer)
1507 gboolean ret = TRUE;
1510 case 0: /* STREAMINFO */
1511 GST_INFO_OBJECT (flacparse, "STREAMINFO header");
1512 ret = gst_flac_parse_handle_streaminfo (flacparse, sbuffer);
1514 case 3: /* SEEKTABLE */
1515 GST_INFO_OBJECT (flacparse, "SEEKTABLE header");
1516 ret = gst_flac_parse_handle_seektable (flacparse, sbuffer);
1518 case 4: /* VORBIS_COMMENT */
1519 GST_INFO_OBJECT (flacparse, "VORBISCOMMENT header");
1520 ret = gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer);
1522 case 5: /* CUESHEET */
1523 GST_INFO_OBJECT (flacparse, "CUESHEET header");
1524 ret = gst_flac_parse_handle_cuesheet (flacparse, sbuffer);
1526 case 6: /* PICTURE */
1527 GST_INFO_OBJECT (flacparse, "PICTURE header");
1528 ret = gst_flac_parse_handle_picture (flacparse, sbuffer);
1530 case 1: /* PADDING */
1531 GST_INFO_OBJECT (flacparse, "PADDING header");
1533 case 2: /* APPLICATION */
1534 GST_INFO_OBJECT (flacparse, "APPLICATION header");
1536 default: /* RESERVED */
1537 GST_INFO_OBJECT (flacparse, "Unhandled metadata header type '%u'", type);
1538 GST_FIXME_OBJECT (flacparse, "FLAC version might not be fully supported");
1545 static GstFlowReturn
1546 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
1549 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1550 GstBuffer *buffer = frame->buffer, *sbuffer;
1552 GstFlowReturn res = GST_FLOW_ERROR;
1553 guint64 relative_sample_number;
1555 gst_buffer_map (buffer, &map, GST_MAP_READ);
1557 if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1558 sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1559 gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1561 /* 32 bits metadata block */
1562 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1563 flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1565 flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1567 res = GST_BASE_PARSE_FLOW_DROPPED;
1568 } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1569 gboolean is_last = map.data[0] >> 7;
1570 guint type = (map.data[0] & 0x7F);
1573 GST_WARNING_OBJECT (flacparse, "Invalid metadata block type 127");
1574 res = GST_BASE_PARSE_FLOW_DROPPED;
1578 GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1580 sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1582 if (gst_flac_parse_handle_block_type (flacparse, type, sbuffer)) {
1583 gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1584 flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1586 GST_WARNING_OBJECT (parse, "failed to parse header of type %u", type);
1587 GST_MEMDUMP_OBJECT (parse, "bad header data", map.data, size);
1589 gst_buffer_unref (sbuffer);
1591 /* error out unless we have a STREAMINFO header */
1592 if (flacparse->samplerate == 0 || flacparse->bps == 0)
1593 goto header_parsing_error;
1595 /* .. in which case just stop header parsing and try to find audio */
1600 res = gst_flac_parse_handle_headers (flacparse);
1602 /* Minimal size of a frame header */
1603 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1604 flacparse->min_framesize));
1605 flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1607 if (res != GST_FLOW_OK)
1611 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1614 /* DROPPED because we pushed already or will push all headers manually */
1615 res = GST_BASE_PARSE_FLOW_DROPPED;
1617 if (flacparse->byte_mode && flacparse->byte_offset < flacparse->header_size) {
1622 if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1623 FrameHeaderCheckReturn ret;
1625 flacparse->offset = GST_BUFFER_OFFSET (buffer);
1627 gst_flac_parse_frame_header_is_valid (flacparse,
1628 map.data, map.size, TRUE, NULL, NULL);
1629 if (ret != FRAME_HEADER_VALID) {
1630 GST_ERROR_OBJECT (flacparse,
1631 "Baseclass didn't provide a complete frame");
1636 if (flacparse->block_size == 0) {
1637 GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1641 if (flacparse->seektable)
1642 gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));
1644 if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1645 if (flacparse->blocking_strategy == 1) {
1646 GST_WARNING_OBJECT (flacparse,
1647 "Generating headers for variable blocksize streams not supported");
1649 res = gst_flac_parse_handle_headers (flacparse);
1651 GST_DEBUG_OBJECT (flacparse, "Generating headers");
1653 if (!gst_flac_parse_generate_headers (flacparse))
1656 res = gst_flac_parse_handle_headers (flacparse);
1658 flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1659 if (res != GST_FLOW_OK)
1663 /* also cater for oggmux metadata */
1664 relative_sample_number =
1665 flacparse->sample_number - flacparse->first_sample_number;
1666 if (flacparse->blocking_strategy == 0) {
1667 GST_BUFFER_PTS (buffer) =
1668 gst_util_uint64_scale (relative_sample_number,
1669 flacparse->block_size * GST_SECOND, flacparse->samplerate);
1670 GST_BUFFER_OFFSET_END (buffer) =
1671 relative_sample_number * flacparse->block_size +
1672 flacparse->block_size;
1674 GST_BUFFER_PTS (buffer) =
1675 gst_util_uint64_scale (relative_sample_number, GST_SECOND,
1676 flacparse->samplerate);
1677 GST_BUFFER_OFFSET_END (buffer) =
1678 relative_sample_number + flacparse->block_size;
1681 GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
1682 GST_BUFFER_OFFSET (buffer) =
1683 gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
1684 flacparse->samplerate);
1685 GST_BUFFER_DURATION (buffer) =
1686 GST_BUFFER_OFFSET (buffer) - GST_BUFFER_PTS (buffer);
1688 /* To simplify, we just assume that it's a fixed size header and ignore
1689 * subframe headers. The first could lead us to be off by 88 bits and
1690 * the second even less, so the total inaccuracy is negligible. */
1691 frame->overhead = 7;
1693 /* Minimal size of a frame header */
1694 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1695 flacparse->min_framesize));
1697 flacparse->offset = -1;
1698 flacparse->blocking_strategy = 0;
1699 flacparse->sample_number = 0;
1704 gst_buffer_unmap (buffer, &map);
1707 header_parsing_error:
1708 GST_ELEMENT_ERROR (flacparse, STREAM, DECODE, (NULL),
1709 ("Failed to parse headers"));
1713 static GstFlowReturn
1714 gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1716 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1718 if (!flacparse->sent_codec_tag) {
1721 if (flacparse->tags == NULL)
1722 flacparse->tags = gst_tag_list_new_empty ();
1725 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1726 if (G_UNLIKELY (caps == NULL)) {
1727 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1728 GST_INFO_OBJECT (parse, "Src pad is flushing");
1729 return GST_FLOW_FLUSHING;
1731 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1732 return GST_FLOW_NOT_NEGOTIATED;
1734 gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
1735 GST_TAG_AUDIO_CODEC, caps);
1736 gst_caps_unref (caps);
1738 /* Announce our pending tags */
1739 gst_base_parse_merge_tags (parse, flacparse->tags, GST_TAG_MERGE_REPLACE);
1741 /* also signals the end of first-frame processing */
1742 flacparse->sent_codec_tag = TRUE;
1746 if (flacparse->toc) {
1747 gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
1748 gst_event_new_toc (flacparse->toc, FALSE));
1751 frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1753 flacparse->byte_offset += gst_buffer_get_size (frame->buffer);
1759 gst_flac_parse_convert (GstBaseParse * parse,
1760 GstFormat src_format, gint64 src_value, GstFormat dest_format,
1761 gint64 * dest_value)
1763 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1765 if (flacparse->samplerate > 0) {
1766 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1767 if (src_value != -1)
1769 gst_util_uint64_scale (src_value, GST_SECOND,
1770 flacparse->samplerate);
1774 } else if (src_format == GST_FORMAT_TIME &&
1775 dest_format == GST_FORMAT_DEFAULT) {
1776 if (src_value != -1)
1778 gst_util_uint64_scale (src_value, flacparse->samplerate,
1786 return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
1787 src_value, dest_format, dest_value);
1791 gst_flac_parse_sink_event (GstBaseParse * parse, GstEvent * event)
1793 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1794 const GstSegment *segment;
1796 switch (GST_EVENT_TYPE (event)) {
1797 case GST_EVENT_SEGMENT:
1799 gst_event_parse_segment (event, &segment);
1800 flacparse->byte_mode = (segment->format == GST_FORMAT_BYTES)
1801 && flacparse->header_size > 0;
1802 if (flacparse->byte_mode) {
1803 /* we must pass every header update now */
1804 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 0);
1805 /* we must drain any pending data before the seek */
1806 gst_base_parse_drain (parse);
1807 flacparse->byte_offset = segment->start;
1808 return gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (parse), event);
1815 return GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
1819 gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1821 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1822 gboolean res = FALSE;
1824 switch (GST_EVENT_TYPE (event)) {
1825 case GST_EVENT_TOC_SELECT:
1827 GstTocEntry *entry = NULL;
1828 GstEvent *seek_event;
1833 /* FIXME: some locking would be good */
1835 toc = gst_toc_ref (flacparse->toc);
1838 gst_event_parse_toc_select (event, &uid);
1840 entry = gst_toc_find_entry (toc, uid);
1841 if (entry != NULL) {
1842 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
1844 /* FIXME: use segment rate here instead? */
1845 seek_event = gst_event_new_seek (1.0,
1847 GST_SEEK_FLAG_FLUSH,
1848 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);
1851 GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
1855 GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
1859 gst_toc_unref (toc);
1861 GST_DEBUG_OBJECT (flacparse, "no TOC to select");
1863 gst_event_unref (event);
1867 res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1874 remove_fields (GstCaps * caps)
1878 n = gst_caps_get_size (caps);
1879 for (i = 0; i < n; i++) {
1880 GstStructure *s = gst_caps_get_structure (caps, i);
1882 gst_structure_remove_field (s, "framed");
1887 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
1889 GstCaps *peercaps, *templ;
1892 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1894 GstCaps *fcopy = gst_caps_copy (filter);
1895 /* Remove the fields we convert */
1896 remove_fields (fcopy);
1897 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1898 gst_caps_unref (fcopy);
1900 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1903 /* Remove the framed field */
1904 peercaps = gst_caps_make_writable (peercaps);
1905 remove_fields (peercaps);
1907 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1908 gst_caps_unref (peercaps);
1909 gst_caps_unref (templ);
1915 GstCaps *intersection;
1918 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1919 gst_caps_unref (res);