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
27 * @see_also: flacdec, oggdemux, vorbisparse
29 * The flacparse element will parse the header packets of the FLAC
30 * stream and put them as the streamheader in the caps. This is used in the
31 * multifdsink case where you want to stream live FLAC streams to multiple
32 * clients, each client has to receive the streamheaders first before they can
33 * consume the FLAC packets.
35 * This element also makes sure that the buffers that it pushes out are properly
36 * timestamped and that their offset and offset_end are set. The buffers that
37 * flacparse outputs have all of the metadata that oggmux expects to receive,
38 * which allows you to (for example) remux an ogg/flac or convert a native FLAC
39 * format file to an ogg bitstream.
41 * ## Example pipelines
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.
55 #include "gstaudioparserselements.h"
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 *
187 flacparse, gboolean is_last);
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_src_event (GstBaseParse * parse,
213 static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
215 static gboolean gst_flac_parse_set_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);
220 GST_ELEMENT_REGISTER_DEFINE (flacparse, "flacparse",
221 GST_RANK_PRIMARY + 1, GST_TYPE_FLAC_PARSE);
224 gst_flac_parse_class_init (GstFlacParseClass * klass)
226 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
227 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
228 GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);
230 GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
231 "Flac parser element");
233 gobject_class->finalize = gst_flac_parse_finalize;
234 gobject_class->set_property = gst_flac_parse_set_property;
235 gobject_class->get_property = gst_flac_parse_get_property;
237 g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
238 g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
239 "Check the overall checksums of every frame",
240 DEFAULT_CHECK_FRAME_CHECKSUMS,
241 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
243 baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
244 baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
245 baseparse_class->handle_frame =
246 GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
247 baseparse_class->pre_push_frame =
248 GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
249 baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
250 baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
251 baseparse_class->get_sink_caps =
252 GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
253 baseparse_class->set_sink_caps =
254 GST_DEBUG_FUNCPTR (gst_flac_parse_set_sink_caps);
256 gst_element_class_add_static_pad_template (element_class, &src_factory);
257 gst_element_class_add_static_pad_template (element_class, &sink_factory);
259 gst_element_class_set_static_metadata (element_class, "FLAC audio parser",
260 "Codec/Parser/Audio",
261 "Parses audio with the FLAC lossless audio codec",
262 "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
266 gst_flac_parse_init (GstFlacParse * flacparse)
268 flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
269 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (flacparse));
270 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (flacparse));
274 gst_flac_parse_set_property (GObject * object, guint prop_id,
275 const GValue * value, GParamSpec * pspec)
277 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
280 case PROP_CHECK_FRAME_CHECKSUMS:
281 flacparse->check_frame_checksums = g_value_get_boolean (value);
284 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
290 gst_flac_parse_get_property (GObject * object, guint prop_id,
291 GValue * value, GParamSpec * pspec)
293 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
296 case PROP_CHECK_FRAME_CHECKSUMS:
297 g_value_set_boolean (value, flacparse->check_frame_checksums);
300 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
306 gst_flac_parse_reset (GstFlacParse * parser)
309 gst_tag_list_unref (parser->tags);
313 gst_toc_unref (parser->toc);
316 if (parser->seektable) {
317 gst_buffer_unref (parser->seektable);
318 parser->seektable = NULL;
321 g_list_foreach (parser->headers, (GFunc) gst_mini_object_unref, NULL);
322 g_list_free (parser->headers);
323 parser->headers = NULL;
327 gst_flac_parse_finalize (GObject * object)
329 GstFlacParse *flacparse = GST_FLAC_PARSE (object);
331 gst_flac_parse_reset (flacparse);
332 G_OBJECT_CLASS (parent_class)->finalize (object);
336 gst_flac_parse_start (GstBaseParse * parse)
338 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
340 flacparse->state = GST_FLAC_PARSE_STATE_INIT;
341 flacparse->min_blocksize = 0;
342 flacparse->max_blocksize = 0;
343 flacparse->min_framesize = 0;
344 flacparse->max_framesize = 0;
346 flacparse->upstream_length = -1;
348 flacparse->samplerate = 0;
349 flacparse->channels = 0;
351 flacparse->total_samples = 0;
353 flacparse->offset = GST_CLOCK_TIME_NONE;
354 flacparse->blocking_strategy = 0;
355 flacparse->block_size = 0;
356 flacparse->sample_number = 0;
357 flacparse->strategy_checked = FALSE;
359 flacparse->sent_codec_tag = FALSE;
362 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
364 /* inform baseclass we can come up with ts, based on counters in packets */
365 gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
366 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);
372 gst_flac_parse_stop (GstBaseParse * parse)
374 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
376 gst_flac_parse_reset (flacparse);
380 static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };
382 static const guint16 blocksize_table[16] = {
383 0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
384 256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
388 static const guint32 sample_rate_table[16] = {
390 88200, 176400, 192000,
391 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
398 FRAME_HEADER_INVALID,
399 FRAME_HEADER_MORE_DATA
400 } FrameHeaderCheckReturn;
402 static FrameHeaderCheckReturn
403 gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
404 const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
407 GstBitReader reader = GST_BIT_READER_INIT (data, size);
408 guint8 blocking_strategy;
410 guint32 samplerate = 0;
411 guint64 sample_number;
412 guint8 channels, bps;
414 guint8 actual_crc, expected_crc = 0;
416 /* Skip 14 bit sync code */
417 gst_bit_reader_skip_unchecked (&reader, 14);
420 if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
423 /* 0 == fixed block size, 1 == variable block size */
424 blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
425 if (flacparse->force_variable_block_size)
426 blocking_strategy = 1;
428 /* block size index, calculation of the real blocksize below */
429 block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
433 /* sample rate index, calculation of the real samplerate below */
434 samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
435 if (samplerate == 0x0f)
438 /* channel assignment */
439 channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
442 } else if (channels <= 10) {
444 } else if (channels > 10) {
447 if (flacparse->channels && flacparse->channels != channels)
450 /* bits per sample */
451 bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
452 if (bps == 0x03 || bps == 0x07) {
454 } else if (bps == 0 && flacparse->bps == 0) {
455 goto need_streaminfo;
457 bps = sample_size_table[bps];
458 if (flacparse->bps && bps != flacparse->bps)
461 /* reserved, must be 0 */
462 if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
465 /* read "utf8" encoded sample/frame number */
469 len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);
471 /* This is slightly faster than a loop */
475 } else if ((len & 0xc0) && !(len & 0x20)) {
476 sample_number = len & 0x1f;
478 } else if ((len & 0xe0) && !(len & 0x10)) {
479 sample_number = len & 0x0f;
481 } else if ((len & 0xf0) && !(len & 0x08)) {
482 sample_number = len & 0x07;
484 } else if ((len & 0xf8) && !(len & 0x04)) {
485 sample_number = len & 0x03;
487 } else if ((len & 0xfc) && !(len & 0x02)) {
488 sample_number = len & 0x01;
490 } else if ((len & 0xfe) && !(len & 0x01)) {
491 sample_number = len & 0x0;
497 if ((blocking_strategy == 0 && len > 5) ||
498 (blocking_strategy == 1 && len > 6))
502 if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
505 if ((tmp & 0xc0) != 0x80)
509 sample_number |= (tmp & 0x3f);
514 /* calculate real blocksize from the blocksize index */
515 if (block_size == 6) {
516 if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
519 } else if (block_size == 7) {
520 if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
524 block_size = blocksize_table[block_size];
527 /* calculate the real samplerate from the samplerate index */
528 if (samplerate == 0 && flacparse->samplerate == 0) {
529 goto need_streaminfo;
530 } else if (samplerate < 12) {
531 samplerate = sample_rate_table[samplerate];
532 } else if (samplerate == 12) {
533 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
536 } else if (samplerate == 13) {
537 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
539 } else if (samplerate == 14) {
540 if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
545 if (flacparse->samplerate && flacparse->samplerate != samplerate)
548 /* check crc-8 for the header */
549 if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
553 gst_flac_calculate_crc8 (data,
554 (gst_bit_reader_get_pos (&reader) / 8) - 1);
555 if (actual_crc != expected_crc) {
556 GST_DEBUG_OBJECT (flacparse,
557 "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
558 expected_crc, actual_crc);
562 /* Sanity check sample number against blocking strategy, as it seems
563 some files claim fixed block size but supply sample numbers,
564 rather than block numbers. */
565 if (blocking_strategy == 0 && flacparse->block_size != 0) {
566 if (!flacparse->strategy_checked) {
567 if (block_size == sample_number) {
568 GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
569 "but seems to be lying: assuming variable block size");
570 flacparse->force_variable_block_size = TRUE;
571 blocking_strategy = 1;
573 flacparse->strategy_checked = TRUE;
577 /* documentation says:
578 * The "blocking strategy" bit must be the same throughout the entire stream. */
579 if (flacparse->blocking_strategy != blocking_strategy) {
580 if (flacparse->block_size != 0) {
581 GST_WARNING_OBJECT (flacparse, "blocking strategy is not constant");
588 The FLAC format documentation says:
589 The "blocking strategy" bit determines how to calculate the sample number
590 of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
591 frame header encodes the frame number as above, and the frame's starting
592 sample number will be the frame number times the blocksize. If it is 1
593 (variable-blocksize), the frame header encodes the frame's starting
594 sample number itself. (In the case of a fixed-blocksize stream, only the
595 last block may be shorter than the stream blocksize; its starting sample
596 number will be calculated as the frame number times the previous frame's
597 blocksize, or zero if it is the first frame).
599 Therefore, when in fixed block size mode, we only update the block size
600 the first time, then reuse that block size for subsequent calls.
601 This will also fix a timestamp problem with the last block's timestamp
602 being miscalculated by scaling the block number by a "wrong" block size.
604 if (blocking_strategy == 0) {
605 if (flacparse->block_size != 0) {
606 /* after first block */
607 if (flacparse->block_size != block_size) {
608 /* TODO: can we know we're on the last frame, to avoid warning ? */
609 GST_WARNING_OBJECT (flacparse, "Block size is not constant");
610 block_size = flacparse->block_size;
618 flacparse->block_size = block_size;
619 if (!flacparse->samplerate)
620 flacparse->samplerate = samplerate;
622 flacparse->bps = bps;
623 if (!flacparse->blocking_strategy)
624 flacparse->blocking_strategy = blocking_strategy;
625 if (!flacparse->channels)
626 flacparse->channels = channels;
627 if (!flacparse->sample_number)
628 flacparse->sample_number = sample_number;
630 GST_DEBUG_OBJECT (flacparse,
631 "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
632 "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
633 flacparse->block_size, flacparse->sample_number);
637 *block_size_ret = block_size;
639 return FRAME_HEADER_VALID;
642 GST_ERROR_OBJECT (flacparse, "Need STREAMINFO metadata. Bits per sample "
643 "or sample rate not in frame header");
645 return FRAME_HEADER_INVALID;
648 return FRAME_HEADER_MORE_DATA;
652 gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
653 const guint8 * data, gsize size, guint * ret)
655 guint max, remaining;
656 guint i, search_start, search_end;
657 FrameHeaderCheckReturn header_ret;
659 gboolean suspect_start = FALSE, suspect_end = FALSE;
661 if (size < flacparse->min_framesize)
665 gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
666 &block_size, &suspect_start);
667 if (header_ret == FRAME_HEADER_INVALID) {
671 if (header_ret == FRAME_HEADER_MORE_DATA)
674 /* mind unknown framesize */
675 search_start = MAX (2, flacparse->min_framesize);
676 if (flacparse->max_framesize)
677 search_end = MIN (size, flacparse->max_framesize + 9 + 2);
684 for (i = search_start; i < search_end; i++, remaining--) {
686 if ((GST_READ_UINT16_BE (data + i) & 0xfffe) != 0xfff8)
689 GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
692 gst_flac_parse_frame_header_is_valid (flacparse, data + i,
693 remaining, FALSE, NULL, &suspect_end);
694 if (header_ret == FRAME_HEADER_VALID) {
695 if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
696 guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
697 guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);
699 GST_LOG_OBJECT (flacparse,
700 "Found possible frame (%d, %d). Checking for CRC match",
701 suspect_start, suspect_end);
702 if (actual_crc != expected_crc) {
703 GST_DEBUG_OBJECT (flacparse,
704 "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
705 expected_crc, actual_crc);
710 flacparse->block_size = block_size;
712 } else if (header_ret == FRAME_HEADER_MORE_DATA) {
717 /* For the last frame output everything to the end */
718 if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
719 if (flacparse->check_frame_checksums) {
720 guint16 actual_crc = gst_flac_calculate_crc16 (data, size - 2);
721 guint16 expected_crc = GST_READ_UINT16_BE (data + size - 2);
723 if (actual_crc == expected_crc) {
725 flacparse->block_size = block_size;
730 flacparse->block_size = block_size;
735 /* so we searched to expected end and found nothing,
736 * give up on this frame (start) */
737 if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
738 GST_LOG_OBJECT (flacparse,
739 "could not determine valid frame end, discarding frame (start)");
745 max = flacparse->max_framesize + 16;
748 *ret = MIN (size + 4096, max);
753 gst_flac_parse_handle_frame (GstBaseParse * parse,
754 GstBaseParseFrame * frame, gint * skipsize)
756 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
757 GstBuffer *buffer = frame->buffer;
759 gboolean result = TRUE;
760 GstFlowReturn ret = GST_FLOW_OK;
763 gst_buffer_map (buffer, &map, GST_MAP_READ);
767 if (G_UNLIKELY (map.size < 4)) {
772 if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
773 if (memcmp (map.data, "fLaC", 4) == 0) {
774 GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
778 if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
779 GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
780 /* Minimal size of a frame header */
781 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
782 flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
787 GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
792 if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
793 guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));
795 GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
797 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), framesize);
801 if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
802 gboolean ret, is_first = !flacparse->strategy_checked;
805 flacparse->offset = GST_BUFFER_OFFSET (buffer);
806 flacparse->blocking_strategy = 0;
807 flacparse->sample_number = 0;
809 GST_DEBUG_OBJECT (flacparse, "Found sync code");
810 ret = gst_flac_parse_frame_is_valid (flacparse, map.data, map.size, &next);
813 GST_INFO_OBJECT (flacparse, "First sample number is %" G_GUINT64_FORMAT,
814 flacparse->sample_number);
815 flacparse->first_sample_number = flacparse->sample_number;
821 /* If we're at EOS and the frame was not valid, drop it! */
822 if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
823 GST_WARNING_OBJECT (flacparse, "EOS");
829 } else if (next > map.size) {
830 GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
832 gst_base_parse_set_min_frame_size (parse, next);
836 GST_ERROR_OBJECT (flacparse,
837 "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
842 GstByteReader reader;
845 gst_byte_reader_init (&reader, map.data, map.size);
847 gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
851 GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
857 GST_DEBUG_OBJECT (flacparse, "Sync code not found");
858 *skipsize = map.size - 3;
866 gst_buffer_unmap (buffer, &map);
871 if (result && framesize <= map.size) {
872 ret = gst_flac_parse_parse_frame (parse, frame, framesize);
873 if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
874 frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
877 if (ret == GST_FLOW_OK)
878 ret = gst_base_parse_finish_frame (parse, frame, framesize);
885 gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
890 gst_buffer_map (buffer, &map, GST_MAP_READ);
891 gst_bit_reader_init (&reader, map.data, map.size);
893 if (map.size != 4 + 34) {
894 GST_ERROR_OBJECT (flacparse,
895 "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
899 /* Skip metadata block header */
900 if (!gst_bit_reader_skip (&reader, 32))
903 if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
905 if (flacparse->min_blocksize < 16) {
906 GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
907 flacparse->min_blocksize);
910 if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
912 if (flacparse->max_blocksize < 16) {
913 GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
914 flacparse->max_blocksize);
917 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
919 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
922 if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
924 if (flacparse->samplerate == 0) {
925 GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
929 if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
931 flacparse->channels++;
932 if (flacparse->channels > 8) {
933 GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
934 flacparse->channels);
938 if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
942 if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
944 if (flacparse->total_samples) {
945 gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
946 GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
949 gst_buffer_unmap (buffer, &map);
951 GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
952 "\tmin/max blocksize: %u/%u,\n"
953 "\tmin/max framesize: %u/%u,\n"
954 "\tsamplerate: %u,\n"
956 "\tbits per sample: %u,\n"
957 "\ttotal samples: %" G_GUINT64_FORMAT,
958 flacparse->min_blocksize, flacparse->max_blocksize,
959 flacparse->min_framesize, flacparse->max_framesize,
960 flacparse->samplerate,
961 flacparse->channels, flacparse->bps, flacparse->total_samples);
966 GST_ERROR_OBJECT (flacparse, "Failed to read data");
968 gst_buffer_unmap (buffer, &map);
973 gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
979 gst_buffer_map (buffer, &map, GST_MAP_READ);
982 gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
983 gst_buffer_unmap (buffer, &map);
986 GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
987 } else if (gst_tag_list_is_empty (tags)) {
988 gst_tag_list_unref (tags);
989 } else if (flacparse->tags == NULL) {
990 flacparse->tags = tags;
992 gst_tag_list_insert (flacparse->tags, tags, GST_TAG_MERGE_APPEND);
993 gst_tag_list_unref (tags);
1000 gst_flac_parse_handle_cuesheet (GstFlacParse * flacparse, GstBuffer * buffer)
1002 GstByteReader reader;
1005 guint8 n_tracks, track_num, index;
1012 GstTocEntry *cur_entry = NULL, *prev_entry = NULL;
1014 gst_buffer_map (buffer, &map, GST_MAP_READ);
1015 gst_byte_reader_init (&reader, map.data, map.size);
1017 toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
1019 /* skip 4 bytes METADATA_BLOCK_HEADER */
1020 /* https://xiph.org/flac/format.html#metadata_block_header */
1021 if (!gst_byte_reader_skip (&reader, 4))
1024 /* skip 395 bytes from METADATA_BLOCK_CUESHEET */
1025 /* https://xiph.org/flac/format.html#metadata_block_cuesheet */
1026 if (!gst_byte_reader_skip (&reader, 395))
1029 if (!gst_byte_reader_get_uint8 (&reader, &n_tracks))
1032 /* CUESHEET_TRACK */
1033 /* https://xiph.org/flac/format.html#cuesheet_track */
1034 for (i = 0; i < n_tracks; i++) {
1035 if (!gst_byte_reader_get_uint64_be (&reader, &offset))
1037 if (!gst_byte_reader_get_uint8 (&reader, &track_num))
1040 if (gst_byte_reader_get_remaining (&reader) < 12)
1042 memcpy (isrc, map.data + gst_byte_reader_get_pos (&reader), 12);
1043 /* \0-terminate the string */
1045 if (!gst_byte_reader_skip (&reader, 12))
1048 /* skip 14 bytes from CUESHEET_TRACK */
1049 if (!gst_byte_reader_skip (&reader, 14))
1051 if (!gst_byte_reader_get_uint8 (&reader, &index))
1053 /* add tracks in TOC */
1054 /* lead-out tack has number 170 or 255 */
1055 if (track_num != 170 && track_num != 255) {
1056 prev_entry = cur_entry;
1057 /* previous track stop time = current track start time */
1058 if (prev_entry != NULL) {
1059 gst_toc_entry_get_start_stop_times (prev_entry, &start, NULL);
1061 gst_util_uint64_scale_round (offset, GST_SECOND,
1062 flacparse->samplerate);
1063 gst_toc_entry_set_start_stop_times (prev_entry, start, stop);
1065 id = g_strdup_printf ("%08x", track_num);
1066 cur_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, id);
1069 gst_util_uint64_scale_round (offset, GST_SECOND,
1070 flacparse->samplerate);
1071 gst_toc_entry_set_start_stop_times (cur_entry, start, -1);
1072 /* add ISRC as tag in track */
1073 if (strlen (isrc) != 0) {
1074 tags = gst_tag_list_new_empty ();
1075 gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ISRC, isrc, NULL);
1076 gst_toc_entry_set_tags (cur_entry, tags);
1078 gst_toc_append_entry (toc, cur_entry);
1079 /* CUESHEET_TRACK_INDEX */
1080 /* https://xiph.org/flac/format.html#cuesheet_track_index */
1081 for (j = 0; j < index; j++) {
1082 if (!gst_byte_reader_skip (&reader, 12))
1086 /* set stop time in last track */
1088 gst_util_uint64_scale_round (offset, GST_SECOND,
1089 flacparse->samplerate);
1090 gst_toc_entry_set_start_stop_times (cur_entry, start, stop);
1094 /* send data as TOC */
1095 if (!flacparse->toc)
1096 flacparse->toc = toc;
1098 gst_buffer_unmap (buffer, &map);
1102 GST_ERROR_OBJECT (flacparse, "Error reading data");
1103 gst_buffer_unmap (buffer, &map);
1108 gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
1110 GstByteReader reader;
1112 guint32 img_len = 0, img_type = 0;
1113 guint32 img_mimetype_len = 0, img_description_len = 0;
1115 gst_buffer_map (buffer, &map, GST_MAP_READ);
1116 gst_byte_reader_init (&reader, map.data, map.size);
1118 if (!gst_byte_reader_skip (&reader, 4))
1121 if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
1124 if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
1126 if (!gst_byte_reader_skip (&reader, img_mimetype_len))
1129 if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
1131 if (!gst_byte_reader_skip (&reader, img_description_len))
1134 if (!gst_byte_reader_skip (&reader, 4 * 4))
1137 if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
1140 if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
1143 GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);
1146 if (flacparse->tags == NULL)
1147 flacparse->tags = gst_tag_list_new_empty ();
1149 gst_tag_list_add_id3_image (flacparse->tags,
1150 map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
1153 gst_buffer_unmap (buffer, &map);
1157 GST_ERROR_OBJECT (flacparse, "Error reading data");
1158 gst_buffer_unmap (buffer, &map);
1163 gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
1166 GST_DEBUG_OBJECT (flacparse, "storing seektable");
1167 /* only store for now;
1168 * offset of the first frame is needed to get real info */
1169 if (flacparse->seektable)
1170 gst_buffer_unref (flacparse->seektable);
1171 flacparse->seektable = gst_buffer_ref (buffer);
1177 gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
1180 gint64 offset = 0, samples = 0;
1183 GST_DEBUG_OBJECT (flacparse,
1184 "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);
1189 gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
1190 gst_byte_reader_init (&br, map.data, map.size);
1193 if (!gst_byte_reader_skip (&br, 4))
1197 while (gst_byte_reader_get_remaining (&br)) {
1198 if (!gst_byte_reader_get_int64_be (&br, &samples))
1200 if (!gst_byte_reader_get_int64_be (&br, &offset))
1202 if (!gst_byte_reader_skip (&br, 2))
1205 GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
1206 G_GINT64_FORMAT, samples, offset);
1209 if (G_LIKELY (offset > 0 && samples > 0)) {
1210 gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
1211 boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
1212 flacparse->samplerate), TRUE, FALSE);
1217 gst_buffer_unmap (flacparse->seektable, &map);
1219 gst_buffer_unref (flacparse->seektable);
1220 flacparse->seektable = NULL;
1224 _value_array_append_buffer (GValue * array_val, GstBuffer * buf)
1226 GValue value = { 0, };
1228 g_value_init (&value, GST_TYPE_BUFFER);
1229 /* copy buffer to avoid problems with circular refcounts */
1230 buf = gst_buffer_copy (buf);
1231 /* again, for good measure */
1232 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1233 gst_value_set_buffer (&value, buf);
1234 gst_buffer_unref (buf);
1235 gst_value_array_append_value (array_val, &value);
1236 g_value_unset (&value);
1239 static GstFlowReturn
1240 gst_flac_parse_handle_headers (GstFlacParse * flacparse)
1242 GstBuffer *vorbiscomment = NULL;
1243 GstBuffer *streaminfo = NULL;
1244 GstBuffer *marker = NULL;
1245 GValue array = { 0, };
1248 GstFlowReturn res = GST_FLOW_OK;
1249 gboolean is_streaminfo_last = FALSE;
1251 caps = gst_caps_new_simple ("audio/x-flac",
1252 "channels", G_TYPE_INT, flacparse->channels,
1253 "framed", G_TYPE_BOOLEAN, TRUE,
1254 "rate", G_TYPE_INT, flacparse->samplerate, NULL);
1256 if (!flacparse->headers)
1259 for (l = flacparse->headers; l; l = l->next) {
1260 GstBuffer *header = l->data;
1263 gst_buffer_map (header, &map, GST_MAP_READ);
1265 GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);
1267 if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
1269 } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
1270 streaminfo = header;
1271 is_streaminfo_last = (map.data[0] & 0x80) != 0;
1272 } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
1273 vorbiscomment = header;
1276 gst_buffer_unmap (header, &map);
1279 /* at least this one we can generate easily
1280 * to provide full headers downstream */
1281 if (vorbiscomment == NULL && streaminfo != NULL) {
1282 GST_DEBUG_OBJECT (flacparse,
1283 "missing vorbiscomment header; generating dummy");
1284 /* this vorbiscomment header is inserted after streaminfo and inherits its last-metadata-block flag */
1286 gst_flac_parse_generate_vorbiscomment (flacparse, is_streaminfo_last);
1287 flacparse->headers =
1288 g_list_insert (flacparse->headers, vorbiscomment,
1289 g_list_index (flacparse->headers, streaminfo) + 1);
1292 if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
1293 GST_WARNING_OBJECT (flacparse,
1294 "missing header %p %p %p, muxing into container "
1295 "formats may be broken", marker, streaminfo, vorbiscomment);
1299 g_value_init (&array, GST_TYPE_ARRAY);
1301 /* add marker including STREAMINFO header */
1305 GstMapInfo sinfomap, writemap;
1307 gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);
1309 /* minus one for the marker that is merged with streaminfo here */
1310 num = g_list_length (flacparse->headers) - 1;
1312 buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
1313 gst_buffer_map (buf, &writemap, GST_MAP_WRITE);
1315 writemap.data[0] = 0x7f;
1316 memcpy (writemap.data + 1, "FLAC", 4);
1317 writemap.data[5] = 0x01; /* mapping version major */
1318 writemap.data[6] = 0x00; /* mapping version minor */
1319 writemap.data[7] = (num & 0xFF00) >> 8;
1320 writemap.data[8] = (num & 0x00FF) >> 0;
1321 memcpy (writemap.data + 9, "fLaC", 4);
1322 memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
1323 /* clear the last-metadata-block flag because a VORBISCOMMENT always follows */
1324 writemap.data[13] = 0x00; /* is_last = 0; type = 0; */
1325 _value_array_append_buffer (&array, buf);
1327 gst_buffer_unmap (streaminfo, &sinfomap);
1328 gst_buffer_unmap (buf, &writemap);
1329 gst_buffer_unref (buf);
1332 /* add other headers, including VORBISCOMMENT */
1333 for (l = flacparse->headers; l; l = l->next) {
1334 if (GST_BUFFER_CAST (l->data) != marker &&
1335 GST_BUFFER_CAST (l->data) != streaminfo) {
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 while (flacparse->headers) {
1352 GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
1353 GstBaseParseFrame frame;
1355 flacparse->headers =
1356 g_list_delete_link (flacparse->headers, flacparse->headers);
1357 buf = gst_buffer_make_writable (buf);
1359 /* init, set and give away frame */
1360 gst_base_parse_frame_init (&frame);
1362 frame.overhead = -1;
1363 res = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
1364 gst_base_parse_frame_free (&frame);
1365 if (res != GST_FLOW_OK)
1368 g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
1369 g_list_free (flacparse->headers);
1370 flacparse->headers = NULL;
1375 /* empty vorbiscomment */
1377 gst_flac_parse_generate_vorbiscomment (GstFlacParse * flacparse,
1380 GstTagList *taglist = gst_tag_list_new_empty ();
1383 GstBuffer *vorbiscomment;
1386 header[0] = (is_last ? 0x80 : 0x00) | 0x04; /* is_last may vary; type = 4; */
1389 gst_tag_list_to_vorbiscomment_buffer (taglist, header,
1390 sizeof (header), NULL);
1391 gst_tag_list_unref (taglist);
1393 gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1395 /* Get rid of framing bit */
1396 if (map.data[map.size - 1] == 1) {
1400 gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
1402 gst_buffer_unmap (vorbiscomment, &map);
1403 gst_buffer_unref (vorbiscomment);
1404 vorbiscomment = sub;
1405 gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
1408 size = map.size - 4;
1409 map.data[1] = ((size & 0xFF0000) >> 16);
1410 map.data[2] = ((size & 0x00FF00) >> 8);
1411 map.data[3] = (size & 0x0000FF);
1412 gst_buffer_unmap (vorbiscomment, &map);
1413 gst_flac_parse_reset_buffer_time_and_offset (vorbiscomment);
1415 return vorbiscomment;
1419 gst_flac_parse_generate_headers (GstFlacParse * flacparse)
1421 GstBuffer *marker, *streaminfo;
1424 marker = gst_buffer_new_and_alloc (4);
1425 gst_buffer_map (marker, &map, GST_MAP_WRITE);
1426 memcpy (map.data, "fLaC", 4);
1427 gst_buffer_unmap (marker, &map);
1428 gst_flac_parse_reset_buffer_time_and_offset (marker);
1429 flacparse->headers = g_list_append (flacparse->headers, marker);
1431 streaminfo = gst_buffer_new_and_alloc (4 + 34);
1432 gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
1433 memset (map.data, 0, 4 + 34);
1435 /* metadata block header */
1436 map.data[0] = 0x00; /* is_last = 0; type = 0; */
1437 map.data[1] = 0x00; /* length = 34; */
1443 map.data[4] = (flacparse->block_size >> 8) & 0xff; /* min blocksize = blocksize; */
1444 map.data[5] = (flacparse->block_size) & 0xff;
1445 map.data[6] = (flacparse->block_size >> 8) & 0xff; /* max blocksize = blocksize; */
1446 map.data[7] = (flacparse->block_size) & 0xff;
1448 map.data[8] = 0x00; /* min framesize = 0; */
1450 map.data[10] = 0x00;
1451 map.data[11] = 0x00; /* max framesize = 0; */
1452 map.data[12] = 0x00;
1453 map.data[13] = 0x00;
1455 map.data[14] = (flacparse->samplerate >> 12) & 0xff;
1456 map.data[15] = (flacparse->samplerate >> 4) & 0xff;
1457 map.data[16] = (flacparse->samplerate >> 0) & 0xf0;
1459 map.data[16] |= (flacparse->channels - 1) << 1;
1461 map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
1462 map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;
1467 if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
1468 GST_FORMAT_TIME, &duration) && duration != -1) {
1469 duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);
1471 map.data[17] |= (duration >> 32) & 0xff;
1472 map.data[18] |= (duration >> 24) & 0xff;
1473 map.data[19] |= (duration >> 16) & 0xff;
1474 map.data[20] |= (duration >> 8) & 0xff;
1475 map.data[21] |= (duration >> 0) & 0xff;
1480 gst_buffer_unmap (streaminfo, &map);
1481 gst_flac_parse_reset_buffer_time_and_offset (streaminfo);
1482 flacparse->headers = g_list_append (flacparse->headers, streaminfo);
1484 flacparse->headers = g_list_append (flacparse->headers,
1485 gst_flac_parse_generate_vorbiscomment (flacparse, TRUE));
1491 gst_flac_parse_reset_buffer_time_and_offset (GstBuffer * buffer)
1493 GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
1494 GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
1495 GST_BUFFER_OFFSET (buffer) = 0;
1496 GST_BUFFER_OFFSET_END (buffer) = 0;
1499 /* Type 127 is invalid for a metadata block header & should
1500 * be discarded _before_ calling this function */
1502 gst_flac_parse_handle_block_type (GstFlacParse * flacparse, guint type,
1503 GstBuffer * sbuffer)
1505 gboolean ret = TRUE;
1508 case 0: /* STREAMINFO */
1509 GST_INFO_OBJECT (flacparse, "STREAMINFO header");
1510 ret = gst_flac_parse_handle_streaminfo (flacparse, sbuffer);
1512 case 3: /* SEEKTABLE */
1513 GST_INFO_OBJECT (flacparse, "SEEKTABLE header");
1514 ret = gst_flac_parse_handle_seektable (flacparse, sbuffer);
1516 case 4: /* VORBIS_COMMENT */
1517 GST_INFO_OBJECT (flacparse, "VORBISCOMMENT header");
1518 ret = gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer);
1520 case 5: /* CUESHEET */
1521 GST_INFO_OBJECT (flacparse, "CUESHEET header");
1522 ret = gst_flac_parse_handle_cuesheet (flacparse, sbuffer);
1524 case 6: /* PICTURE */
1525 GST_INFO_OBJECT (flacparse, "PICTURE header");
1526 ret = gst_flac_parse_handle_picture (flacparse, sbuffer);
1528 case 1: /* PADDING */
1529 GST_INFO_OBJECT (flacparse, "PADDING header");
1531 case 2: /* APPLICATION */
1532 GST_INFO_OBJECT (flacparse, "APPLICATION header");
1534 default: /* RESERVED */
1535 GST_INFO_OBJECT (flacparse, "Unhandled metadata header type '%u'", type);
1536 GST_FIXME_OBJECT (flacparse, "FLAC version might not be fully supported");
1543 static GstFlowReturn
1544 gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
1547 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1548 GstBuffer *buffer = frame->buffer, *sbuffer;
1550 GstFlowReturn res = GST_FLOW_ERROR;
1551 guint64 relative_sample_number;
1553 gst_buffer_map (buffer, &map, GST_MAP_READ);
1555 if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
1556 sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1557 gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1559 /* 32 bits metadata block */
1560 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1561 flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;
1563 flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1565 res = GST_BASE_PARSE_FLOW_DROPPED;
1566 } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
1567 gboolean is_last = map.data[0] >> 7;
1568 guint type = (map.data[0] & 0x7F);
1571 GST_WARNING_OBJECT (flacparse, "Invalid metadata block type 127");
1572 res = GST_BASE_PARSE_FLOW_DROPPED;
1576 GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);
1578 sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
1580 if (gst_flac_parse_handle_block_type (flacparse, type, sbuffer)) {
1581 gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
1582 flacparse->headers = g_list_append (flacparse->headers, sbuffer);
1584 GST_WARNING_OBJECT (parse, "failed to parse header of type %u", type);
1585 GST_MEMDUMP_OBJECT (parse, "bad header data", map.data, size);
1587 gst_buffer_unref (sbuffer);
1589 /* error out unless we have a STREAMINFO header */
1590 if (flacparse->samplerate == 0 || flacparse->bps == 0)
1591 goto header_parsing_error;
1593 /* .. in which case just stop header parsing and try to find audio */
1598 res = gst_flac_parse_handle_headers (flacparse);
1600 /* Minimal size of a frame header */
1601 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1602 flacparse->min_framesize));
1603 flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1605 if (res != GST_FLOW_OK)
1609 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
1612 /* DROPPED because we pushed already or will push all headers manually */
1613 res = GST_BASE_PARSE_FLOW_DROPPED;
1615 if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
1616 FrameHeaderCheckReturn ret;
1618 flacparse->offset = GST_BUFFER_OFFSET (buffer);
1620 gst_flac_parse_frame_header_is_valid (flacparse,
1621 map.data, map.size, TRUE, NULL, NULL);
1622 if (ret != FRAME_HEADER_VALID) {
1623 GST_ERROR_OBJECT (flacparse,
1624 "Baseclass didn't provide a complete frame");
1629 if (flacparse->block_size == 0) {
1630 GST_ERROR_OBJECT (flacparse, "Unparsed frame");
1634 if (flacparse->seektable)
1635 gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));
1637 if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
1638 if (flacparse->blocking_strategy == 1) {
1639 GST_WARNING_OBJECT (flacparse,
1640 "Generating headers for variable blocksize streams not supported");
1642 res = gst_flac_parse_handle_headers (flacparse);
1644 GST_DEBUG_OBJECT (flacparse, "Generating headers");
1646 if (!gst_flac_parse_generate_headers (flacparse))
1649 res = gst_flac_parse_handle_headers (flacparse);
1651 flacparse->state = GST_FLAC_PARSE_STATE_DATA;
1652 if (res != GST_FLOW_OK)
1656 /* also cater for oggmux metadata */
1657 relative_sample_number =
1658 flacparse->sample_number - flacparse->first_sample_number;
1659 if (flacparse->blocking_strategy == 0) {
1660 GST_BUFFER_PTS (buffer) =
1661 gst_util_uint64_scale (relative_sample_number,
1662 flacparse->block_size * GST_SECOND, flacparse->samplerate);
1663 GST_BUFFER_OFFSET_END (buffer) =
1664 relative_sample_number * flacparse->block_size +
1665 flacparse->block_size;
1667 GST_BUFFER_PTS (buffer) =
1668 gst_util_uint64_scale (relative_sample_number, GST_SECOND,
1669 flacparse->samplerate);
1670 GST_BUFFER_OFFSET_END (buffer) =
1671 relative_sample_number + flacparse->block_size;
1674 GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
1675 GST_BUFFER_OFFSET (buffer) =
1676 gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
1677 flacparse->samplerate);
1678 GST_BUFFER_DURATION (buffer) =
1679 GST_BUFFER_OFFSET (buffer) - GST_BUFFER_PTS (buffer);
1681 /* To simplify, we just assume that it's a fixed size header and ignore
1682 * subframe headers. The first could lead us to be off by 88 bits and
1683 * the second even less, so the total inaccuracy is negligible. */
1684 frame->overhead = 7;
1686 /* Minimal size of a frame header */
1687 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
1688 flacparse->min_framesize));
1690 flacparse->offset = -1;
1691 flacparse->blocking_strategy = 0;
1692 flacparse->sample_number = 0;
1697 gst_buffer_unmap (buffer, &map);
1700 header_parsing_error:
1701 GST_ELEMENT_ERROR (flacparse, STREAM, DECODE, (NULL),
1702 ("Failed to parse headers"));
1706 static GstFlowReturn
1707 gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1709 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1711 if (!flacparse->sent_codec_tag) {
1714 if (flacparse->tags == NULL)
1715 flacparse->tags = gst_tag_list_new_empty ();
1718 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1719 if (G_UNLIKELY (caps == NULL)) {
1720 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1721 GST_INFO_OBJECT (parse, "Src pad is flushing");
1722 return GST_FLOW_FLUSHING;
1724 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1725 return GST_FLOW_NOT_NEGOTIATED;
1727 gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
1728 GST_TAG_AUDIO_CODEC, caps);
1729 gst_caps_unref (caps);
1731 /* Announce our pending tags */
1732 gst_base_parse_merge_tags (parse, flacparse->tags, GST_TAG_MERGE_REPLACE);
1734 /* also signals the end of first-frame processing */
1735 flacparse->sent_codec_tag = TRUE;
1739 if (flacparse->toc) {
1740 gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
1741 gst_event_new_toc (flacparse->toc, FALSE));
1744 frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1750 gst_flac_parse_convert (GstBaseParse * parse,
1751 GstFormat src_format, gint64 src_value, GstFormat dest_format,
1752 gint64 * dest_value)
1754 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1756 if (flacparse->samplerate > 0) {
1757 if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
1758 if (src_value != -1)
1760 gst_util_uint64_scale (src_value, GST_SECOND,
1761 flacparse->samplerate);
1765 } else if (src_format == GST_FORMAT_TIME &&
1766 dest_format == GST_FORMAT_DEFAULT) {
1767 if (src_value != -1)
1769 gst_util_uint64_scale (src_value, flacparse->samplerate,
1777 return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
1778 src_value, dest_format, dest_value);
1782 gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1784 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1785 gboolean res = FALSE;
1787 switch (GST_EVENT_TYPE (event)) {
1788 case GST_EVENT_TOC_SELECT:
1790 GstTocEntry *entry = NULL;
1791 GstEvent *seek_event;
1796 /* FIXME: some locking would be good */
1798 toc = gst_toc_ref (flacparse->toc);
1801 gst_event_parse_toc_select (event, &uid);
1803 entry = gst_toc_find_entry (toc, uid);
1804 if (entry != NULL) {
1805 gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);
1807 /* FIXME: use segment rate here instead? */
1808 seek_event = gst_event_new_seek (1.0,
1810 GST_SEEK_FLAG_FLUSH,
1811 GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);
1814 GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
1818 GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
1822 gst_toc_unref (toc);
1824 GST_DEBUG_OBJECT (flacparse, "no TOC to select");
1826 gst_event_unref (event);
1830 res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1837 remove_fields (GstCaps * caps)
1841 n = gst_caps_get_size (caps);
1842 for (i = 0; i < n; i++) {
1843 GstStructure *s = gst_caps_get_structure (caps, i);
1845 gst_structure_remove_field (s, "framed");
1850 gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
1852 GstCaps *peercaps, *templ;
1855 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1857 GstCaps *fcopy = gst_caps_copy (filter);
1858 /* Remove the fields we convert */
1859 remove_fields (fcopy);
1860 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1861 gst_caps_unref (fcopy);
1863 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1866 /* Remove the framed field */
1867 peercaps = gst_caps_make_writable (peercaps);
1868 remove_fields (peercaps);
1870 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1871 gst_caps_unref (peercaps);
1872 gst_caps_unref (templ);
1878 GstCaps *intersection;
1881 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1882 gst_caps_unref (res);
1890 gst_flac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
1892 GstCaps *current_caps;
1893 GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
1895 /* If caps are changing, drain any pending frames we have so that afterwards
1896 * we can potentially accept a new stream that is starting with the FLAC
1897 * headers again. If headers appear in the middle of the stream we can't
1900 gst_base_parse_drain (parse);
1902 /* If the caps did really change we need to reset the parser */
1903 current_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
1905 if (!gst_caps_is_strictly_equal (caps, current_caps)) {
1906 GST_DEBUG_OBJECT (flacparse, "Reset parser on sink pad caps change");
1907 gst_flac_parse_stop (parse);
1908 gst_flac_parse_start (parse);
1910 gst_caps_unref (current_caps);