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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, 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-1.0 filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
47 #include <gst/base/gstbitreader.h>
48 #include <gst/pbutils/pbutils.h>
49 #include "gstaacparse.h"
52 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
55 GST_STATIC_CAPS ("audio/mpeg, "
56 "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
57 "stream-format = (string) { raw, adts, adif, loas };"));
59 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
62 GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) { 2, 4 };"));
64 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
65 #define GST_CAT_DEFAULT aacparse_debug
68 #define ADIF_MAX_SIZE 40 /* Should be enough */
69 #define ADTS_MAX_SIZE 10 /* Should be enough */
70 #define LOAS_MAX_SIZE 3 /* Should be enough */
72 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
73 headers prepended during raw to ADTS
76 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION /* to get more accurate duration */
77 #define AAC_MAX_ESTIMATE_DURATION_BUF (1024 * 1024) /* use first 1 Mbyte */
78 #define AAC_SAMPLE_PER_FRAME 1024
80 #define AAC_MAX_PULL_RANGE_BUF (1 * 1024 * 1024) /* 1 MByte */
81 #define AAC_LARGE_FILE_SIZE (2 * 1024 * 1024) /* 2 MByte */
82 #define gst_aac_parse_parent_class parent_class
85 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
87 static const gint loas_sample_rate_table[16] = {
88 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
89 16000, 12000, 11025, 8000, 7350, 0, 0, 0
92 static const gint loas_channels_table[16] = {
93 0, 1, 2, 3, 4, 5, 6, 8,
94 0, 0, 0, 7, 8, 0, 8, 0
97 static gboolean gst_aac_parse_start (GstBaseParse * parse);
98 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
100 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
102 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
105 static GstFlowReturn gst_aac_parse_handle_frame (GstBaseParse * parse,
106 GstBaseParseFrame * frame, gint * skipsize);
107 static GstFlowReturn gst_aac_parse_pre_push_frame (GstBaseParse * parse,
108 GstBaseParseFrame * frame);
109 static gboolean gst_aac_parse_src_event (GstBaseParse * parse,
112 static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
113 aacparse, GstBitReader * br, gint * object_type, gint * sample_rate,
114 gint * channels, gint * frame_samples);
116 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
117 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
118 static gboolean gst_aac_parse_src_eventfunc (GstBaseParse * parse,
120 /* make full aac(adts) index table when seek */
121 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
123 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
125 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
128 #define gst_aac_parse_parent_class parent_class
129 G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
131 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
133 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
135 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
136 32000, 24000, 22050, 16000, 12000, 11025, 8000
139 if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
140 return aac_sample_rates[sr_idx];
141 GST_WARNING ("Invalid sample rate index %u", sr_idx);
146 * gst_aac_parse_class_init:
147 * @klass: #GstAacParseClass.
151 gst_aac_parse_class_init (GstAacParseClass * klass)
153 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
154 GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
156 GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
157 "AAC audio stream parser");
159 gst_element_class_add_static_pad_template (element_class, &sink_template);
160 gst_element_class_add_static_pad_template (element_class, &src_template);
162 gst_element_class_set_static_metadata (element_class,
163 "AAC audio stream parser", "Codec/Parser/Audio",
164 "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
166 parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
167 parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
168 parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
169 parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
170 parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_handle_frame);
171 parse_class->pre_push_frame =
172 GST_DEBUG_FUNCPTR (gst_aac_parse_pre_push_frame);
173 parse_class->src_event = GST_DEBUG_FUNCPTR (gst_aac_parse_src_event);
178 * gst_aac_parse_init:
179 * @aacparse: #GstAacParse.
180 * @klass: #GstAacParseClass.
184 gst_aac_parse_init (GstAacParse * aacparse)
186 GST_DEBUG ("initialized");
187 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (aacparse));
188 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (aacparse));
190 aacparse->last_parsed_sample_rate = 0;
191 aacparse->last_parsed_channels = 0;
192 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
193 /* to get more correct duration */
194 aacparse->first_frame = TRUE;
200 * gst_aac_parse_set_src_caps:
201 * @aacparse: #GstAacParse.
202 * @sink_caps: (proposed) caps of sink pad
204 * Set source pad caps according to current knowledge about the
207 * Returns: TRUE if caps were successfully set.
210 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
213 GstCaps *src_caps = NULL, *allowed;
214 gboolean res = FALSE;
215 const gchar *stream_format;
216 guint8 codec_data[2];
217 guint16 codec_data_data;
218 gint sample_rate_idx;
220 GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
222 src_caps = gst_caps_copy (sink_caps);
224 src_caps = gst_caps_new_empty_simple ("audio/mpeg");
226 gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
227 "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
229 aacparse->output_header_type = aacparse->header_type;
230 switch (aacparse->header_type) {
231 case DSPAAC_HEADER_NONE:
232 stream_format = "raw";
234 case DSPAAC_HEADER_ADTS:
235 stream_format = "adts";
237 case DSPAAC_HEADER_ADIF:
238 stream_format = "adif";
240 case DSPAAC_HEADER_LOAS:
241 stream_format = "loas";
244 stream_format = NULL;
247 /* Generate codec data to be able to set profile/level on the caps */
249 gst_codec_utils_aac_get_index_from_sample_rate (aacparse->sample_rate);
250 if (sample_rate_idx < 0)
251 goto not_a_known_rate;
253 (aacparse->object_type << 11) |
254 (sample_rate_idx << 7) | (aacparse->channels << 3);
255 GST_WRITE_UINT16_BE (codec_data, codec_data_data);
256 gst_codec_utils_aac_caps_set_level_and_profile (src_caps, codec_data, 2);
258 s = gst_caps_get_structure (src_caps, 0);
259 if (aacparse->sample_rate > 0)
260 gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
261 if (aacparse->channels > 0)
262 gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
264 gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
266 allowed = gst_pad_get_allowed_caps (GST_BASE_PARSE (aacparse)->srcpad);
267 if (allowed && !gst_caps_can_intersect (src_caps, allowed)) {
268 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
269 "Caps can not intersect");
270 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
271 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
272 "Input is ADTS, trying raw");
273 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "raw",
275 if (gst_caps_can_intersect (src_caps, allowed)) {
276 GstBuffer *codec_data_buffer;
278 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
279 "Caps can intersect, we will drop the ADTS layer");
280 aacparse->output_header_type = DSPAAC_HEADER_NONE;
282 /* The codec_data data is according to AudioSpecificConfig,
283 ISO/IEC 14496-3, 1.6.2.1 */
284 codec_data_buffer = gst_buffer_new_and_alloc (2);
285 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
286 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
287 codec_data_buffer, NULL);
289 } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
290 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
291 "Input is raw, trying ADTS");
292 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
294 if (gst_caps_can_intersect (src_caps, allowed)) {
295 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
296 "Caps can intersect, we will prepend ADTS headers");
297 aacparse->output_header_type = DSPAAC_HEADER_ADTS;
302 gst_caps_unref (allowed);
304 aacparse->last_parsed_channels = 0;
305 aacparse->last_parsed_sample_rate = 0;
307 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
309 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
310 gst_caps_unref (src_caps);
314 GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
315 aacparse->sample_rate);
316 gst_caps_unref (src_caps);
322 * gst_aac_parse_sink_setcaps:
326 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
328 * Returns: TRUE on success.
331 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
333 GstAacParse *aacparse;
334 GstStructure *structure;
338 aacparse = GST_AAC_PARSE (parse);
339 structure = gst_caps_get_structure (caps, 0);
340 caps_str = gst_caps_to_string (caps);
342 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
345 /* This is needed at least in case of RTP
346 * Parses the codec_data information to get ObjectType,
347 * number of channels and samplerate */
348 value = gst_structure_get_value (structure, "codec_data");
350 GstBuffer *buf = gst_value_get_buffer (value);
352 if (buf && gst_buffer_get_size (buf) >= 2) {
356 if (!gst_buffer_map (buf, &map, GST_MAP_READ))
358 gst_bit_reader_init (&br, map.data, map.size);
359 gst_aac_parse_read_audio_specific_config (aacparse, &br,
360 &aacparse->object_type, &aacparse->sample_rate, &aacparse->channels,
361 &aacparse->frame_samples);
363 aacparse->header_type = DSPAAC_HEADER_NONE;
364 aacparse->mpegversion = 4;
365 gst_buffer_unmap (buf, &map);
367 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
368 "samples=%d", aacparse->object_type, aacparse->sample_rate,
369 aacparse->channels, aacparse->frame_samples);
371 /* arrange for metadata and get out of the way */
372 gst_aac_parse_set_src_caps (aacparse, caps);
373 if (aacparse->header_type == aacparse->output_header_type)
374 gst_base_parse_set_passthrough (parse, TRUE);
379 /* caps info overrides */
380 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
381 gst_structure_get_int (structure, "channels", &aacparse->channels);
383 const gchar *stream_format =
384 gst_structure_get_string (structure, "stream-format");
386 if (g_strcmp0 (stream_format, "raw") == 0) {
387 GST_ERROR_OBJECT (parse, "Need codec_data for raw AAC");
390 aacparse->sample_rate = 0;
391 aacparse->channels = 0;
392 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
393 gst_base_parse_set_passthrough (parse, FALSE);
401 * gst_aac_parse_adts_get_frame_len:
402 * @data: block of data containing an ADTS header.
404 * This function calculates ADTS frame length from the given header.
406 * Returns: size of the ADTS frame.
409 gst_aac_parse_adts_get_frame_len (const guint8 * data)
411 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
416 * gst_aac_parse_check_adts_frame:
417 * @aacparse: #GstAacParse.
418 * @data: Data to be checked.
419 * @avail: Amount of data passed.
420 * @framesize: If valid ADTS frame was found, this will be set to tell the
421 * found frame size in bytes.
422 * @needed_data: If frame was not found, this may be set to tell how much
423 * more data is needed in the next round to detect the frame
424 * reliably. This may happen when a frame header candidate
425 * is found but it cannot be guaranteed to be the header without
426 * peeking the following data.
428 * Check if the given data contains contains ADTS frame. The algorithm
429 * will examine ADTS frame header and calculate the frame size. Also, another
430 * consecutive ADTS frame header need to be present after the found frame.
431 * Otherwise the data is not considered as a valid ADTS frame. However, this
432 * "extra check" is omitted when EOS has been received. In this case it is
433 * enough when data[0] contains a valid ADTS header.
435 * This function may set the #needed_data to indicate that a possible frame
436 * candidate has been found, but more data (#needed_data bytes) is needed to
437 * be absolutely sure. When this situation occurs, FALSE will be returned.
439 * When a valid frame is detected, this function will use
440 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
441 * to set the needed bytes for next frame.This way next data chunk is already
444 * Returns: TRUE if the given data contains a valid ADTS header.
447 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
448 const guint8 * data, const guint avail, gboolean drain,
449 guint * framesize, guint * needed_data)
455 /* Absolute minimum to perform the ADTS syncword,
456 layer and sampling frequency tests */
457 if (G_UNLIKELY (avail < 3)) {
462 /* Syncword and layer tests */
463 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
465 /* Sampling frequency test */
466 if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
469 /* This looks like an ADTS frame header but
470 we need at least 6 bytes to proceed */
471 if (G_UNLIKELY (avail < 6)) {
476 *framesize = gst_aac_parse_adts_get_frame_len (data);
478 /* If frame has CRC, it needs 2 bytes
479 for it at the end of the header */
480 crc_size = (data[1] & 0x01) ? 0 : 2;
483 if (*framesize < 7 + crc_size) {
484 *needed_data = 7 + crc_size;
488 /* In EOS mode this is enough. No need to examine the data further.
489 We also relax the check when we have sync, on the assumption that
490 if we're not looking at random data, we have a much higher chance
491 to get the correct sync, and this avoids losing two frames when
492 a single bit corruption happens. */
493 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
497 if (*framesize + ADTS_MAX_SIZE > avail) {
498 /* We have found a possible frame header candidate, but can't be
499 sure since we don't have enough data to check the next frame */
500 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
501 *framesize + ADTS_MAX_SIZE, avail);
502 *needed_data = *framesize + ADTS_MAX_SIZE;
503 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
504 *framesize + ADTS_MAX_SIZE);
508 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
509 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
511 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
512 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
513 nextlen + ADTS_MAX_SIZE);
521 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
524 guint8 bytes, i, byte;
527 if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
529 for (i = 0; i <= bytes; ++i) {
531 if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
539 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
540 guint8 * audio_object_type)
542 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
544 if (*audio_object_type == 31) {
545 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
547 *audio_object_type += 32;
549 GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
554 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
557 guint8 sampling_frequency_index;
558 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
560 GST_LOG_OBJECT (aacparse, "sampling_frequency_index: %u",
561 sampling_frequency_index);
562 if (sampling_frequency_index == 0xf) {
563 guint32 sampling_rate;
564 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
566 *sample_rate = sampling_rate;
568 *sample_rate = loas_sample_rate_table[sampling_frequency_index];
572 aacparse->last_parsed_sample_rate = *sample_rate;
576 /* See table 1.13 in ISO/IEC 14496-3 */
578 gst_aac_parse_read_audio_specific_config (GstAacParse * aacparse,
579 GstBitReader * br, gint * object_type, gint * sample_rate, gint * channels,
580 gint * frame_samples)
582 guint8 audio_object_type;
583 guint8 G_GNUC_UNUSED extension_audio_object_type;
584 guint8 channel_configuration, extension_channel_configuration;
585 gboolean G_GNUC_UNUSED sbr = FALSE, ps = FALSE;
587 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
590 *object_type = audio_object_type;
592 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
595 if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
597 *channels = loas_channels_table[channel_configuration];
598 GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
602 if (audio_object_type == 5 || audio_object_type == 29) {
603 extension_audio_object_type = 5;
605 if (audio_object_type == 29) {
607 /* Parametric stereo. If we have a one-channel configuration, we can
608 * override it to stereo */
613 GST_LOG_OBJECT (aacparse,
614 "Audio object type 5 or 29, so rereading sampling rate (was %d)...",
616 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
619 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
622 if (audio_object_type == 22) {
623 /* extension channel configuration */
624 if (!gst_bit_reader_get_bits_uint8 (br, &extension_channel_configuration,
627 GST_LOG_OBJECT (aacparse, "extension channel_configuration: %d",
628 extension_channel_configuration);
629 *channels = loas_channels_table[extension_channel_configuration];
634 extension_audio_object_type = 0;
637 GST_INFO_OBJECT (aacparse, "Parsed AudioSpecificConfig: %d Hz, %d channels",
638 *sample_rate, *channels);
640 if (frame_samples && audio_object_type == 23) {
642 /* Read the Decoder Configuration (GASpecificConfig) if present */
643 /* We only care about the first bit to know what the number of samples
645 if (!gst_bit_reader_get_bits_uint8 (br, &frame_flag, 1))
647 *frame_samples = frame_flag ? 960 : 1024;
650 /* There's LOTS of stuff next, but we ignore it for now as we have
651 what we want (sample rate and number of channels */
652 GST_DEBUG_OBJECT (aacparse,
653 "Need more code to parse humongous LOAS data, currently ignored");
654 aacparse->last_parsed_channels = *channels;
660 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
661 guint avail, gint * sample_rate, gint * channels, gint * version)
666 /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
670 gst_bit_reader_init (&br, data, avail);
672 /* skip sync word (11 bits) and size (13 bits) */
673 if (!gst_bit_reader_skip (&br, 11 + 13))
676 /* First bit is "use last config" */
677 if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
680 GST_LOG_OBJECT (aacparse, "Frame uses previous config");
681 if (!aacparse->last_parsed_sample_rate || !aacparse->last_parsed_channels) {
682 GST_DEBUG_OBJECT (aacparse,
683 "No previous config to use. We'll look for more data.");
686 *sample_rate = aacparse->last_parsed_sample_rate;
687 *channels = aacparse->last_parsed_channels;
691 GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
693 /* audioMuxVersion */
694 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
697 /* audioMuxVersionA */
698 if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
703 GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
705 guint8 same_time, subframes, num_program, prog;
708 /* taraBufferFullness */
709 if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
712 if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
714 if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
716 if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
718 GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
719 same_time, subframes, num_program);
721 for (prog = 0; prog <= num_program; ++prog) {
722 guint8 num_layer, layer;
723 if (!gst_bit_reader_get_bits_uint8 (&br, &num_layer, 3))
725 GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
727 for (layer = 0; layer <= num_layer; ++layer) {
728 guint8 use_same_config;
729 if (prog == 0 && layer == 0) {
732 if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
735 if (!use_same_config) {
737 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
738 sample_rate, channels, NULL))
742 if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
744 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
745 sample_rate, channels, NULL))
747 if (!gst_bit_reader_skip (&br, asc_len))
753 GST_LOG_OBJECT (aacparse, "More data ignored");
755 GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
762 * gst_aac_parse_loas_get_frame_len:
763 * @data: block of data containing a LOAS header.
765 * This function calculates LOAS frame length from the given header.
767 * Returns: size of the LOAS frame.
770 gst_aac_parse_loas_get_frame_len (const guint8 * data)
772 return (((data[1] & 0x1f) << 8) | data[2]) + 3;
777 * gst_aac_parse_check_loas_frame:
778 * @aacparse: #GstAacParse.
779 * @data: Data to be checked.
780 * @avail: Amount of data passed.
781 * @framesize: If valid LOAS frame was found, this will be set to tell the
782 * found frame size in bytes.
783 * @needed_data: If frame was not found, this may be set to tell how much
784 * more data is needed in the next round to detect the frame
785 * reliably. This may happen when a frame header candidate
786 * is found but it cannot be guaranteed to be the header without
787 * peeking the following data.
789 * Check if the given data contains contains LOAS frame. The algorithm
790 * will examine LOAS frame header and calculate the frame size. Also, another
791 * consecutive LOAS frame header need to be present after the found frame.
792 * Otherwise the data is not considered as a valid LOAS frame. However, this
793 * "extra check" is omitted when EOS has been received. In this case it is
794 * enough when data[0] contains a valid LOAS header.
796 * This function may set the #needed_data to indicate that a possible frame
797 * candidate has been found, but more data (#needed_data bytes) is needed to
798 * be absolutely sure. When this situation occurs, FALSE will be returned.
800 * When a valid frame is detected, this function will use
801 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
802 * to set the needed bytes for next frame.This way next data chunk is already
805 * LOAS can have three different formats, if I read the spec correctly. Only
806 * one of them is supported here, as the two samples I have use this one.
808 * Returns: TRUE if the given data contains a valid LOAS header.
811 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
812 const guint8 * data, const guint avail, gboolean drain,
813 guint * framesize, guint * needed_data)
818 if (G_UNLIKELY (avail < 3)) {
823 if ((data[0] == 0x56) && ((data[1] & 0xe0) == 0xe0)) {
824 *framesize = gst_aac_parse_loas_get_frame_len (data);
825 GST_DEBUG_OBJECT (aacparse, "Found possible %u byte LOAS frame",
828 /* In EOS mode this is enough. No need to examine the data further.
829 We also relax the check when we have sync, on the assumption that
830 if we're not looking at random data, we have a much higher chance
831 to get the correct sync, and this avoids losing two frames when
832 a single bit corruption happens. */
833 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
837 if (*framesize + LOAS_MAX_SIZE > avail) {
838 /* We have found a possible frame header candidate, but can't be
839 sure since we don't have enough data to check the next frame */
840 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
841 *framesize + LOAS_MAX_SIZE, avail);
842 *needed_data = *framesize + LOAS_MAX_SIZE;
843 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
844 *framesize + LOAS_MAX_SIZE);
848 if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
849 guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
851 GST_LOG ("LOAS frame found, len: %d bytes", *framesize);
852 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
853 nextlen + LOAS_MAX_SIZE);
856 GST_DEBUG_OBJECT (aacparse, "That was a false positive");
862 /* caller ensure sufficient data */
864 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
865 gint * rate, gint * channels, gint * object, gint * version)
869 gint sr_idx = (data[2] & 0x3c) >> 2;
871 *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
874 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
880 *version = (data[1] & 0x08) ? 2 : 4;
882 *object = ((data[2] & 0xc0) >> 6) + 1;
886 * gst_aac_parse_detect_stream:
887 * @aacparse: #GstAacParse.
888 * @data: A block of data that needs to be examined for stream characteristics.
889 * @avail: Size of the given datablock.
890 * @framesize: If valid stream was found, this will be set to tell the
891 * first frame size in bytes.
892 * @skipsize: If valid stream was found, this will be set to tell the first
893 * audio frame position within the given data.
895 * Examines the given piece of data and try to detect the format of it. It
896 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
897 * header. If the stream is detected, TRUE will be returned and #framesize
898 * is set to indicate the found frame size. Additionally, #skipsize might
899 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
900 * position of the frame inside given data chunk.
902 * Returns: TRUE on success.
905 gst_aac_parse_detect_stream (GstAacParse * aacparse,
906 const guint8 * data, const guint avail, gboolean drain,
907 guint * framesize, gint * skipsize)
909 gboolean found = FALSE;
910 guint need_data_adts = 0, need_data_loas;
913 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
915 /* FIXME: No need to check for ADIF if we are not in the beginning of the
918 /* Can we even parse the header? */
919 if (avail < MAX (ADTS_MAX_SIZE, LOAS_MAX_SIZE)) {
920 GST_DEBUG_OBJECT (aacparse, "Not enough data to check");
924 for (i = 0; i < avail - 4; i++) {
925 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
926 ((data[i] == 0x56) && ((data[i + 1] & 0xe0) == 0xe0)) ||
927 strncmp ((char *) data + i, "ADIF", 4) == 0) {
928 GST_DEBUG_OBJECT (aacparse, "Found signature at offset %u", i);
932 /* Trick: tell the parent class that we didn't find the frame yet,
933 but make it skip 'i' amount of bytes. Next time we arrive
934 here we have full frame in the beginning of the data. */
947 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
948 framesize, &need_data_adts)) {
951 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
953 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
954 &aacparse->object_type, &aacparse->mpegversion);
956 if (!channels || !framesize) {
957 GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
961 aacparse->header_type = DSPAAC_HEADER_ADTS;
962 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
963 aacparse->frame_samples, 2, 2);
965 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
966 rate, channels, aacparse->object_type, aacparse->mpegversion);
968 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
973 if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
974 framesize, &need_data_loas)) {
975 gint rate = 0, channels = 0;
977 GST_INFO ("LOAS, framesize: %d", *framesize);
979 aacparse->header_type = DSPAAC_HEADER_LOAS;
981 if (!gst_aac_parse_read_loas_config (aacparse, data, avail, &rate,
982 &channels, &aacparse->mpegversion)) {
983 /* This is pretty normal when skipping data at the start of
984 * random stream (MPEG-TS capture for example) */
985 GST_LOG_OBJECT (aacparse, "Error reading LOAS config");
989 if (rate && channels) {
990 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
991 aacparse->frame_samples, 2, 2);
993 /* Don't store the sample rate and channels yet -
994 * this is just format detection. */
995 GST_DEBUG ("LOAS: samplerate %d, channels %d, objtype %d, version %d",
996 rate, channels, aacparse->object_type, aacparse->mpegversion);
999 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
1004 if (need_data_adts || need_data_loas) {
1005 /* This tells the parent class not to skip any data */
1010 if (avail < ADIF_MAX_SIZE)
1013 if (memcmp (data + i, "ADIF", 4) == 0) {
1020 aacparse->header_type = DSPAAC_HEADER_ADIF;
1021 aacparse->mpegversion = 4;
1023 /* Skip the "ADIF" bytes */
1024 adif = data + i + 4;
1026 /* copyright string */
1028 skip_size += 9; /* skip 9 bytes */
1030 bitstream_type = adif[0 + skip_size] & 0x10;
1032 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
1033 ((unsigned int) adif[1 + skip_size] << 11) |
1034 ((unsigned int) adif[2 + skip_size] << 3) |
1035 ((unsigned int) adif[3 + skip_size] & 0xe0);
1038 if (bitstream_type == 0) {
1040 /* Buffer fullness parsing. Currently not needed... */
1041 guint num_elems = 0;
1044 num_elems = (adif[3 + skip_size] & 0x1e);
1045 GST_INFO ("ADIF num_config_elems: %d", num_elems);
1047 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
1048 ((unsigned int) adif[4 + skip_size] << 11) |
1049 ((unsigned int) adif[5 + skip_size] << 3) |
1050 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
1052 GST_INFO ("ADIF buffer fullness: %d", fullness);
1054 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
1055 ((adif[7 + skip_size] & 0x80) >> 7);
1056 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
1060 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
1061 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
1062 ((adif[5 + skip_size] & 0x80) >> 7);
1065 /* FIXME: This gives totally wrong results. Duration calculation cannot
1067 aacparse->sample_rate =
1068 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1070 /* baseparse is not given any fps,
1071 * so it will give up on timestamps, seeking, etc */
1073 /* FIXME: Can we assume this? */
1074 aacparse->channels = 2;
1076 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1077 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1079 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1081 /* arrange for metadata and get out of the way */
1082 sinkcaps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (aacparse));
1083 gst_aac_parse_set_src_caps (aacparse, sinkcaps);
1085 gst_caps_unref (sinkcaps);
1087 /* not syncable, not easily seekable (unless we push data from start */
1088 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
1089 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
1090 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
1096 /* This should never happen */
1101 * gst_aac_parse_get_audio_profile_object_type
1102 * @aacparse: #GstAacParse.
1104 * Gets the MPEG-2 profile or the MPEG-4 object type value corresponding to the
1105 * mpegversion and profile of @aacparse's src pad caps, according to the
1106 * values defined by table 1.A.11 in ISO/IEC 14496-3.
1108 * Returns: the profile or object type value corresponding to @aacparse's src
1109 * pad caps, if such a value exists; otherwise G_MAXUINT8.
1112 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1115 GstStructure *srcstruct;
1116 const gchar *profile;
1119 srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1120 if (G_UNLIKELY (srccaps == NULL)) {
1124 srcstruct = gst_caps_get_structure (srccaps, 0);
1125 profile = gst_structure_get_string (srcstruct, "profile");
1126 if (G_UNLIKELY (profile == NULL)) {
1127 gst_caps_unref (srccaps);
1131 if (g_strcmp0 (profile, "main") == 0) {
1133 } else if (g_strcmp0 (profile, "lc") == 0) {
1135 } else if (g_strcmp0 (profile, "ssr") == 0) {
1137 } else if (g_strcmp0 (profile, "ltp") == 0) {
1138 if (G_LIKELY (aacparse->mpegversion == 4))
1141 ret = G_MAXUINT8; /* LTP Object Type allowed only for MPEG-4 */
1146 gst_caps_unref (srccaps);
1151 * gst_aac_parse_get_audio_channel_configuration
1152 * @num_channels: number of audio channels.
1154 * Gets the Channel Configuration value, as defined by table 1.19 in ISO/IEC
1155 * 14496-3, for a given number of audio channels.
1157 * Returns: the Channel Configuration value corresponding to @num_channels, if
1158 * such a value exists; otherwise G_MAXUINT8.
1161 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1163 if (num_channels >= 1 && num_channels <= 6) /* Mono up to & including 5.1 */
1164 return (guint8) num_channels;
1165 else if (num_channels == 8) /* 7.1 */
1170 /* FIXME: Add support for configurations 11, 12 and 14 from
1171 * ISO/IEC 14496-3:2009/PDAM 4 based on the actual channel layout
1176 * gst_aac_parse_get_audio_sampling_frequency_index:
1177 * @sample_rate: audio sampling rate.
1179 * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1180 * 14496-3, for a given sampling rate.
1182 * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1183 * if such a value exists; otherwise G_MAXUINT8.
1186 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1188 switch (sample_rate) {
1221 * gst_aac_parse_prepend_adts_headers:
1222 * @aacparse: #GstAacParse.
1223 * @frame: raw AAC frame to which ADTS headers shall be prepended.
1225 * Prepends ADTS headers to a raw AAC audio frame.
1227 * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1230 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1231 GstBaseParseFrame * frame)
1234 guint8 *adts_headers;
1237 guint8 id, profile, channel_configuration, sampling_frequency_index;
1239 id = (aacparse->mpegversion == 4) ? 0x0U : 0x1U;
1240 profile = gst_aac_parse_get_audio_profile_object_type (aacparse);
1241 if (profile == G_MAXUINT8) {
1242 GST_ERROR_OBJECT (aacparse, "Unsupported audio profile or object type");
1245 channel_configuration =
1246 gst_aac_parse_get_audio_channel_configuration (aacparse->channels);
1247 if (channel_configuration == G_MAXUINT8) {
1248 GST_ERROR_OBJECT (aacparse, "Unsupported number of channels");
1251 sampling_frequency_index =
1252 gst_aac_parse_get_audio_sampling_frequency_index (aacparse->sample_rate);
1253 if (sampling_frequency_index == G_MAXUINT8) {
1254 GST_ERROR_OBJECT (aacparse, "Unsupported sampling frequency");
1258 frame->out_buffer = gst_buffer_copy (frame->buffer);
1259 buf_size = gst_buffer_get_size (frame->out_buffer);
1260 frame_size = buf_size + ADTS_HEADERS_LENGTH;
1262 if (G_UNLIKELY (frame_size >= 0x4000)) {
1263 GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1267 adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1269 /* Note: no error correction bits are added to the resulting ADTS frames */
1270 adts_headers[0] = 0xFFU;
1271 adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
1272 adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
1273 (channel_configuration & 0x4U);
1274 adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
1275 (guint8) (frame_size >> 11);
1276 adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
1277 adts_headers[5] = (guint8) (((frame_size & 0x0007) << 5) + 0x1FU);
1278 adts_headers[6] = 0xFCU;
1280 mem = gst_memory_new_wrapped (0, adts_headers, ADTS_HEADERS_LENGTH, 0,
1281 ADTS_HEADERS_LENGTH, adts_headers, g_free);
1282 gst_buffer_prepend_memory (frame->out_buffer, mem);
1288 * gst_aac_parse_check_valid_frame:
1289 * @parse: #GstBaseParse.
1290 * @frame: #GstBaseParseFrame.
1291 * @skipsize: How much data parent class should skip in order to find the
1294 * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1296 * Also determines frame overhead.
1297 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
1298 * a per-frame header. LOAS has 3 bytes.
1300 * We're making a couple of simplifying assumptions:
1302 * 1. We count Program Configuration Elements rather than searching for them
1303 * in the streams to discount them - the overhead is negligible.
1305 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
1306 * bits, which should still not be significant enough to warrant the
1307 * additional parsing through the headers
1309 * Returns: a #GstFlowReturn.
1311 static GstFlowReturn
1312 gst_aac_parse_handle_frame (GstBaseParse * parse,
1313 GstBaseParseFrame * frame, gint * skipsize)
1316 GstAacParse *aacparse;
1317 gboolean ret = FALSE;
1321 gint rate = 0, channels = 0;
1323 aacparse = GST_AAC_PARSE (parse);
1324 buffer = frame->buffer;
1326 gst_buffer_map (buffer, &map, GST_MAP_READ);
1329 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1331 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
1332 aacparse->header_type == DSPAAC_HEADER_NONE) {
1333 /* There is nothing to parse */
1334 framesize = map.size;
1337 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1339 ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1340 GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1342 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1343 guint needed_data = 1024;
1345 ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1346 GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1348 if (!ret && needed_data) {
1349 GST_DEBUG ("buffer didn't contain valid frame");
1351 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1355 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1356 guint needed_data = 1024;
1358 ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1359 map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1361 if (!ret && needed_data) {
1362 GST_DEBUG ("buffer didn't contain valid frame");
1364 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1369 GST_DEBUG ("buffer didn't contain valid frame");
1370 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1374 if (G_UNLIKELY (!ret))
1377 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1379 frame->overhead = 7;
1381 gst_aac_parse_parse_adts_header (aacparse, map.data,
1382 &rate, &channels, NULL, NULL);
1384 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1386 if (G_UNLIKELY (rate != aacparse->sample_rate
1387 || channels != aacparse->channels)) {
1388 aacparse->sample_rate = rate;
1389 aacparse->channels = channels;
1391 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1392 /* If linking fails, we need to return appropriate error */
1393 ret = GST_FLOW_NOT_LINKED;
1396 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1397 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1399 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1400 if (aacparse->first_frame == TRUE) {
1401 gboolean ret = FALSE;
1402 aacparse->first_frame = FALSE;
1404 ret = gst_aac_parse_estimate_duration (parse);
1406 GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1407 ret = GST_FLOW_NOT_SUPPORTED;
1411 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1412 gboolean setcaps = FALSE;
1415 frame->overhead = 3;
1417 if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
1418 &channels, NULL) || !rate || !channels) {
1419 /* This is pretty normal when skipping data at the start of
1420 * random stream (MPEG-TS capture for example) */
1421 GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
1422 /* Since we don't fully parse the LOAS config, we don't know for sure
1423 * how much to skip. Just skip 1 to end up to the next marker and
1424 * resume parsing from there */
1429 if (G_UNLIKELY (rate != aacparse->sample_rate
1430 || channels != aacparse->channels)) {
1431 aacparse->sample_rate = rate;
1432 aacparse->channels = channels;
1434 GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1438 /* We want to set caps both at start, and when rate/channels change.
1439 Since only some LOAS frames have that info, we may receive frames
1440 before knowing about rate/channels. */
1442 || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
1443 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1444 /* If linking fails, we need to return appropriate error */
1445 ret = GST_FLOW_NOT_LINKED;
1448 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1449 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1452 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1453 else if (aacparse->header_type == DSPAAC_HEADER_ADIF) {
1454 /* to get more correct duration */
1455 float estimated_duration = 0;
1456 gint64 total_file_size;
1457 gst_base_parse_get_upstream_size (parse, &total_file_size);
1458 estimated_duration =
1459 ((total_file_size * 8) / (float) (aacparse->bitrate * 1000)) *
1461 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1462 estimated_duration * 1000, 0);
1466 if (aacparse->header_type == DSPAAC_HEADER_NONE
1467 && aacparse->output_header_type == DSPAAC_HEADER_ADTS) {
1468 if (!gst_aac_parse_prepend_adts_headers (aacparse, frame)) {
1469 GST_ERROR_OBJECT (aacparse, "Failed to prepend ADTS headers to frame");
1470 ret = GST_FLOW_ERROR;
1475 gst_buffer_unmap (buffer, &map);
1478 /* found, skip if needed */
1487 if (ret && framesize <= map.size) {
1488 return gst_base_parse_finish_frame (parse, frame, framesize);
1494 static GstFlowReturn
1495 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1497 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1499 if (!aacparse->sent_codec_tag) {
1500 GstTagList *taglist;
1504 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1506 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1507 GST_INFO_OBJECT (parse, "Src pad is flushing");
1508 return GST_FLOW_FLUSHING;
1510 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1511 return GST_FLOW_NOT_NEGOTIATED;
1515 taglist = gst_tag_list_new_empty ();
1516 gst_pb_utils_add_codec_description_to_tag_list (taglist,
1517 GST_TAG_AUDIO_CODEC, caps);
1518 gst_caps_unref (caps);
1520 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1521 gst_tag_list_unref (taglist);
1523 /* also signals the end of first-frame processing */
1524 aacparse->sent_codec_tag = TRUE;
1527 /* As a special case, we can remove the ADTS framing and output raw AAC. */
1528 if (aacparse->header_type == DSPAAC_HEADER_ADTS
1529 && aacparse->output_header_type == DSPAAC_HEADER_NONE) {
1532 frame->out_buffer = gst_buffer_make_writable (frame->buffer);
1533 frame->buffer = NULL;
1534 gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ);
1535 header_size = (map.data[1] & 1) ? 7 : 9; /* optional CRC */
1536 gst_buffer_unmap (frame->out_buffer, &map);
1537 gst_buffer_resize (frame->out_buffer, header_size,
1538 gst_buffer_get_size (frame->out_buffer) - header_size);
1546 * gst_aac_parse_start:
1547 * @parse: #GstBaseParse.
1549 * Implementation of "start" vmethod in #GstBaseParse class.
1551 * Returns: TRUE if startup succeeded.
1554 gst_aac_parse_start (GstBaseParse * parse)
1556 GstAacParse *aacparse;
1558 aacparse = GST_AAC_PARSE (parse);
1559 GST_DEBUG ("start");
1560 aacparse->frame_samples = 1024;
1561 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
1562 aacparse->sent_codec_tag = FALSE;
1563 aacparse->last_parsed_channels = 0;
1564 aacparse->last_parsed_sample_rate = 0;
1565 aacparse->object_type = 0;
1566 aacparse->bitrate = 0;
1567 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
1568 aacparse->output_header_type = DSPAAC_HEADER_NOT_PARSED;
1569 aacparse->channels = 0;
1570 aacparse->sample_rate = 0;
1576 * gst_aac_parse_stop:
1577 * @parse: #GstBaseParse.
1579 * Implementation of "stop" vmethod in #GstBaseParse class.
1581 * Returns: TRUE is stopping succeeded.
1584 gst_aac_parse_stop (GstBaseParse * parse)
1591 remove_fields (GstCaps * caps)
1595 n = gst_caps_get_size (caps);
1596 for (i = 0; i < n; i++) {
1597 GstStructure *s = gst_caps_get_structure (caps, i);
1599 gst_structure_remove_field (s, "framed");
1604 add_conversion_fields (GstCaps * caps)
1608 n = gst_caps_get_size (caps);
1609 for (i = 0; i < n; i++) {
1610 GstStructure *s = gst_caps_get_structure (caps, i);
1612 if (gst_structure_has_field (s, "stream-format")) {
1613 const GValue *v = gst_structure_get_value (s, "stream-format");
1615 if (G_VALUE_HOLDS_STRING (v)) {
1616 const gchar *str = g_value_get_string (v);
1618 if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1619 GValue va = G_VALUE_INIT;
1620 GValue vs = G_VALUE_INIT;
1622 g_value_init (&va, GST_TYPE_LIST);
1623 g_value_init (&vs, G_TYPE_STRING);
1624 g_value_set_string (&vs, "adts");
1625 gst_value_list_append_value (&va, &vs);
1626 g_value_set_string (&vs, "raw");
1627 gst_value_list_append_value (&va, &vs);
1628 gst_structure_set_value (s, "stream-format", &va);
1629 g_value_unset (&va);
1630 g_value_unset (&vs);
1632 } else if (GST_VALUE_HOLDS_LIST (v)) {
1633 gboolean contains_raw = FALSE;
1634 gboolean contains_adts = FALSE;
1635 guint m = gst_value_list_get_size (v), j;
1637 for (j = 0; j < m; j++) {
1638 const GValue *ve = gst_value_list_get_value (v, j);
1641 if (G_VALUE_HOLDS_STRING (ve) && (str = g_value_get_string (ve))) {
1642 if (strcmp (str, "adts") == 0)
1643 contains_adts = TRUE;
1644 else if (strcmp (str, "raw") == 0)
1645 contains_raw = TRUE;
1649 if (contains_adts || contains_raw) {
1650 GValue va = G_VALUE_INIT;
1651 GValue vs = G_VALUE_INIT;
1653 g_value_init (&va, GST_TYPE_LIST);
1654 g_value_init (&vs, G_TYPE_STRING);
1655 g_value_copy (v, &va);
1657 if (!contains_raw) {
1658 g_value_set_string (&vs, "raw");
1659 gst_value_list_append_value (&va, &vs);
1661 if (!contains_adts) {
1662 g_value_set_string (&vs, "adts");
1663 gst_value_list_append_value (&va, &vs);
1666 gst_structure_set_value (s, "stream-format", &va);
1668 g_value_unset (&vs);
1669 g_value_unset (&va);
1677 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1679 GstCaps *peercaps, *templ;
1682 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1685 GstCaps *fcopy = gst_caps_copy (filter);
1686 /* Remove the fields we convert */
1687 remove_fields (fcopy);
1688 add_conversion_fields (fcopy);
1689 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1690 gst_caps_unref (fcopy);
1692 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1695 peercaps = gst_caps_make_writable (peercaps);
1696 /* Remove the fields we convert */
1697 remove_fields (peercaps);
1698 add_conversion_fields (peercaps);
1700 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1701 gst_caps_unref (peercaps);
1702 gst_caps_unref (templ);
1708 GstCaps *intersection;
1711 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1712 gst_caps_unref (res);
1720 gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1722 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1724 if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1725 aacparse->last_parsed_channels = 0;
1726 aacparse->last_parsed_sample_rate = 0;
1728 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1729 GST_DEBUG ("Entering gst_aac_parse_src_eventfunc header type = %d",
1730 aacparse->header_type);
1731 if (aacparse->header_type == DSPAAC_HEADER_ADTS)
1732 return gst_aac_parse_adts_src_eventfunc (parse, event);
1736 return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1740 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1742 * get_aac_parse_get_adts_framelength:
1743 * @data: #GstBufferData.
1744 * @offset: #GstBufferData offset
1746 * Implementation to get adts framelength by using first some frame.
1748 * Returns: frame size
1751 get_aac_parse_get_adts_frame_length (const unsigned char *data, gint64 offset)
1753 const gint adts_header_length_no_crc = 7;
1754 const gint adts_header_length_with_crc = 9;
1755 gint frame_size = 0;
1756 gint protection_absent;
1759 /* check of syncword */
1760 if ((data[offset + 0] != 0xff) || ((data[offset + 1] & 0xf6) != 0xf0)) {
1761 GST_ERROR ("check sync word is fail\n");
1765 /* check of protection absent */
1766 protection_absent = (data[offset + 1] & 0x01);
1768 /*check of frame length */
1770 (data[offset + 3] & 0x3) << 11 | data[offset + 4] << 3 | data[offset +
1773 /* check of header size */
1774 /* protectionAbsent is 0 if there is CRC */
1776 protection_absent ? adts_header_length_no_crc :
1777 adts_header_length_with_crc;
1778 if (head_size > frame_size) {
1779 GST_ERROR ("return frame length as 0 (frameSize %u < headSize %u)",
1780 frame_size, head_size);
1788 * gst_aac_parse_estimate_duration:
1789 * @parse: #GstBaseParse.
1791 * Implementation to get estimated total duration by using first some frame.
1793 * Returns: TRUE if we can get estimated total duraion
1796 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1798 gboolean ret = FALSE;
1799 GstFlowReturn res = GST_FLOW_OK;
1800 gint64 pull_size = 0, file_size = 0, offset = 0, num_frames = 0, duration = 0;
1801 guint sample_rate_index = 0, sample_rate = 0, channel = 0;
1802 guint frame_size = 0, frame_duration_us = 0, estimated_bitrate = 0;
1803 guint lost_sync_count = 0;
1804 GstClockTime estimated_duration = GST_CLOCK_TIME_NONE;
1805 GstBuffer *buffer = NULL;
1808 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1809 GstAacParse *aacparse;
1810 gint64 buffer_size = 0;
1813 aacparse = GST_AAC_PARSE (parse);
1814 GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1816 /* check baseparse define these fuction */
1817 gst_base_parse_get_pad_mode (parse, &pad_mode);
1818 if (pad_mode != GST_PAD_MODE_PULL) {
1819 GST_INFO_OBJECT (aacparse,
1820 "aac parser is not pull mode. can not estimate duration");
1824 gst_base_parse_get_upstream_size (parse, &file_size);
1826 if (file_size < ADIF_MAX_SIZE) {
1827 GST_ERROR_OBJECT (aacparse, "file size is too short");
1831 pull_size = MIN (file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1833 res = gst_pad_pull_range (parse->sinkpad, 0, pull_size, &buffer);
1834 if (res != GST_FLOW_OK) {
1835 GST_ERROR_OBJECT (aacparse, "gst_pad_pull_range failed!");
1839 gst_buffer_map (buffer, &map, GST_MAP_READ);
1841 buffer_size = map.size;
1842 if (buffer_size != pull_size) {
1843 GST_ERROR_OBJECT (aacparse,
1844 "We got different buffer_size(%" G_GINT64_FORMAT ") with pull_size(%"
1845 G_GINT64_FORMAT ").", buffer_size, pull_size);
1848 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1849 for (i = 0; i < buffer_size; i++) {
1850 if ((buf[i] == 0xff) && ((buf[i + 1] & 0xf6) == 0xf0)) { /* aac sync word */
1851 //guint profile = (buf[i+2] >> 6) & 0x3;
1852 sample_rate_index = (buf[i + 2] >> 2) & 0xf;
1854 gst_aac_parse_get_sample_rate_from_index (sample_rate_index);
1855 if (sample_rate == 0) {
1856 GST_WARNING_OBJECT (aacparse, "Invalid sample rate index (0)");
1859 channel = (buf[i + 2] & 0x1) << 2 | (buf[i + 3] >> 6);
1861 GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate,
1864 /* count number of frames */
1865 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1866 //while (offset < pull_size) {
1867 while (offset < buffer_size) {
1868 frame_size = get_aac_parse_get_adts_frame_length (buf, i + offset);
1869 if (frame_size == 0) {
1870 GST_ERROR_OBJECT (aacparse,
1871 "framesize error at offset %" G_GINT64_FORMAT, offset);
1873 } else if (frame_size == -1) {
1875 lost_sync_count++; // lost sync count limmitation 2K Bytes
1876 if (lost_sync_count > (1024 * 2)) {
1877 GST_WARNING_OBJECT (aacparse,
1878 "lost_sync_count is larger than 2048");
1882 offset += frame_size;
1884 lost_sync_count = 0;
1888 /* if we can got full file, we can calculate the accurate duration */
1889 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1890 //if (pull_size == file_size) {
1891 if (buffer_size == file_size) {
1892 gfloat duration_for_one_frame = 0;
1893 GstClockTime calculated_duration = GST_CLOCK_TIME_NONE;
1895 GST_INFO_OBJECT (aacparse,
1896 "we got total file (%" G_GINT64_FORMAT
1897 " bytes). do not estimate but make Accurate total duration.",
1900 duration_for_one_frame =
1901 (gfloat) AAC_SAMPLE_PER_FRAME / (gfloat) sample_rate;
1902 calculated_duration =
1903 num_frames * duration_for_one_frame * 1000 * 1000 * 1000;
1905 GST_INFO_OBJECT (aacparse, "duration_for_one_frame %f ms",
1906 duration_for_one_frame);
1907 GST_INFO_OBJECT (aacparse, "calculated duration = %" GST_TIME_FORMAT,
1908 GST_TIME_ARGS (calculated_duration));
1909 /* 0 means disable estimate */
1910 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1911 calculated_duration, 0);
1914 GST_INFO_OBJECT (aacparse,
1915 "we got %" G_GUINT64_FORMAT " bytes in total file (%"
1916 G_GINT64_FORMAT "). can not make accurate duration but Estimate.",
1917 pull_size, file_size);
1919 (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1920 duration = num_frames * frame_duration_us;
1922 if (duration == 0) {
1923 GST_WARNING_OBJECT (aacparse, "Invalid duration");
1927 (gint) ((gfloat) (offset * 8) / (gfloat) (duration / 1000));
1929 if (estimated_bitrate == 0) {
1930 GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1933 estimated_duration =
1934 (GstClockTime) ((file_size * 8) / (estimated_bitrate * 1000)) *
1937 GST_INFO_OBJECT (aacparse, "number of frame = %" G_GINT64_FORMAT,
1939 GST_INFO_OBJECT (aacparse, "duration = %" G_GINT64_FORMAT,
1940 duration / 1000000);
1941 GST_INFO_OBJECT (aacparse, "byte = %" G_GINT64_FORMAT, offset);
1942 GST_INFO_OBJECT (aacparse, "estimated bitrate = %d bps",
1944 GST_INFO_OBJECT (aacparse, "estimated duration = %" GST_TIME_FORMAT,
1945 GST_TIME_ARGS (estimated_duration));
1947 gst_base_parse_set_average_bitrate (parse, estimated_bitrate * 1000);
1948 /* set update_interval as duration(sec)/2 */
1949 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration,
1950 (gint) (duration / 2));
1959 gst_buffer_unmap (buffer, &map);
1960 gst_buffer_unref (buffer);
1965 /* perform seek in push based mode:
1966 find BYTE position to move to based on time and delegate to upstream
1969 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1970 GstPad * pad, GstEvent * event)
1972 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1976 GstSeekType cur_type, stop_type;
1980 gint64 esimate_byte;
1982 gint64 upstream_total_bytes = 0;
1983 GstFormat fmt = GST_FORMAT_BYTES;
1985 GST_INFO_OBJECT (parse, "doing aac push-based seek");
1987 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1990 /* FIXME, always play to the end */
1993 /* only forward streaming and seeking is possible */
1995 goto unsupported_seek;
1998 /* handle rewind only */
1999 cur_type = GST_SEEK_TYPE_SET;
2001 stop_type = GST_SEEK_TYPE_NONE;
2003 flags |= GST_SEEK_FLAG_FLUSH;
2005 /* handle normal seek */
2006 cur_type = GST_SEEK_TYPE_SET;
2007 stop_type = GST_SEEK_TYPE_NONE;
2009 flags |= GST_SEEK_FLAG_FLUSH;
2011 esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
2012 if (aacparse->sample_rate > 0)
2013 frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
2015 goto unsupported_seek;
2017 byte_cur = esimate_byte / (frame_dur);
2019 goto unsupported_seek;
2021 GST_INFO_OBJECT (parse, "frame_byte(%d) spf(%d) rate (%d) ",
2022 aacparse->frame_byte, aacparse->spf, aacparse->sample_rate);
2023 GST_INFO_OBJECT (parse,
2024 "seek cur (%" G_GINT64_FORMAT ") = (%" GST_TIME_FORMAT ") ", cur,
2025 GST_TIME_ARGS (cur));
2026 GST_INFO_OBJECT (parse,
2027 "esimate_byte(%" G_GINT64_FORMAT ") esimate_byte (%d)", esimate_byte,
2031 /* obtain real upstream total bytes */
2032 if (!gst_pad_peer_query_duration (parse->sinkpad, fmt, &upstream_total_bytes))
2033 upstream_total_bytes = 0;
2034 GST_INFO_OBJECT (aacparse,
2035 "gst_pad_query_peer_duration -upstream_total_bytes (%" G_GUINT64_FORMAT
2036 ")", upstream_total_bytes);
2037 aacparse->file_size = upstream_total_bytes;
2039 if ((byte_cur == -1) || (byte_cur > aacparse->file_size)) {
2040 GST_INFO_OBJECT (parse,
2041 "[WEB-ERROR] seek cur (%" G_GINT64_FORMAT ") > file_size (%"
2042 G_GINT64_FORMAT ") ", cur, aacparse->file_size);
2046 GST_INFO_OBJECT (parse,
2047 "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %"
2048 G_GINT64_FORMAT, rate, byte_cur, stop);
2050 if (!(flags & GST_SEEK_FLAG_KEY_UNIT)) {
2051 GST_INFO_OBJECT (parse,
2052 "Requested seek time: %" GST_TIME_FORMAT ", calculated seek offset: %"
2053 G_GUINT64_FORMAT, GST_TIME_ARGS (cur), byte_cur);
2056 /* BYTE seek event */
2058 gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
2060 res = gst_pad_push_event (parse->sinkpad, event);
2068 GST_DEBUG_OBJECT (parse,
2069 "could not determine byte position to seek to, " "seek aborted.");
2075 GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
2082 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
2085 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
2087 ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
2095 * gst_aac_parse_adts_src_eventfunc:
2096 * @parse: #GstBaseParse. #event
2098 * before baseparse handles seek event, make full amr index table.
2100 * Returns: TRUE on success.
2103 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
2105 gboolean handled = FALSE;
2106 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2108 switch (GST_EVENT_TYPE (event)) {
2109 case GST_EVENT_SEEK:
2111 GstFlowReturn res = GST_FLOW_OK;
2112 gint64 base_offset = 0, cur = 0;
2113 gint32 frame_count = 1; /* do not add first frame because it is already in index table */
2114 gint64 second_count = 0; /* initial 1 second */
2115 gint64 total_file_size = 0, start_offset = 0;
2116 GstClockTime current_ts = GST_CLOCK_TIME_NONE;
2117 GstPadMode pad_mode = GST_PAD_MODE_NONE;
2119 /* check baseparse define these fuction */
2120 gst_base_parse_get_pad_mode (parse, &pad_mode);
2121 if (pad_mode != GST_PAD_MODE_PULL) {
2122 gboolean ret = FALSE;
2123 GstPad *srcpad = parse->srcpad;
2124 GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
2126 ret = gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
2127 gst_object_unref (srcpad);
2130 gst_base_parse_get_upstream_size (parse, &total_file_size);
2131 gst_base_parse_get_index_last_offset (parse, &start_offset);
2132 gst_base_parse_get_index_last_ts (parse, ¤t_ts);
2134 if (total_file_size > AAC_LARGE_FILE_SIZE) {
2135 gst_base_parse_set_seek_mode (parse, 0);
2136 GST_INFO_OBJECT (aacparse, "larger than big size (2MB).");
2137 goto aac_seek_null_exit;
2140 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2142 if (total_file_size == 0 || start_offset >= total_file_size) {
2143 GST_ERROR ("last index offset %" G_GINT64_FORMAT
2144 " is larger than file size %" G_GINT64_FORMAT, start_offset,
2149 gst_event_parse_seek (event, NULL, NULL, NULL, NULL, &cur, NULL, NULL);
2150 if (cur <= current_ts) {
2151 GST_INFO ("seek to %" GST_TIME_FORMAT " within index table %"
2152 GST_TIME_FORMAT ". do not make index table", GST_TIME_ARGS (cur),
2153 GST_TIME_ARGS (current_ts));
2156 GST_INFO ("seek to %" GST_TIME_FORMAT " without index table %"
2157 GST_TIME_FORMAT ". make index table", GST_TIME_ARGS (cur),
2158 GST_TIME_ARGS (current_ts));
2161 GST_INFO ("make AAC(ADTS) Index Table. file_size = %" G_GINT64_FORMAT
2162 " last idx offset=%" G_GINT64_FORMAT ", last idx ts=%"
2163 GST_TIME_FORMAT, total_file_size, start_offset,
2164 GST_TIME_ARGS (current_ts));
2166 base_offset = start_offset; /* set base by start offset */
2167 second_count = current_ts + GST_SECOND; /* 1sec */
2169 /************************************/
2170 /* STEP 0: Setting parse information */
2171 /************************************/
2172 aacparse->spf = aacparse->frame_samples;
2173 aacparse->frame_duration = (aacparse->spf * 1000 * 100) / aacparse->sample_rate; /* duration per frame (msec) */
2174 aacparse->frame_per_sec = (aacparse->sample_rate) / aacparse->spf; /* frames per second (ea) */
2176 /************************************/
2177 /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2178 /************************************/
2179 while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2181 GstBuffer *buffer = NULL;
2184 GST_INFO ("gst_pad_pull_range %d bytes (from %" G_GINT64_FORMAT
2185 ") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2187 gst_pad_pull_range (parse->sinkpad, base_offset,
2188 base_offset + AAC_MAX_PULL_RANGE_BUF, &buffer);
2189 if (res != GST_FLOW_OK) {
2190 GST_ERROR ("gst_pad_pull_range failed!");
2194 gst_buffer_map (buffer, &map, GST_MAP_READ);
2197 gst_buffer_unmap (buffer, &map);
2198 GST_WARNING ("buffer is NULL in make aac seek table's STEP1");
2199 gst_buffer_unref (buffer);
2200 goto aac_seek_null_exit;
2203 while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2204 gint frame_size = 0;
2206 /* make sure the values in the frame header look sane */
2207 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2209 if ((frame_size > 0)
2210 && (frame_size < (AAC_MAX_PULL_RANGE_BUF - offset))) {
2211 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2212 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2213 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2214 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2215 base_offset + offset);
2216 second_count += GST_SECOND; /* 1sec */
2219 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2220 offset += frame_size;
2223 } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2224 GST_DEBUG ("we need refill buffer");
2227 GST_WARNING ("we lost sync");
2233 base_offset = base_offset + offset;
2235 gst_buffer_unmap (buffer, &map);
2236 gst_buffer_unref (buffer);
2237 } /* end MAX buffer cycle */
2239 /*******************************/
2240 /* STEP 2: Remain Buffer cycle */
2241 /*******************************/
2242 if (total_file_size - base_offset > 0) {
2244 GstBuffer *buffer = NULL;
2248 GST_INFO ("gst_pad_pull_range %" G_GINT64_FORMAT " bytes (from %"
2249 G_GINT64_FORMAT ") use remain_buf size",
2250 total_file_size - base_offset, base_offset);
2252 gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size,
2254 if (res != GST_FLOW_OK) {
2255 GST_ERROR ("gst_pad_pull_range failed!");
2259 gst_buffer_map (buffer, &map, GST_MAP_READ);
2262 gst_buffer_unmap (buffer, &map);
2263 GST_WARNING ("buffer is NULL in make aac seek table's STEP2");
2264 gst_buffer_unref (buffer);
2265 goto aac_seek_null_exit;
2268 while (base_offset + offset < total_file_size) {
2269 gint frame_size = 0;
2271 /* make sure the values in the frame header look sane */
2272 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2274 if ((frame_size > 0)
2275 && (frame_size <= (total_file_size - (base_offset + offset)))) {
2276 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2277 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2278 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2279 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2280 base_offset + offset);
2281 second_count += GST_SECOND; /* 1sec */
2284 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2285 offset += frame_size;
2288 } else if (frame_size == 0) {
2289 GST_DEBUG ("Frame size is 0 so, Decoding end..");
2292 GST_WARNING ("we lost sync");
2298 gst_buffer_unmap (buffer, &map);
2299 gst_buffer_unref (buffer);
2301 /* end remain_buf buffer cycle */
2302 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2312 /* call baseparse src_event function to handle event */
2313 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2316 #endif //end of #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION