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[32] = {
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[32] = {
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);
110 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
111 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
112 static gboolean gst_aac_parse_src_eventfunc(GstBaseParse * parse,
114 /* make full aac(adts) index table when seek */
115 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
117 int get_aac_parse_get_adts_frame_length (const unsigned char* data,
119 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
122 G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
124 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
126 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
128 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
129 32000, 24000, 22050, 16000, 12000, 11025, 8000
132 if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
133 return aac_sample_rates[sr_idx];
134 GST_WARNING ("Invalid sample rate index %u", sr_idx);
139 * gst_aac_parse_class_init:
140 * @klass: #GstAacParseClass.
144 gst_aac_parse_class_init (GstAacParseClass * klass)
146 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
147 GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
149 GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
150 "AAC audio stream parser");
152 gst_element_class_add_pad_template (element_class,
153 gst_static_pad_template_get (&sink_template));
154 gst_element_class_add_pad_template (element_class,
155 gst_static_pad_template_get (&src_template));
157 gst_element_class_set_static_metadata (element_class,
158 "AAC audio stream parser", "Codec/Parser/Audio",
159 "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
161 parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
162 parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
163 parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
164 parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
165 parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_handle_frame);
166 parse_class->pre_push_frame =
167 GST_DEBUG_FUNCPTR (gst_aac_parse_pre_push_frame);
168 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
169 /* make full aac(adts) index table when seek */
170 parse_class->src_event = GST_DEBUG_FUNCPTR (gst_aac_parse_src_eventfunc);
176 * gst_aac_parse_init:
177 * @aacparse: #GstAacParse.
178 * @klass: #GstAacParseClass.
182 gst_aac_parse_init (GstAacParse * aacparse)
184 GST_DEBUG ("initialized");
185 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (aacparse));
186 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (aacparse));
187 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
188 /* to get more correct duration */
189 aacparse->first_frame = TRUE;
195 * gst_aac_parse_set_src_caps:
196 * @aacparse: #GstAacParse.
197 * @sink_caps: (proposed) caps of sink pad
199 * Set source pad caps according to current knowledge about the
202 * Returns: TRUE if caps were successfully set.
205 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
208 GstCaps *src_caps = NULL, *allowed;
209 gboolean res = FALSE;
210 const gchar *stream_format;
211 guint8 codec_data[2];
212 guint16 codec_data_data;
213 gint sample_rate_idx;
215 GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
217 src_caps = gst_caps_copy (sink_caps);
219 src_caps = gst_caps_new_empty_simple ("audio/mpeg");
221 gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
222 "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
224 aacparse->output_header_type = aacparse->header_type;
225 switch (aacparse->header_type) {
226 case DSPAAC_HEADER_NONE:
227 stream_format = "raw";
229 case DSPAAC_HEADER_ADTS:
230 stream_format = "adts";
232 case DSPAAC_HEADER_ADIF:
233 stream_format = "adif";
235 case DSPAAC_HEADER_LOAS:
236 stream_format = "loas";
239 stream_format = NULL;
242 /* Generate codec data to be able to set profile/level on the caps */
244 gst_codec_utils_aac_get_index_from_sample_rate (aacparse->sample_rate);
245 if (sample_rate_idx < 0)
246 goto not_a_known_rate;
248 (aacparse->object_type << 11) |
249 (sample_rate_idx << 7) | (aacparse->channels << 3);
250 GST_WRITE_UINT16_BE (codec_data, codec_data_data);
251 gst_codec_utils_aac_caps_set_level_and_profile (src_caps, codec_data, 2);
253 s = gst_caps_get_structure (src_caps, 0);
254 if (aacparse->sample_rate > 0)
255 gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
256 if (aacparse->channels > 0)
257 gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
259 gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
261 allowed = gst_pad_get_allowed_caps (GST_BASE_PARSE (aacparse)->srcpad);
262 if (allowed && !gst_caps_can_intersect (src_caps, allowed)) {
263 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
264 "Caps can not intersect");
265 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
266 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
267 "Input is ADTS, trying raw");
268 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "raw",
270 if (gst_caps_can_intersect (src_caps, allowed)) {
271 GstBuffer *codec_data_buffer;
273 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
274 "Caps can intersect, we will drop the ADTS layer");
275 aacparse->output_header_type = DSPAAC_HEADER_NONE;
277 /* The codec_data data is according to AudioSpecificConfig,
278 ISO/IEC 14496-3, 1.6.2.1 */
279 codec_data_buffer = gst_buffer_new_and_alloc (2);
280 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
281 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
282 codec_data_buffer, NULL);
284 } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
285 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
286 "Input is raw, trying ADTS");
287 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
289 if (gst_caps_can_intersect (src_caps, allowed)) {
290 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
291 "Caps can intersect, we will prepend ADTS headers");
292 aacparse->output_header_type = DSPAAC_HEADER_ADTS;
297 gst_caps_unref (allowed);
299 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
301 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
302 gst_caps_unref (src_caps);
306 GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
307 aacparse->sample_rate);
308 gst_caps_unref (src_caps);
314 * gst_aac_parse_sink_setcaps:
318 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
320 * Returns: TRUE on success.
323 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
325 GstAacParse *aacparse;
326 GstStructure *structure;
330 aacparse = GST_AAC_PARSE (parse);
331 structure = gst_caps_get_structure (caps, 0);
332 caps_str = gst_caps_to_string (caps);
334 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
337 /* This is needed at least in case of RTP
338 * Parses the codec_data information to get ObjectType,
339 * number of channels and samplerate */
340 value = gst_structure_get_value (structure, "codec_data");
342 GstBuffer *buf = gst_value_get_buffer (value);
348 gst_buffer_map (buf, &map, GST_MAP_READ);
350 sr_idx = ((map.data[0] & 0x07) << 1) | ((map.data[1] & 0x80) >> 7);
351 aacparse->object_type = (map.data[0] & 0xf8) >> 3;
352 aacparse->sample_rate =
353 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
354 aacparse->channels = (map.data[1] & 0x78) >> 3;
355 if (aacparse->channels == 7)
356 aacparse->channels = 8;
357 else if (aacparse->channels == 11)
358 aacparse->channels = 7;
359 else if (aacparse->channels == 12 || aacparse->channels == 14)
360 aacparse->channels = 8;
361 aacparse->header_type = DSPAAC_HEADER_NONE;
362 aacparse->mpegversion = 4;
363 aacparse->frame_samples = (map.data[1] & 4) ? 960 : 1024;
364 gst_buffer_unmap (buf, &map);
366 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
367 "samples=%d", aacparse->object_type, aacparse->sample_rate,
368 aacparse->channels, aacparse->frame_samples);
370 /* arrange for metadata and get out of the way */
371 gst_aac_parse_set_src_caps (aacparse, caps);
372 if (aacparse->header_type == aacparse->output_header_type)
373 gst_base_parse_set_passthrough (parse, TRUE);
377 /* caps info overrides */
378 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
379 gst_structure_get_int (structure, "channels", &aacparse->channels);
381 aacparse->sample_rate = 0;
382 aacparse->channels = 0;
383 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
384 gst_base_parse_set_passthrough (parse, FALSE);
392 * gst_aac_parse_adts_get_frame_len:
393 * @data: block of data containing an ADTS header.
395 * This function calculates ADTS frame length from the given header.
397 * Returns: size of the ADTS frame.
400 gst_aac_parse_adts_get_frame_len (const guint8 * data)
402 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
407 * gst_aac_parse_check_adts_frame:
408 * @aacparse: #GstAacParse.
409 * @data: Data to be checked.
410 * @avail: Amount of data passed.
411 * @framesize: If valid ADTS frame was found, this will be set to tell the
412 * found frame size in bytes.
413 * @needed_data: If frame was not found, this may be set to tell how much
414 * more data is needed in the next round to detect the frame
415 * reliably. This may happen when a frame header candidate
416 * is found but it cannot be guaranteed to be the header without
417 * peeking the following data.
419 * Check if the given data contains contains ADTS frame. The algorithm
420 * will examine ADTS frame header and calculate the frame size. Also, another
421 * consecutive ADTS frame header need to be present after the found frame.
422 * Otherwise the data is not considered as a valid ADTS frame. However, this
423 * "extra check" is omitted when EOS has been received. In this case it is
424 * enough when data[0] contains a valid ADTS header.
426 * This function may set the #needed_data to indicate that a possible frame
427 * candidate has been found, but more data (#needed_data bytes) is needed to
428 * be absolutely sure. When this situation occurs, FALSE will be returned.
430 * When a valid frame is detected, this function will use
431 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
432 * to set the needed bytes for next frame.This way next data chunk is already
435 * Returns: TRUE if the given data contains a valid ADTS header.
438 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
439 const guint8 * data, const guint avail, gboolean drain,
440 guint * framesize, guint * needed_data)
446 /* Absolute minimum to perform the ADTS syncword,
447 layer and sampling frequency tests */
448 if (G_UNLIKELY (avail < 3)) {
453 /* Syncword and layer tests */
454 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
456 /* Sampling frequency test */
457 if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
460 /* This looks like an ADTS frame header but
461 we need at least 6 bytes to proceed */
462 if (G_UNLIKELY (avail < 6)) {
467 *framesize = gst_aac_parse_adts_get_frame_len (data);
469 /* If frame has CRC, it needs 2 bytes
470 for it at the end of the header */
471 crc_size = (data[1] & 0x01) ? 0 : 2;
474 if (*framesize < 7 + crc_size) {
475 *needed_data = 7 + crc_size;
479 /* In EOS mode this is enough. No need to examine the data further.
480 We also relax the check when we have sync, on the assumption that
481 if we're not looking at random data, we have a much higher chance
482 to get the correct sync, and this avoids losing two frames when
483 a single bit corruption happens. */
484 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
488 if (*framesize + ADTS_MAX_SIZE > avail) {
489 /* We have found a possible frame header candidate, but can't be
490 sure since we don't have enough data to check the next frame */
491 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
492 *framesize + ADTS_MAX_SIZE, avail);
493 *needed_data = *framesize + ADTS_MAX_SIZE;
494 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
495 *framesize + ADTS_MAX_SIZE);
499 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
500 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
502 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
503 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
504 nextlen + ADTS_MAX_SIZE);
512 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
515 guint8 bytes, i, byte;
518 if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
520 for (i = 0; i < bytes; ++i) {
522 if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
530 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
531 guint8 * audio_object_type)
533 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
535 if (*audio_object_type == 31) {
536 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
538 *audio_object_type += 32;
540 GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
545 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
548 guint8 sampling_frequency_index;
549 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
551 GST_LOG_OBJECT (aacparse, "sampling_frequency_index: %u",
552 sampling_frequency_index);
553 if (sampling_frequency_index == 0xf) {
554 guint32 sampling_rate;
555 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
557 *sample_rate = sampling_rate;
559 *sample_rate = loas_sample_rate_table[sampling_frequency_index];
566 /* See table 1.13 in ISO/IEC 14496-3 */
568 gst_aac_parse_read_loas_audio_specific_config (GstAacParse * aacparse,
569 GstBitReader * br, gint * sample_rate, gint * channels, guint32 * bits)
571 guint8 audio_object_type, channel_configuration;
573 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
576 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
579 if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
581 GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
582 *channels = loas_channels_table[channel_configuration];
586 if (audio_object_type == 5) {
587 GST_LOG_OBJECT (aacparse,
588 "Audio object type 5, so rereading sampling rate...");
589 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
593 GST_INFO_OBJECT (aacparse, "Found LOAS config: %d Hz, %d channels",
594 *sample_rate, *channels);
596 /* There's LOTS of stuff next, but we ignore it for now as we have
597 what we want (sample rate and number of channels */
598 GST_DEBUG_OBJECT (aacparse,
599 "Need more code to parse humongous LOAS data, currently ignored");
607 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
608 guint avail, gint * sample_rate, gint * channels, gint * version)
613 /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
617 gst_bit_reader_init (&br, data, avail);
619 /* skip sync word (11 bits) and size (13 bits) */
620 if (!gst_bit_reader_skip (&br, 11 + 13))
623 /* First bit is "use last config" */
624 if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
627 GST_LOG_OBJECT (aacparse, "Frame uses previous config");
628 if (!aacparse->sample_rate || !aacparse->channels) {
629 GST_DEBUG_OBJECT (aacparse,
630 "No previous config to use. We'll look for more data.");
633 *sample_rate = aacparse->sample_rate;
634 *channels = aacparse->channels;
638 GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
640 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
643 if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
648 GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
650 guint8 same_time, subframes, num_program, prog;
653 if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
656 if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
658 if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
660 if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
662 GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
663 same_time, subframes, num_program);
665 for (prog = 0; prog <= num_program; ++prog) {
666 guint8 num_layer, layer;
667 if (!gst_bit_reader_get_bits_uint8 (&br, &num_layer, 3))
669 GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
671 for (layer = 0; layer <= num_layer; ++layer) {
672 guint8 use_same_config;
673 if (prog == 0 && layer == 0) {
676 if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
679 if (!use_same_config) {
681 if (!gst_aac_parse_read_loas_audio_specific_config (aacparse, &br,
682 sample_rate, channels, NULL))
685 guint32 bits, asc_len;
686 if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
688 if (!gst_aac_parse_read_loas_audio_specific_config (aacparse, &br,
689 sample_rate, channels, &bits))
692 if (!gst_bit_reader_skip (&br, asc_len))
698 GST_LOG_OBJECT (aacparse, "More data ignored");
700 GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
707 * gst_aac_parse_loas_get_frame_len:
708 * @data: block of data containing a LOAS header.
710 * This function calculates LOAS frame length from the given header.
712 * Returns: size of the LOAS frame.
715 gst_aac_parse_loas_get_frame_len (const guint8 * data)
717 return (((data[1] & 0x1f) << 8) | data[2]) + 3;
722 * gst_aac_parse_check_loas_frame:
723 * @aacparse: #GstAacParse.
724 * @data: Data to be checked.
725 * @avail: Amount of data passed.
726 * @framesize: If valid LOAS frame was found, this will be set to tell the
727 * found frame size in bytes.
728 * @needed_data: If frame was not found, this may be set to tell how much
729 * more data is needed in the next round to detect the frame
730 * reliably. This may happen when a frame header candidate
731 * is found but it cannot be guaranteed to be the header without
732 * peeking the following data.
734 * Check if the given data contains contains LOAS frame. The algorithm
735 * will examine LOAS frame header and calculate the frame size. Also, another
736 * consecutive LOAS frame header need to be present after the found frame.
737 * Otherwise the data is not considered as a valid LOAS frame. However, this
738 * "extra check" is omitted when EOS has been received. In this case it is
739 * enough when data[0] contains a valid LOAS header.
741 * This function may set the #needed_data to indicate that a possible frame
742 * candidate has been found, but more data (#needed_data bytes) is needed to
743 * be absolutely sure. When this situation occurs, FALSE will be returned.
745 * When a valid frame is detected, this function will use
746 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
747 * to set the needed bytes for next frame.This way next data chunk is already
750 * LOAS can have three different formats, if I read the spec correctly. Only
751 * one of them is supported here, as the two samples I have use this one.
753 * Returns: TRUE if the given data contains a valid LOAS header.
756 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
757 const guint8 * data, const guint avail, gboolean drain,
758 guint * framesize, guint * needed_data)
763 if (G_UNLIKELY (avail < 3)) {
768 if ((data[0] == 0x56) && ((data[1] & 0xe0) == 0xe0)) {
769 *framesize = gst_aac_parse_loas_get_frame_len (data);
770 GST_DEBUG_OBJECT (aacparse, "Found %u byte LOAS frame", *framesize);
772 /* In EOS mode this is enough. No need to examine the data further.
773 We also relax the check when we have sync, on the assumption that
774 if we're not looking at random data, we have a much higher chance
775 to get the correct sync, and this avoids losing two frames when
776 a single bit corruption happens. */
777 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
781 if (*framesize + LOAS_MAX_SIZE > avail) {
782 /* We have found a possible frame header candidate, but can't be
783 sure since we don't have enough data to check the next frame */
784 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
785 *framesize + LOAS_MAX_SIZE, avail);
786 *needed_data = *framesize + LOAS_MAX_SIZE;
787 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
788 *framesize + LOAS_MAX_SIZE);
792 if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
793 guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
795 GST_LOG ("LOAS frame found, len: %d bytes", *framesize);
796 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
797 nextlen + LOAS_MAX_SIZE);
804 /* caller ensure sufficient data */
806 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
807 gint * rate, gint * channels, gint * object, gint * version)
811 gint sr_idx = (data[2] & 0x3c) >> 2;
813 *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
816 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
822 *version = (data[1] & 0x08) ? 2 : 4;
824 *object = ((data[2] & 0xc0) >> 6) + 1;
828 * gst_aac_parse_detect_stream:
829 * @aacparse: #GstAacParse.
830 * @data: A block of data that needs to be examined for stream characteristics.
831 * @avail: Size of the given datablock.
832 * @framesize: If valid stream was found, this will be set to tell the
833 * first frame size in bytes.
834 * @skipsize: If valid stream was found, this will be set to tell the first
835 * audio frame position within the given data.
837 * Examines the given piece of data and try to detect the format of it. It
838 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
839 * header. If the stream is detected, TRUE will be returned and #framesize
840 * is set to indicate the found frame size. Additionally, #skipsize might
841 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
842 * position of the frame inside given data chunk.
844 * Returns: TRUE on success.
847 gst_aac_parse_detect_stream (GstAacParse * aacparse,
848 const guint8 * data, const guint avail, gboolean drain,
849 guint * framesize, gint * skipsize)
851 gboolean found = FALSE;
852 guint need_data_adts = 0, need_data_loas;
855 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
857 /* FIXME: No need to check for ADIF if we are not in the beginning of the
860 /* Can we even parse the header? */
861 if (avail < MAX (ADTS_MAX_SIZE, LOAS_MAX_SIZE)) {
862 GST_DEBUG_OBJECT (aacparse, "Not enough data to check");
866 for (i = 0; i < avail - 4; i++) {
867 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
868 ((data[i] == 0x56) && ((data[i + 1] & 0xe0) == 0xe0)) ||
869 strncmp ((char *) data + i, "ADIF", 4) == 0) {
870 GST_DEBUG_OBJECT (aacparse, "Found signature at offset %u", i);
874 /* Trick: tell the parent class that we didn't find the frame yet,
875 but make it skip 'i' amount of bytes. Next time we arrive
876 here we have full frame in the beginning of the data. */
889 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
890 framesize, &need_data_adts)) {
893 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
895 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
896 &aacparse->object_type, &aacparse->mpegversion);
898 if (!channels || !framesize) {
899 GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
903 aacparse->header_type = DSPAAC_HEADER_ADTS;
904 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
905 aacparse->frame_samples, 2, 2);
907 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
908 rate, channels, aacparse->object_type, aacparse->mpegversion);
910 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
915 if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
916 framesize, &need_data_loas)) {
917 gint rate = 0, channels = 0;
919 GST_INFO ("LOAS, framesize: %d", *framesize);
921 aacparse->header_type = DSPAAC_HEADER_LOAS;
923 if (!gst_aac_parse_read_loas_config (aacparse, data, avail, &rate,
924 &channels, &aacparse->mpegversion)) {
925 /* This is pretty normal when skipping data at the start of
926 * random stream (MPEG-TS capture for example) */
927 GST_LOG_OBJECT (aacparse, "Error reading LOAS config");
931 if (rate && channels) {
932 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
933 aacparse->frame_samples, 2, 2);
935 /* Don't store the sample rate and channels yet -
936 * this is just format detection. */
937 GST_DEBUG ("LOAS: samplerate %d, channels %d, objtype %d, version %d",
938 rate, channels, aacparse->object_type, aacparse->mpegversion);
941 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
946 if (need_data_adts || need_data_loas) {
947 /* This tells the parent class not to skip any data */
952 if (avail < ADIF_MAX_SIZE)
955 if (memcmp (data + i, "ADIF", 4) == 0) {
962 aacparse->header_type = DSPAAC_HEADER_ADIF;
963 aacparse->mpegversion = 4;
965 /* Skip the "ADIF" bytes */
968 /* copyright string */
970 skip_size += 9; /* skip 9 bytes */
972 bitstream_type = adif[0 + skip_size] & 0x10;
974 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
975 ((unsigned int) adif[1 + skip_size] << 11) |
976 ((unsigned int) adif[2 + skip_size] << 3) |
977 ((unsigned int) adif[3 + skip_size] & 0xe0);
980 if (bitstream_type == 0) {
982 /* Buffer fullness parsing. Currently not needed... */
986 num_elems = (adif[3 + skip_size] & 0x1e);
987 GST_INFO ("ADIF num_config_elems: %d", num_elems);
989 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
990 ((unsigned int) adif[4 + skip_size] << 11) |
991 ((unsigned int) adif[5 + skip_size] << 3) |
992 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
994 GST_INFO ("ADIF buffer fullness: %d", fullness);
996 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
997 ((adif[7 + skip_size] & 0x80) >> 7);
998 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
1002 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
1003 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
1004 ((adif[5 + skip_size] & 0x80) >> 7);
1007 /* FIXME: This gives totally wrong results. Duration calculation cannot
1009 aacparse->sample_rate =
1010 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1012 /* baseparse is not given any fps,
1013 * so it will give up on timestamps, seeking, etc */
1015 /* FIXME: Can we assume this? */
1016 aacparse->channels = 2;
1018 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1019 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1021 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1023 /* arrange for metadata and get out of the way */
1024 sinkcaps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (aacparse));
1025 gst_aac_parse_set_src_caps (aacparse, sinkcaps);
1027 gst_caps_unref (sinkcaps);
1029 /* not syncable, not easily seekable (unless we push data from start */
1030 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
1031 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
1032 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
1038 /* This should never happen */
1043 * gst_aac_parse_get_audio_profile_object_type
1044 * @aacparse: #GstAacParse.
1046 * Gets the MPEG-2 profile or the MPEG-4 object type value corresponding to the
1047 * mpegversion and profile of @aacparse's src pad caps, according to the
1048 * values defined by table 1.A.11 in ISO/IEC 14496-3.
1050 * Returns: the profile or object type value corresponding to @aacparse's src
1051 * pad caps, if such a value exists; otherwise G_MAXUINT8.
1054 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1057 GstStructure *srcstruct;
1058 const gchar *profile;
1061 srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1062 srcstruct = gst_caps_get_structure (srccaps, 0);
1063 profile = gst_structure_get_string (srcstruct, "profile");
1064 if (G_UNLIKELY (profile == NULL)) {
1065 gst_caps_unref (srccaps);
1069 if (g_strcmp0 (profile, "main") == 0) {
1071 } else if (g_strcmp0 (profile, "lc") == 0) {
1073 } else if (g_strcmp0 (profile, "ssr") == 0) {
1075 } else if (g_strcmp0 (profile, "ltp") == 0) {
1076 if (G_LIKELY (aacparse->mpegversion == 4))
1079 ret = G_MAXUINT8; /* LTP Object Type allowed only for MPEG-4 */
1084 gst_caps_unref (srccaps);
1089 * gst_aac_parse_get_audio_channel_configuration
1090 * @num_channels: number of audio channels.
1092 * Gets the Channel Configuration value, as defined by table 1.19 in ISO/IEC
1093 * 14496-3, for a given number of audio channels.
1095 * Returns: the Channel Configuration value corresponding to @num_channels, if
1096 * such a value exists; otherwise G_MAXUINT8.
1099 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1101 if (num_channels >= 1 && num_channels <= 6) /* Mono up to & including 5.1 */
1102 return (guint8) num_channels;
1103 else if (num_channels == 8) /* 7.1 */
1108 /* FIXME: Add support for configurations 11, 12 and 14 from
1109 * ISO/IEC 14496-3:2009/PDAM 4 based on the actual channel layout
1114 * gst_aac_parse_get_audio_sampling_frequency_index:
1115 * @sample_rate: audio sampling rate.
1117 * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1118 * 14496-3, for a given sampling rate.
1120 * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1121 * if such a value exists; otherwise G_MAXUINT8.
1124 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1126 switch (sample_rate) {
1159 * gst_aac_parse_prepend_adts_headers:
1160 * @aacparse: #GstAacParse.
1161 * @frame: raw AAC frame to which ADTS headers shall be prepended.
1163 * Prepends ADTS headers to a raw AAC audio frame.
1165 * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1168 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1169 GstBaseParseFrame * frame)
1172 guint8 *adts_headers;
1175 guint8 id, profile, channel_configuration, sampling_frequency_index;
1177 id = (aacparse->mpegversion == 4) ? 0x0U : 0x1U;
1178 profile = gst_aac_parse_get_audio_profile_object_type (aacparse);
1179 if (profile == G_MAXUINT8) {
1180 GST_ERROR_OBJECT (aacparse, "Unsupported audio profile or object type");
1183 channel_configuration =
1184 gst_aac_parse_get_audio_channel_configuration (aacparse->channels);
1185 if (channel_configuration == G_MAXUINT8) {
1186 GST_ERROR_OBJECT (aacparse, "Unsupported number of channels");
1189 sampling_frequency_index =
1190 gst_aac_parse_get_audio_sampling_frequency_index (aacparse->sample_rate);
1191 if (sampling_frequency_index == G_MAXUINT8) {
1192 GST_ERROR_OBJECT (aacparse, "Unsupported sampling frequency");
1196 frame->out_buffer = gst_buffer_copy (frame->buffer);
1197 buf_size = gst_buffer_get_size (frame->out_buffer);
1198 frame_size = buf_size + ADTS_HEADERS_LENGTH;
1200 if (G_UNLIKELY (frame_size >= 0x4000)) {
1201 GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1205 adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1207 /* Note: no error correction bits are added to the resulting ADTS frames */
1208 adts_headers[0] = 0xFFU;
1209 adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
1210 adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
1211 (channel_configuration & 0x4U);
1212 adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
1213 (guint8) (frame_size >> 11);
1214 adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
1215 adts_headers[5] = (guint8) (((frame_size & 0x0007) << 5) + 0x1FU);
1216 adts_headers[6] = 0xFCU;
1218 mem = gst_memory_new_wrapped (0, adts_headers, ADTS_HEADERS_LENGTH, 0,
1219 ADTS_HEADERS_LENGTH, adts_headers, g_free);
1220 gst_buffer_prepend_memory (frame->out_buffer, mem);
1226 * gst_aac_parse_check_valid_frame:
1227 * @parse: #GstBaseParse.
1228 * @frame: #GstBaseParseFrame.
1229 * @skipsize: How much data parent class should skip in order to find the
1232 * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1234 * Also determines frame overhead.
1235 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
1236 * a per-frame header. LOAS has 3 bytes.
1238 * We're making a couple of simplifying assumptions:
1240 * 1. We count Program Configuration Elements rather than searching for them
1241 * in the streams to discount them - the overhead is negligible.
1243 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
1244 * bits, which should still not be significant enough to warrant the
1245 * additional parsing through the headers
1247 * Returns: a #GstFlowReturn.
1249 static GstFlowReturn
1250 gst_aac_parse_handle_frame (GstBaseParse * parse,
1251 GstBaseParseFrame * frame, gint * skipsize)
1254 GstAacParse *aacparse;
1255 gboolean ret = FALSE;
1259 gint rate = 0, channels = 0;
1261 aacparse = GST_AAC_PARSE (parse);
1262 buffer = frame->buffer;
1264 gst_buffer_map (buffer, &map, GST_MAP_READ);
1267 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1269 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
1270 aacparse->header_type == DSPAAC_HEADER_NONE) {
1271 /* There is nothing to parse */
1272 framesize = map.size;
1275 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1277 ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1278 GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1280 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1281 guint needed_data = 1024;
1283 ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1284 GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1286 if (!ret && needed_data) {
1287 GST_DEBUG ("buffer didn't contain valid frame");
1289 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1293 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1294 guint needed_data = 1024;
1296 ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1297 map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1299 if (!ret && needed_data) {
1300 GST_DEBUG ("buffer didn't contain valid frame");
1302 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1307 GST_DEBUG ("buffer didn't contain valid frame");
1308 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1312 if (G_UNLIKELY (!ret))
1315 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1317 frame->overhead = 7;
1319 gst_aac_parse_parse_adts_header (aacparse, map.data,
1320 &rate, &channels, NULL, NULL);
1322 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1324 if (G_UNLIKELY (rate != aacparse->sample_rate
1325 || channels != aacparse->channels)) {
1326 aacparse->sample_rate = rate;
1327 aacparse->channels = channels;
1329 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1330 /* If linking fails, we need to return appropriate error */
1331 ret = GST_FLOW_NOT_LINKED;
1334 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1335 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1337 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1338 if (aacparse->first_frame == TRUE) {
1339 gboolean ret = FALSE;
1340 aacparse->first_frame = FALSE;
1342 ret = gst_aac_parse_estimate_duration(parse);
1344 GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1345 ret = GST_FLOW_NOT_SUPPORTED;
1349 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1350 gboolean setcaps = FALSE;
1353 frame->overhead = 3;
1355 if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
1356 &channels, NULL) || !rate || !channels) {
1357 /* This is pretty normal when skipping data at the start of
1358 * random stream (MPEG-TS capture for example) */
1359 GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
1360 *skipsize = map.size;
1364 if (G_UNLIKELY (rate != aacparse->sample_rate
1365 || channels != aacparse->channels)) {
1366 aacparse->sample_rate = rate;
1367 aacparse->channels = channels;
1369 GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1373 /* We want to set caps both at start, and when rate/channels change.
1374 Since only some LOAS frames have that info, we may receive frames
1375 before knowing about rate/channels. */
1377 || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
1378 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1379 /* If linking fails, we need to return appropriate error */
1380 ret = GST_FLOW_NOT_LINKED;
1383 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1384 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1387 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1388 else if(aacparse->header_type == DSPAAC_HEADER_ADIF)
1390 /* to get more correct duration */
1392 float estimated_duration = 0;
1393 gint64 total_file_size;
1394 gst_base_parse_get_upstream_size(parse, &total_file_size);
1395 estimated_duration = ((total_file_size * 8) / (float)(aacparse->bitrate * 1000))* GST_SECOND;
1396 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration * 1000, 0);
1400 if (aacparse->header_type == DSPAAC_HEADER_NONE
1401 && aacparse->output_header_type == DSPAAC_HEADER_ADTS) {
1402 if (!gst_aac_parse_prepend_adts_headers (aacparse, frame)) {
1403 GST_ERROR_OBJECT (aacparse, "Failed to prepend ADTS headers to frame");
1404 ret = GST_FLOW_ERROR;
1409 gst_buffer_unmap (buffer, &map);
1412 /* found, skip if needed */
1421 if (ret && framesize <= map.size) {
1422 return gst_base_parse_finish_frame (parse, frame, framesize);
1428 static GstFlowReturn
1429 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1431 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1433 if (!aacparse->sent_codec_tag) {
1434 GstTagList *taglist;
1437 taglist = gst_tag_list_new_empty ();
1440 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1441 gst_pb_utils_add_codec_description_to_tag_list (taglist,
1442 GST_TAG_AUDIO_CODEC, caps);
1443 gst_caps_unref (caps);
1445 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1446 gst_tag_list_unref (taglist);
1448 /* also signals the end of first-frame processing */
1449 aacparse->sent_codec_tag = TRUE;
1452 /* As a special case, we can remove the ADTS framing and output raw AAC. */
1453 if (aacparse->header_type == DSPAAC_HEADER_ADTS
1454 && aacparse->output_header_type == DSPAAC_HEADER_NONE) {
1457 gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
1458 header_size = (map.data[1] & 1) ? 7 : 9; /* optional CRC */
1459 gst_buffer_unmap (frame->buffer, &map);
1460 gst_buffer_resize (frame->buffer, header_size,
1461 gst_buffer_get_size (frame->buffer) - header_size);
1469 * gst_aac_parse_start:
1470 * @parse: #GstBaseParse.
1472 * Implementation of "start" vmethod in #GstBaseParse class.
1474 * Returns: TRUE if startup succeeded.
1477 gst_aac_parse_start (GstBaseParse * parse)
1479 GstAacParse *aacparse;
1481 aacparse = GST_AAC_PARSE (parse);
1482 GST_DEBUG ("start");
1483 aacparse->frame_samples = 1024;
1484 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
1485 aacparse->sent_codec_tag = FALSE;
1491 * gst_aac_parse_stop:
1492 * @parse: #GstBaseParse.
1494 * Implementation of "stop" vmethod in #GstBaseParse class.
1496 * Returns: TRUE is stopping succeeded.
1499 gst_aac_parse_stop (GstBaseParse * parse)
1506 remove_fields (GstCaps * caps)
1510 n = gst_caps_get_size (caps);
1511 for (i = 0; i < n; i++) {
1512 GstStructure *s = gst_caps_get_structure (caps, i);
1514 gst_structure_remove_field (s, "framed");
1519 add_conversion_fields (GstCaps * caps)
1523 n = gst_caps_get_size (caps);
1524 for (i = 0; i < n; i++) {
1525 GstStructure *s = gst_caps_get_structure (caps, i);
1527 if (gst_structure_has_field (s, "stream-format")) {
1528 const GValue *v = gst_structure_get_value (s, "stream-format");
1530 if (G_VALUE_HOLDS_STRING (v)) {
1531 const gchar *str = g_value_get_string (v);
1533 if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1534 GValue va = G_VALUE_INIT;
1535 GValue vs = G_VALUE_INIT;
1537 g_value_init (&va, GST_TYPE_LIST);
1538 g_value_init (&vs, G_TYPE_STRING);
1539 g_value_set_string (&vs, "adts");
1540 gst_value_list_append_value (&va, &vs);
1541 g_value_set_string (&vs, "raw");
1542 gst_value_list_append_value (&va, &vs);
1543 gst_structure_set_value (s, "stream-format", &va);
1544 g_value_unset (&va);
1545 g_value_unset (&vs);
1547 } else if (GST_VALUE_HOLDS_LIST (v)) {
1548 gboolean contains_raw = FALSE;
1549 gboolean contains_adts = FALSE;
1550 guint m = gst_value_list_get_size (v), j;
1552 for (j = 0; j < m; j++) {
1553 const GValue *ve = gst_value_list_get_value (v, j);
1556 if (G_VALUE_HOLDS_STRING (ve) && (str = g_value_get_string (ve))) {
1557 if (strcmp (str, "adts") == 0)
1558 contains_adts = TRUE;
1559 else if (strcmp (str, "raw") == 0)
1560 contains_raw = TRUE;
1564 if (contains_adts || contains_raw) {
1565 GValue va = G_VALUE_INIT;
1566 GValue vs = G_VALUE_INIT;
1568 g_value_init (&va, GST_TYPE_LIST);
1569 g_value_init (&vs, G_TYPE_STRING);
1570 g_value_copy (v, &va);
1572 if (!contains_raw) {
1573 g_value_set_string (&vs, "raw");
1574 gst_value_list_append_value (&va, &vs);
1576 if (!contains_adts) {
1577 g_value_set_string (&vs, "adts");
1578 gst_value_list_append_value (&va, &vs);
1581 gst_structure_set_value (s, "stream-format", &va);
1583 g_value_unset (&vs);
1584 g_value_unset (&va);
1592 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1594 GstCaps *peercaps, *templ;
1597 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1600 GstCaps *fcopy = gst_caps_copy (filter);
1601 /* Remove the fields we convert */
1602 remove_fields (fcopy);
1603 add_conversion_fields (fcopy);
1604 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1605 gst_caps_unref (fcopy);
1607 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1610 peercaps = gst_caps_make_writable (peercaps);
1611 /* Remove the fields we convert */
1612 remove_fields (peercaps);
1613 add_conversion_fields (peercaps);
1615 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1616 gst_caps_unref (peercaps);
1617 gst_caps_unref (templ);
1623 GstCaps *intersection;
1626 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1627 gst_caps_unref (res);
1634 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1636 * get_aac_parse_get_adts_framelength:
1637 * @data: #GstBufferData.
1638 * @offset: #GstBufferData offset
1640 * Implementation to get adts framelength by using first some frame.
1642 * Returns: frame size
1644 int get_aac_parse_get_adts_frame_length (const unsigned char* data,
1647 const gint adts_header_length_no_crc = 7;
1648 const gint adts_header_length_with_crc = 9;
1649 gint frame_size = 0;
1650 gint protection_absent;
1653 /* check of syncword */
1654 if ((data[offset+0] != 0xff) || ((data[offset+1] & 0xf6) != 0xf0)) {
1655 GST_ERROR("check sync word is fail\n");
1659 /* check of protection absent */
1660 protection_absent = (data[offset+1] & 0x01);
1662 /*check of frame length */
1663 frame_size = (data[offset+3] & 0x3) << 11 | data[offset+4] << 3 | data[offset+5] >> 5;
1665 /* check of header size */
1666 /* protectionAbsent is 0 if there is CRC */
1667 head_size = protection_absent ? adts_header_length_no_crc : adts_header_length_with_crc;
1668 if (head_size > frame_size) {
1669 GST_ERROR("return frame length as 0 (frameSize %u < headSize %u)", frame_size, head_size);
1677 * gst_aac_parse_estimate_duration:
1678 * @parse: #GstBaseParse.
1680 * Implementation to get estimated total duration by using first some frame.
1682 * Returns: TRUE if we can get estimated total duraion
1685 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1687 gboolean ret = FALSE;
1688 GstFlowReturn res = GST_FLOW_OK;
1689 gint64 pull_size = 0, file_size = 0, offset = 0, num_frames=0, duration=0;
1690 guint profile = 0, sample_rate_index = 0, sample_rate = 0, channel = 0;
1691 guint frame_size = 0, frame_duration_us = 0, estimated_bitrate = 0;
1692 guint lost_sync_count=0;
1693 GstClockTime estimated_duration = GST_CLOCK_TIME_NONE;
1694 GstBuffer *buffer = NULL;
1697 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1698 GstAacParse *aacparse;
1699 gint64 buffer_size = 0;
1701 aacparse = GST_AAC_PARSE (parse);
1702 GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1704 /* check baseparse define these fuction */
1705 gst_base_parse_get_pad_mode(parse, &pad_mode);
1706 if (pad_mode != GST_PAD_MODE_PULL) {
1707 GST_INFO_OBJECT (aacparse, "aac parser is not pull mode. can not estimate duration");
1711 gst_base_parse_get_upstream_size (parse, &file_size);
1713 if (file_size < ADIF_MAX_SIZE) {
1714 GST_ERROR_OBJECT (aacparse, "file size is too short");
1718 pull_size = MIN(file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1720 res = gst_pad_pull_range (parse->sinkpad, 0, pull_size, &buffer);
1721 if (res != GST_FLOW_OK) {
1722 GST_ERROR_OBJECT (aacparse, "gst_pad_pull_range failed!");
1727 gst_buffer_map(buffer, &map, GST_MAP_READ);
1729 buffer_size = map.size;
1730 if (buffer_size != pull_size) {
1731 GST_ERROR_OBJECT(aacparse, "We got different buffer_size(%d) with pull_size(%d).",
1732 buffer_size, pull_size);
1735 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1736 for (i = 0; i < buffer_size; i ++) {
1737 if ((buf[i] == 0xff) && ((buf[i+1] & 0xf6) == 0xf0)) { /* aac sync word */
1738 profile = (buf[i+2] >> 6) & 0x3;
1739 sample_rate_index = (buf[i+2] >> 2) & 0xf;
1740 sample_rate = gst_aac_parse_get_sample_rate_from_index(sample_rate_index);
1741 if (sample_rate == 0) {
1742 GST_WARNING_OBJECT (aacparse, "Invalid sample rate index (0)");
1745 channel = (buf[i+2] & 0x1) << 2 | (buf[i+3] >> 6);
1747 GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate, channel);
1749 /* count number of frames */
1750 /*MODIFICATION : add defence codes for real buffer_size is different with pull_size*/
1751 //while (offset < pull_size) {
1752 while (offset < buffer_size) {
1753 frame_size = get_aac_parse_get_adts_frame_length(buf, i + offset);
1754 if (frame_size == 0) {
1755 GST_ERROR_OBJECT (aacparse, "framesize error at offset %"G_GINT64_FORMAT, offset);
1757 } else if (frame_size == -1) {
1759 lost_sync_count++; // lost sync count limmitation 2K Bytes
1760 if (lost_sync_count > (1024*2)) {
1761 GST_WARNING_OBJECT (aacparse, "lost_sync_count is larger than 2048");
1765 offset += frame_size;
1771 /* if we can got full file, we can calculate the accurate duration */
1772 /*MODIFICATION : add defence codes for real buffer_size is different with pull_size*/
1773 //if (pull_size == file_size) {
1774 if (buffer_size == file_size) {
1775 gfloat duration_for_one_frame = 0;
1776 GstClockTime calculated_duration = GST_CLOCK_TIME_NONE;
1778 GST_INFO_OBJECT (aacparse, "we got total file (%d bytes). do not estimate but make Accurate total duration.", pull_size);
1780 duration_for_one_frame = (gfloat)AAC_SAMPLE_PER_FRAME / (gfloat)sample_rate;
1781 calculated_duration = num_frames * duration_for_one_frame * 1000 * 1000 * 1000;
1783 GST_INFO_OBJECT (aacparse, "duration_for_one_frame %f ms", duration_for_one_frame);
1784 GST_INFO_OBJECT (aacparse, "calculated duration = %"GST_TIME_FORMAT,
1785 GST_TIME_ARGS(calculated_duration));
1786 /* 0 means disable estimate */
1787 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, calculated_duration, 0);
1790 GST_INFO_OBJECT (aacparse, "we got %d bytes in total file (%"G_GINT64_FORMAT
1791 "). can not make accurate duration but Estimate.", pull_size, file_size);
1792 frame_duration_us = (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1793 duration = num_frames * frame_duration_us;
1795 if (duration == 0) {
1796 GST_WARNING_OBJECT (aacparse, "Invalid duration");
1799 estimated_bitrate = (gint)((gfloat)(offset * 8) / (gfloat)(duration / 1000));
1801 if (estimated_bitrate == 0) {
1802 GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1805 estimated_duration = (GstClockTime)((file_size * 8) / (estimated_bitrate * 1000)) * GST_SECOND;
1807 GST_INFO_OBJECT (aacparse, "number of frame = %"G_GINT64_FORMAT, num_frames);
1808 GST_INFO_OBJECT (aacparse, "duration = %"G_GINT64_FORMAT, duration / 1000000);
1809 GST_INFO_OBJECT (aacparse, "byte = %"G_GINT64_FORMAT, offset);
1810 GST_INFO_OBJECT (aacparse, "estimated bitrate = %d bps", estimated_bitrate);
1811 GST_INFO_OBJECT (aacparse, "estimated duration = %"GST_TIME_FORMAT, GST_TIME_ARGS(estimated_duration));
1813 gst_base_parse_set_average_bitrate (parse, estimated_bitrate * 1000);
1814 /* set update_interval as duration(sec)/2 */
1815 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration, (gint)(duration/2));
1824 gst_buffer_unmap(buffer, &map);
1825 gst_buffer_unref(buffer);
1830 /* perform seek in push based mode:
1831 find BYTE position to move to based on time and delegate to upstream
1834 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1835 GstPad * pad, GstEvent * event)
1837 GstAacParse *aacparse;
1838 aacparse = GST_AAC_PARSE(parse);
1843 GstSeekType cur_type, stop_type;
1847 gint64 esimate_byte;
1849 gint64 upstream_total_bytes = 0;
1850 GstFormat fmt = GST_FORMAT_BYTES;
1852 GST_INFO_OBJECT (parse, "doing aac push-based seek");
1854 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop);
1856 /* FIXME, always play to the end */
1859 /* only forward streaming and seeking is possible */
1861 goto unsupported_seek;
1864 /* handle rewind only */
1865 cur_type = GST_SEEK_TYPE_SET;
1867 stop_type = GST_SEEK_TYPE_NONE;
1869 flags |= GST_SEEK_FLAG_FLUSH;
1871 /* handle normal seek */
1872 cur_type = GST_SEEK_TYPE_SET;
1873 stop_type = GST_SEEK_TYPE_NONE;
1875 flags |= GST_SEEK_FLAG_FLUSH;
1877 esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
1878 if (aacparse->sample_rate> 0)
1879 frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
1881 goto unsupported_seek;
1883 byte_cur = esimate_byte / (frame_dur);
1885 goto unsupported_seek;
1887 GST_INFO_OBJECT(parse, "frame_byte(%d) spf(%d) rate (%d) ", aacparse->frame_byte, aacparse->spf, aacparse->sample_rate);
1888 GST_INFO_OBJECT(parse, "seek cur (%"G_GINT64_FORMAT") = (%"GST_TIME_FORMAT") ", cur, GST_TIME_ARGS (cur));
1889 GST_INFO_OBJECT(parse, "esimate_byte(%"G_GINT64_FORMAT") esimate_byte (%d)", esimate_byte, frame_dur );
1892 /* obtain real upstream total bytes */
1893 if (!gst_pad_peer_query_duration (parse->sinkpad, fmt, &upstream_total_bytes))
1894 upstream_total_bytes = 0;
1895 GST_INFO_OBJECT (aacparse, "gst_pad_query_peer_duration -upstream_total_bytes (%"G_GUINT64_FORMAT")", upstream_total_bytes);
1896 aacparse->file_size = upstream_total_bytes;
1898 if ( (byte_cur == -1) || (byte_cur > aacparse->file_size))
1900 GST_INFO_OBJECT(parse, "[WEB-ERROR] seek cur (%"G_GINT64_FORMAT") > file_size (%"G_GINT64_FORMAT") ", cur, aacparse->file_size );
1904 GST_INFO_OBJECT (parse, "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, byte_cur, stop);
1906 if (!(flags & GST_SEEK_FLAG_KEY_UNIT)) {
1907 GST_INFO_OBJECT (parse, "Requested seek time: %" GST_TIME_FORMAT ", calculated seek offset: %" G_GUINT64_FORMAT, GST_TIME_ARGS (cur), byte_cur);
1910 /* BYTE seek event */
1911 event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur, stop_type, stop);
1912 res = gst_pad_push_event (parse->sinkpad, event);
1920 GST_DEBUG_OBJECT (parse, "could not determine byte position to seek to, " "seek aborted.");
1926 GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
1933 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
1936 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
1937 length = ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
1945 gst_aac_parse_src_eventfunc(GstBaseParse * parse, GstEvent * event)
1947 gboolean handled = FALSE;
1948 GstAacParse *aacparse;
1949 aacparse = GST_AAC_PARSE(parse);
1951 GST_DEBUG("Entering gst_aac_parse_src_eventfunc header type = %d", aacparse->header_type);
1952 if(aacparse->header_type == DSPAAC_HEADER_ADTS)
1953 return gst_aac_parse_adts_src_eventfunc (parse, event);
1955 goto aac_seek_null_exit;
1958 /* call baseparse src_event function to handle event */
1959 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1964 * gst_aac_parse_adts_src_eventfunc:
1965 * @parse: #GstBaseParse. #event
1967 * before baseparse handles seek event, make full amr index table.
1969 * Returns: TRUE on success.
1972 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
1974 gboolean handled = FALSE;
1975 GstAacParse *aacparse;
1976 aacparse = GST_AAC_PARSE (parse);
1978 switch (GST_EVENT_TYPE (event)) {
1979 case GST_EVENT_SEEK:
1981 GstFlowReturn res = GST_FLOW_OK;
1982 gint64 base_offset = 0, sync_offset = 0, cur = 0;
1983 gint32 frame_count = 1; /* do not add first frame because it is already in index table */
1984 gint64 second_count = 0; /* initial 1 second */
1985 gint64 total_file_size = 0, start_offset = 0;
1986 GstClockTime current_ts = GST_CLOCK_TIME_NONE;
1987 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1988 gboolean large_file_flag = FALSE;
1990 /* check baseparse define these fuction */
1991 gst_base_parse_get_pad_mode(parse, &pad_mode);
1992 if (pad_mode != GST_PAD_MODE_PULL) {
1993 gboolean ret = FALSE;
1994 GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
1995 GstPad* srcpad = parse->srcpad;
1997 ret = gst_aac_audio_parse_do_push_seek(parse, srcpad, event);
1998 gst_object_unref(srcpad);
2001 gst_base_parse_get_upstream_size(parse, &total_file_size);
2002 gst_base_parse_get_index_last_offset(parse, &start_offset);
2003 gst_base_parse_get_index_last_ts(parse, ¤t_ts);
2005 if (total_file_size > AAC_LARGE_FILE_SIZE ) {
2006 large_file_flag = TRUE;
2007 gst_base_parse_set_seek_mode(parse, 0);
2008 GST_INFO_OBJECT (aacparse, "larger than big size (2MB).");
2009 goto aac_seek_null_exit;
2012 GST_DEBUG("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2014 if (total_file_size == 0 || start_offset >= total_file_size) {
2015 GST_ERROR("last index offset %d is larger than file size %d", start_offset, total_file_size);
2019 gst_event_parse_seek (event, NULL, NULL, NULL, NULL, &cur, NULL, NULL);
2020 if (cur <= current_ts) {
2021 GST_INFO("seek to %"GST_TIME_FORMAT" within index table %"GST_TIME_FORMAT". do not make index table",
2022 GST_TIME_ARGS(cur), GST_TIME_ARGS(current_ts));
2025 GST_INFO("seek to %"GST_TIME_FORMAT" without index table %"GST_TIME_FORMAT". make index table",
2026 GST_TIME_ARGS(cur), GST_TIME_ARGS(current_ts));
2029 GST_INFO("make AAC(ADTS) Index Table. file_size = %"G_GINT64_FORMAT" last idx offset=%"G_GINT64_FORMAT
2030 ", last idx ts=%"GST_TIME_FORMAT, total_file_size, start_offset, GST_TIME_ARGS(current_ts));
2032 base_offset = start_offset; /* set base by start offset */
2033 second_count = current_ts + GST_SECOND; /* 1sec */
2035 /************************************/
2036 /* STEP 0: Setting parse information */
2037 /************************************/
2038 aacparse->spf = aacparse->frame_samples;
2039 aacparse->frame_duration = (aacparse->spf * 1000 * 100) / aacparse->sample_rate; /* duration per frame (msec) */
2040 aacparse->frame_per_sec = (aacparse->sample_rate) / aacparse->spf; /* frames per second (ea) */
2042 /************************************/
2043 /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2044 /************************************/
2045 while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2047 GstBuffer *buffer = NULL;
2050 GST_INFO("gst_pad_pull_range %d bytes (from %"G_GINT64_FORMAT") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2051 res = gst_pad_pull_range (parse->sinkpad, base_offset, base_offset + AAC_MAX_PULL_RANGE_BUF, &buffer);
2052 if (res != GST_FLOW_OK) {
2053 GST_ERROR ("gst_pad_pull_range failed!");
2058 gst_buffer_map(buffer, &map, GST_MAP_READ);
2061 gst_buffer_unmap(buffer, &map);
2062 GST_WARNING("buffer is NULL in make aac seek table's STEP1");
2063 gst_buffer_unref (buffer);
2064 goto aac_seek_null_exit;
2067 while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2068 gint frame_size = 0;
2071 /* make sure the values in the frame header look sane */
2072 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2074 if ((frame_size > 0) && (frame_size < (AAC_MAX_PULL_RANGE_BUF - offset))) {
2075 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2076 gst_base_parse_add_index_entry (parse, base_offset +offset, current_ts, TRUE, TRUE); /* force */
2077 GST_DEBUG("Adding index ts=%"GST_TIME_FORMAT" offset %"G_GINT64_FORMAT,
2078 GST_TIME_ARGS(current_ts), base_offset + offset);
2079 second_count += GST_SECOND; /* 1sec */
2082 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2083 offset += frame_size;
2086 } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2087 GST_DEBUG("we need refill buffer");
2090 GST_WARNING("we lost sync");
2096 base_offset = base_offset + offset;
2098 gst_buffer_unmap(buffer, &map);
2099 gst_buffer_unref (buffer);
2100 } /* end MAX buffer cycle */
2102 /*******************************/
2103 /* STEP 2: Remain Buffer cycle */
2104 /*******************************/
2105 if (total_file_size - base_offset > 0) {
2107 GstBuffer *buffer = NULL;
2110 GST_INFO("gst_pad_pull_range %"G_GINT64_FORMAT" bytes (from %"G_GINT64_FORMAT") use remain_buf size",
2111 total_file_size - base_offset, base_offset);
2112 res = gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size, &buffer);
2113 if (res != GST_FLOW_OK) {
2114 GST_ERROR ("gst_pad_pull_range failed!");
2119 gst_buffer_map(buffer, &map, GST_MAP_READ);
2122 gst_buffer_unmap(buffer, &map);
2123 GST_WARNING("buffer is NULL in make aac seek table's STEP2");
2124 gst_buffer_unref (buffer);
2125 goto aac_seek_null_exit;
2128 while (base_offset + offset < total_file_size) {
2129 gint frame_size = 0;
2132 /* make sure the values in the frame header look sane */
2133 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2135 if ((frame_size > 0) && (frame_size <= (total_file_size - (base_offset + offset)))) {
2136 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2137 gst_base_parse_add_index_entry (parse, base_offset +offset, current_ts, TRUE, TRUE); /* force */
2138 GST_DEBUG("Adding index ts=%"GST_TIME_FORMAT" offset %"G_GINT64_FORMAT,
2139 GST_TIME_ARGS(current_ts), base_offset + offset);
2140 second_count += GST_SECOND; /* 1sec */
2143 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2144 offset += frame_size;
2147 } else if (frame_size == 0) {
2148 GST_DEBUG("Frame size is 0 so, Decoding end..");
2151 GST_WARNING("we lost sync");
2157 gst_buffer_unmap(buffer, &map);
2158 gst_buffer_unref (buffer);
2159 } /* end remain_buf buffer cycle */
2161 GST_DEBUG("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2171 /* call baseparse src_event function to handle event */
2172 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2175 #endif //end of #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION