1 /* GStreamer AAC parser plugin
2 * Copyright (C) 2008 Nokia Corporation. All rights reserved.
4 * Contact: Stefan Kost <stefan.kost@nokia.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 * SECTION:element-aacparse
24 * @short_description: AAC parser
25 * @see_also: #GstAmrParse
27 * This is an AAC parser which handles both ADIF and ADTS stream formats.
29 * As ADIF format is not framed, it is not seekable and stream duration cannot
30 * be determined either. However, ADTS format AAC clips can be seeked, and parser
31 * can also estimate playback position and clip duration.
34 * <title>Example launch line</title>
36 * gst-launch filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
47 #include "gstaacparse.h"
50 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
53 GST_STATIC_CAPS ("audio/mpeg, "
54 "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
55 "stream-format = (string) { raw, adts, adif };"));
57 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
60 GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) { 2, 4 };"));
62 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
63 #define GST_CAT_DEFAULT aacparse_debug
66 #define ADIF_MAX_SIZE 40 /* Should be enough */
67 #define ADTS_MAX_SIZE 10 /* Should be enough */
70 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
72 static gboolean gst_aac_parse_start (GstBaseParse * parse);
73 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
75 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
77 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse);
79 static gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse,
80 GstBaseParseFrame * frame, guint * size, gint * skipsize);
82 static GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse,
83 GstBaseParseFrame * frame);
85 #define _do_init(bla) \
86 GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0, \
87 "AAC audio stream parser");
89 GST_BOILERPLATE_FULL (GstAacParse, gst_aac_parse, GstBaseParse,
90 GST_TYPE_BASE_PARSE, _do_init);
93 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
95 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
96 32000, 24000, 22050, 16000, 12000, 11025, 8000
99 if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
100 return aac_sample_rates[sr_idx];
101 GST_WARNING ("Invalid sample rate index %u", sr_idx);
106 * gst_aac_parse_base_init:
107 * @klass: #GstElementClass.
111 gst_aac_parse_base_init (gpointer klass)
113 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
115 gst_element_class_add_pad_template (element_class,
116 gst_static_pad_template_get (&sink_template));
117 gst_element_class_add_pad_template (element_class,
118 gst_static_pad_template_get (&src_template));
120 gst_element_class_set_details_simple (element_class,
121 "AAC audio stream parser", "Codec/Parser/Audio",
122 "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
127 * gst_aac_parse_class_init:
128 * @klass: #GstAacParseClass.
132 gst_aac_parse_class_init (GstAacParseClass * klass)
134 GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
136 parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
137 parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
138 parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
139 parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
140 parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_parse_frame);
141 parse_class->check_valid_frame =
142 GST_DEBUG_FUNCPTR (gst_aac_parse_check_valid_frame);
147 * gst_aac_parse_init:
148 * @aacparse: #GstAacParse.
149 * @klass: #GstAacParseClass.
153 gst_aac_parse_init (GstAacParse * aacparse, GstAacParseClass * klass)
155 GST_DEBUG ("initialized");
160 * gst_aac_parse_set_src_caps:
161 * @aacparse: #GstAacParse.
162 * @sink_caps: (proposed) caps of sink pad
164 * Set source pad caps according to current knowledge about the
167 * Returns: TRUE if caps were successfully set.
170 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
173 GstCaps *src_caps = NULL;
174 gboolean res = FALSE;
175 const gchar *stream_format;
177 GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
179 src_caps = gst_caps_copy (sink_caps);
181 src_caps = gst_caps_new_simple ("audio/mpeg", NULL);
183 gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
184 "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
186 switch (aacparse->header_type) {
187 case DSPAAC_HEADER_NONE:
188 stream_format = "raw";
190 case DSPAAC_HEADER_ADTS:
191 stream_format = "adts";
193 case DSPAAC_HEADER_ADIF:
194 stream_format = "adif";
197 stream_format = NULL;
200 s = gst_caps_get_structure (src_caps, 0);
201 if (aacparse->sample_rate > 0)
202 gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
203 if (aacparse->channels > 0)
204 gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
206 gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
208 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
210 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
211 gst_caps_unref (src_caps);
217 * gst_aac_parse_sink_setcaps:
221 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
223 * Returns: TRUE on success.
226 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
228 GstAacParse *aacparse;
229 GstStructure *structure;
233 aacparse = GST_AAC_PARSE (parse);
234 structure = gst_caps_get_structure (caps, 0);
235 caps_str = gst_caps_to_string (caps);
237 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
240 /* This is needed at least in case of RTP
241 * Parses the codec_data information to get ObjectType,
242 * number of channels and samplerate */
243 value = gst_structure_get_value (structure, "codec_data");
245 GstBuffer *buf = gst_value_get_buffer (value);
248 const guint8 *buffer = GST_BUFFER_DATA (buf);
251 sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7);
252 aacparse->object_type = (buffer[0] & 0xf8) >> 3;
253 aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
254 aacparse->channels = (buffer[1] & 0x78) >> 3;
255 aacparse->header_type = DSPAAC_HEADER_NONE;
256 aacparse->mpegversion = 4;
257 aacparse->frame_samples = (buffer[1] & 4) ? 960 : 1024;
259 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
260 "samples=%d", aacparse->object_type, aacparse->sample_rate,
261 aacparse->channels, aacparse->frame_samples);
263 /* arrange for metadata and get out of the way */
264 gst_aac_parse_set_src_caps (aacparse, caps);
265 gst_base_parse_set_passthrough (parse, TRUE);
269 /* caps info overrides */
270 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
271 gst_structure_get_int (structure, "channels", &aacparse->channels);
273 gst_base_parse_set_passthrough (parse, FALSE);
281 * gst_aac_parse_adts_get_frame_len:
282 * @data: block of data containing an ADTS header.
284 * This function calculates ADTS frame length from the given header.
286 * Returns: size of the ADTS frame.
289 gst_aac_parse_adts_get_frame_len (const guint8 * data)
291 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
296 * gst_aac_parse_check_adts_frame:
297 * @aacparse: #GstAacParse.
298 * @data: Data to be checked.
299 * @avail: Amount of data passed.
300 * @framesize: If valid ADTS frame was found, this will be set to tell the
301 * found frame size in bytes.
302 * @needed_data: If frame was not found, this may be set to tell how much
303 * more data is needed in the next round to detect the frame
304 * reliably. This may happen when a frame header candidate
305 * is found but it cannot be guaranteed to be the header without
306 * peeking the following data.
308 * Check if the given data contains contains ADTS frame. The algorithm
309 * will examine ADTS frame header and calculate the frame size. Also, another
310 * consecutive ADTS frame header need to be present after the found frame.
311 * Otherwise the data is not considered as a valid ADTS frame. However, this
312 * "extra check" is omitted when EOS has been received. In this case it is
313 * enough when data[0] contains a valid ADTS header.
315 * This function may set the #needed_data to indicate that a possible frame
316 * candidate has been found, but more data (#needed_data bytes) is needed to
317 * be absolutely sure. When this situation occurs, FALSE will be returned.
319 * When a valid frame is detected, this function will use
320 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
321 * to set the needed bytes for next frame.This way next data chunk is already
324 * Returns: TRUE if the given data contains a valid ADTS header.
327 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
328 const guint8 * data, const guint avail, gboolean drain,
329 guint * framesize, guint * needed_data)
331 if (G_UNLIKELY (avail < 2))
334 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
335 *framesize = gst_aac_parse_adts_get_frame_len (data);
337 /* In EOS mode this is enough. No need to examine the data further.
338 We also relax the check when we have sync, on the assumption that
339 if we're not looking at random data, we have a much higher chance
340 to get the correct sync, and this avoids losing two frames when
341 a single bit corruption happens. */
342 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
346 if (*framesize + ADTS_MAX_SIZE > avail) {
347 /* We have found a possible frame header candidate, but can't be
348 sure since we don't have enough data to check the next frame */
349 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
350 *framesize + ADTS_MAX_SIZE, avail);
351 *needed_data = *framesize + ADTS_MAX_SIZE;
352 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
353 *framesize + ADTS_MAX_SIZE);
357 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
358 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
360 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
361 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
362 nextlen + ADTS_MAX_SIZE);
369 /* caller ensure sufficient data */
371 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
372 gint * rate, gint * channels, gint * object, gint * version)
376 gint sr_idx = (data[2] & 0x3c) >> 2;
378 *rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
381 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
384 *version = (data[1] & 0x08) ? 2 : 4;
386 *object = (data[2] & 0xc0) >> 6;
390 * gst_aac_parse_detect_stream:
391 * @aacparse: #GstAacParse.
392 * @data: A block of data that needs to be examined for stream characteristics.
393 * @avail: Size of the given datablock.
394 * @framesize: If valid stream was found, this will be set to tell the
395 * first frame size in bytes.
396 * @skipsize: If valid stream was found, this will be set to tell the first
397 * audio frame position within the given data.
399 * Examines the given piece of data and try to detect the format of it. It
400 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
401 * header. If the stream is detected, TRUE will be returned and #framesize
402 * is set to indicate the found frame size. Additionally, #skipsize might
403 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
404 * position of the frame inside given data chunk.
406 * Returns: TRUE on success.
409 gst_aac_parse_detect_stream (GstAacParse * aacparse,
410 const guint8 * data, const guint avail, gboolean drain,
411 guint * framesize, gint * skipsize)
413 gboolean found = FALSE;
417 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
419 /* FIXME: No need to check for ADIF if we are not in the beginning of the
422 /* Can we even parse the header? */
423 if (avail < ADTS_MAX_SIZE)
426 for (i = 0; i < avail - 4; i++) {
427 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
428 strncmp ((char *) data + i, "ADIF", 4) == 0) {
432 /* Trick: tell the parent class that we didn't find the frame yet,
433 but make it skip 'i' amount of bytes. Next time we arrive
434 here we have full frame in the beginning of the data. */
447 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
448 framesize, &need_data)) {
451 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
453 aacparse->header_type = DSPAAC_HEADER_ADTS;
454 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
455 &aacparse->object_type, &aacparse->mpegversion);
457 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
458 aacparse->frame_samples, 2, 2);
460 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
461 rate, channels, aacparse->object_type, aacparse->mpegversion);
463 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
466 } else if (need_data) {
467 /* This tells the parent class not to skip any data */
472 if (avail < ADIF_MAX_SIZE)
475 if (memcmp (data + i, "ADIF", 4) == 0) {
481 aacparse->header_type = DSPAAC_HEADER_ADIF;
482 aacparse->mpegversion = 4;
484 /* Skip the "ADIF" bytes */
487 /* copyright string */
489 skip_size += 9; /* skip 9 bytes */
491 bitstream_type = adif[0 + skip_size] & 0x10;
493 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
494 ((unsigned int) adif[1 + skip_size] << 11) |
495 ((unsigned int) adif[2 + skip_size] << 3) |
496 ((unsigned int) adif[3 + skip_size] & 0xe0);
499 if (bitstream_type == 0) {
501 /* Buffer fullness parsing. Currently not needed... */
505 num_elems = (adif[3 + skip_size] & 0x1e);
506 GST_INFO ("ADIF num_config_elems: %d", num_elems);
508 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
509 ((unsigned int) adif[4 + skip_size] << 11) |
510 ((unsigned int) adif[5 + skip_size] << 3) |
511 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
513 GST_INFO ("ADIF buffer fullness: %d", fullness);
515 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
516 ((adif[7 + skip_size] & 0x80) >> 7);
517 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
521 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
522 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
523 ((adif[5 + skip_size] & 0x80) >> 7);
526 /* FIXME: This gives totally wrong results. Duration calculation cannot
528 aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
530 /* baseparse is not given any fps,
531 * so it will give up on timestamps, seeking, etc */
533 /* FIXME: Can we assume this? */
534 aacparse->channels = 2;
536 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
537 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
539 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
541 /* arrange for metadata and get out of the way */
542 gst_aac_parse_set_src_caps (aacparse,
543 GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse)));
545 /* not syncable, not easily seekable (unless we push data from start */
546 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
547 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
548 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
554 /* This should never happen */
560 * gst_aac_parse_check_valid_frame:
561 * @parse: #GstBaseParse.
562 * @buffer: #GstBuffer.
563 * @framesize: If the buffer contains a valid frame, its size will be put here
564 * @skipsize: How much data parent class should skip in order to find the
567 * Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
569 * Returns: TRUE if buffer contains a valid frame.
572 gst_aac_parse_check_valid_frame (GstBaseParse * parse,
573 GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
576 GstAacParse *aacparse;
577 gboolean ret = FALSE;
581 aacparse = GST_AAC_PARSE (parse);
582 buffer = frame->buffer;
583 data = GST_BUFFER_DATA (buffer);
585 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
587 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
588 aacparse->header_type == DSPAAC_HEADER_NONE) {
589 /* There is nothing to parse */
590 *framesize = GST_BUFFER_SIZE (buffer);
593 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
595 ret = gst_aac_parse_detect_stream (aacparse, data, GST_BUFFER_SIZE (buffer),
596 GST_BASE_PARSE_DRAINING (parse), framesize, skipsize);
598 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
599 guint needed_data = 1024;
601 ret = gst_aac_parse_check_adts_frame (aacparse, data,
602 GST_BUFFER_SIZE (buffer), GST_BASE_PARSE_DRAINING (parse),
603 framesize, &needed_data);
606 GST_DEBUG ("buffer didn't contain valid frame");
607 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
612 GST_DEBUG ("buffer didn't contain valid frame");
613 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
622 * gst_aac_parse_parse_frame:
623 * @parse: #GstBaseParse.
624 * @buffer: #GstBuffer.
626 * Implementation of "parse_frame" vmethod in #GstBaseParse class.
628 * Also determines frame overhead.
629 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
630 * a per-frame header.
632 * We're making a couple of simplifying assumptions:
634 * 1. We count Program Configuration Elements rather than searching for them
635 * in the streams to discount them - the overhead is negligible.
637 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
638 * bits, which should still not be significant enough to warrant the
639 * additional parsing through the headers
641 * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed
642 * forward. Otherwise appropriate error is returned.
645 gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
647 GstAacParse *aacparse;
649 GstFlowReturn ret = GST_FLOW_OK;
652 aacparse = GST_AAC_PARSE (parse);
653 buffer = frame->buffer;
655 if (G_UNLIKELY (aacparse->header_type != DSPAAC_HEADER_ADTS))
661 gst_aac_parse_parse_adts_header (aacparse, GST_BUFFER_DATA (buffer),
662 &rate, &channels, NULL, NULL);
663 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
665 if (G_UNLIKELY (rate != aacparse->sample_rate
666 || channels != aacparse->channels)) {
667 aacparse->sample_rate = rate;
668 aacparse->channels = channels;
670 if (!gst_aac_parse_set_src_caps (aacparse,
671 GST_PAD_CAPS (GST_BASE_PARSE (aacparse)->sinkpad))) {
672 /* If linking fails, we need to return appropriate error */
673 ret = GST_FLOW_NOT_LINKED;
676 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
677 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
685 * gst_aac_parse_start:
686 * @parse: #GstBaseParse.
688 * Implementation of "start" vmethod in #GstBaseParse class.
690 * Returns: TRUE if startup succeeded.
693 gst_aac_parse_start (GstBaseParse * parse)
695 GstAacParse *aacparse;
697 aacparse = GST_AAC_PARSE (parse);
699 aacparse->frame_samples = 1024;
700 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
706 * gst_aac_parse_stop:
707 * @parse: #GstBaseParse.
709 * Implementation of "stop" vmethod in #GstBaseParse class.
711 * Returns: TRUE is stopping succeeded.
714 gst_aac_parse_stop (GstBaseParse * parse)
721 gst_aac_parse_sink_getcaps (GstBaseParse * parse)
726 peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse));
730 /* Remove the framed field */
731 peercaps = gst_caps_make_writable (peercaps);
732 n = gst_caps_get_size (peercaps);
733 for (i = 0; i < n; i++) {
734 GstStructure *s = gst_caps_get_structure (peercaps, i);
736 gst_structure_remove_field (s, "framed");
740 gst_caps_intersect_full (peercaps,
741 gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)),
742 GST_CAPS_INTERSECT_FIRST);
743 gst_caps_unref (peercaps);
746 gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD