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 */
71 #define RAW_MAX_SIZE 1 /* Correct framing is required */
73 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
74 headers prepended during raw to ADTS
77 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION /* to get more accurate duration */
78 #define AAC_MAX_ESTIMATE_DURATION_BUF (1024 * 1024) /* use first 1 Mbyte */
79 #define AAC_SAMPLE_PER_FRAME 1024
81 #define AAC_MAX_PULL_RANGE_BUF (1 * 1024 * 1024) /* 1 MByte */
82 #define AAC_LARGE_FILE_SIZE (2 * 1024 * 1024) /* 2 MByte */
83 #define gst_aac_parse_parent_class parent_class
86 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
88 static const gint loas_sample_rate_table[16] = {
89 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
90 16000, 12000, 11025, 8000, 7350, 0, 0, 0
93 static const gint loas_channels_table[16] = {
94 0, 1, 2, 3, 4, 5, 6, 8,
95 0, 0, 0, 7, 8, 0, 8, 0
98 static gboolean gst_aac_parse_start (GstBaseParse * parse);
99 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
101 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
103 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
106 static GstFlowReturn gst_aac_parse_handle_frame (GstBaseParse * parse,
107 GstBaseParseFrame * frame, gint * skipsize);
108 static GstFlowReturn gst_aac_parse_pre_push_frame (GstBaseParse * parse,
109 GstBaseParseFrame * frame);
110 static gboolean gst_aac_parse_src_event (GstBaseParse * parse,
113 static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
114 aacparse, GstBitReader * br, gint * object_type, gint * sample_rate,
115 gint * channels, gint * frame_samples);
117 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
118 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
119 /* make full aac(adts) index table when seek */
120 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
122 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
124 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
125 static void gst_aac_parse_check_byte_seekability (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 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
267 if (!gst_structure_get_value (s, "codec_data")) {
268 GstBuffer *codec_data_buffer;
269 GST_WARNING("Insert codec_data to src_caps");
270 /* The codec_data data is according to AudioSpecificConfig,
271 ISO/IEC 14496-3, 1.6.2.1 */
272 codec_data_buffer = gst_buffer_new_and_alloc (2);
273 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
274 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER, codec_data_buffer, NULL);
275 gst_buffer_unref (codec_data_buffer);
279 allowed = gst_pad_get_allowed_caps (GST_BASE_PARSE (aacparse)->srcpad);
280 if (allowed && !gst_caps_can_intersect (src_caps, allowed)) {
281 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
282 "Caps can not intersect");
283 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
284 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
285 "Input is ADTS, trying raw");
286 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "raw",
288 if (gst_caps_can_intersect (src_caps, allowed)) {
289 GstBuffer *codec_data_buffer;
291 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
292 "Caps can intersect, we will drop the ADTS layer");
293 aacparse->output_header_type = DSPAAC_HEADER_NONE;
295 /* The codec_data data is according to AudioSpecificConfig,
296 ISO/IEC 14496-3, 1.6.2.1 */
297 codec_data_buffer = gst_buffer_new_and_alloc (2);
298 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
299 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
300 codec_data_buffer, NULL);
301 gst_buffer_unref (codec_data_buffer);
303 } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
304 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
305 "Input is raw, trying ADTS");
306 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
308 if (gst_caps_can_intersect (src_caps, allowed)) {
309 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
310 "Caps can intersect, we will prepend ADTS headers");
311 aacparse->output_header_type = DSPAAC_HEADER_ADTS;
316 gst_caps_unref (allowed);
318 aacparse->last_parsed_channels = 0;
319 aacparse->last_parsed_sample_rate = 0;
321 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
323 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
324 gst_caps_unref (src_caps);
328 GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
329 aacparse->sample_rate);
330 gst_caps_unref (src_caps);
336 * gst_aac_parse_sink_setcaps:
340 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
342 * Returns: TRUE on success.
345 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
347 GstAacParse *aacparse;
348 GstStructure *structure;
352 aacparse = GST_AAC_PARSE (parse);
353 structure = gst_caps_get_structure (caps, 0);
354 caps_str = gst_caps_to_string (caps);
356 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
359 /* This is needed at least in case of RTP
360 * Parses the codec_data information to get ObjectType,
361 * number of channels and samplerate */
362 value = gst_structure_get_value (structure, "codec_data");
364 GstBuffer *buf = gst_value_get_buffer (value);
366 if (buf && gst_buffer_get_size (buf) >= 2) {
370 if (!gst_buffer_map (buf, &map, GST_MAP_READ))
372 gst_bit_reader_init (&br, map.data, map.size);
373 gst_aac_parse_read_audio_specific_config (aacparse, &br,
374 &aacparse->object_type, &aacparse->sample_rate, &aacparse->channels,
375 &aacparse->frame_samples);
377 aacparse->header_type = DSPAAC_HEADER_NONE;
378 aacparse->mpegversion = 4;
379 gst_buffer_unmap (buf, &map);
381 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
382 "samples=%d", aacparse->object_type, aacparse->sample_rate,
383 aacparse->channels, aacparse->frame_samples);
385 /* arrange for metadata and get out of the way */
386 gst_aac_parse_set_src_caps (aacparse, caps);
387 if (aacparse->header_type == aacparse->output_header_type)
388 gst_base_parse_set_passthrough (parse, TRUE);
390 /* input is already correctly framed */
391 gst_base_parse_set_min_frame_size (parse, RAW_MAX_SIZE);
396 /* caps info overrides */
397 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
398 gst_structure_get_int (structure, "channels", &aacparse->channels);
400 const gchar *stream_format =
401 gst_structure_get_string (structure, "stream-format");
403 if (g_strcmp0 (stream_format, "raw") == 0) {
404 GST_ERROR_OBJECT (parse, "Need codec_data for raw AAC");
407 aacparse->sample_rate = 0;
408 aacparse->channels = 0;
409 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
410 gst_base_parse_set_passthrough (parse, FALSE);
418 * gst_aac_parse_adts_get_frame_len:
419 * @data: block of data containing an ADTS header.
421 * This function calculates ADTS frame length from the given header.
423 * Returns: size of the ADTS frame.
426 gst_aac_parse_adts_get_frame_len (const guint8 * data)
428 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
433 * gst_aac_parse_check_adts_frame:
434 * @aacparse: #GstAacParse.
435 * @data: Data to be checked.
436 * @avail: Amount of data passed.
437 * @framesize: If valid ADTS frame was found, this will be set to tell the
438 * found frame size in bytes.
439 * @needed_data: If frame was not found, this may be set to tell how much
440 * more data is needed in the next round to detect the frame
441 * reliably. This may happen when a frame header candidate
442 * is found but it cannot be guaranteed to be the header without
443 * peeking the following data.
445 * Check if the given data contains contains ADTS frame. The algorithm
446 * will examine ADTS frame header and calculate the frame size. Also, another
447 * consecutive ADTS frame header need to be present after the found frame.
448 * Otherwise the data is not considered as a valid ADTS frame. However, this
449 * "extra check" is omitted when EOS has been received. In this case it is
450 * enough when data[0] contains a valid ADTS header.
452 * This function may set the #needed_data to indicate that a possible frame
453 * candidate has been found, but more data (#needed_data bytes) is needed to
454 * be absolutely sure. When this situation occurs, FALSE will be returned.
456 * When a valid frame is detected, this function will use
457 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
458 * to set the needed bytes for next frame.This way next data chunk is already
461 * Returns: TRUE if the given data contains a valid ADTS header.
464 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
465 const guint8 * data, const guint avail, gboolean drain,
466 guint * framesize, guint * needed_data)
472 /* Absolute minimum to perform the ADTS syncword,
473 layer and sampling frequency tests */
474 if (G_UNLIKELY (avail < 3)) {
479 /* Syncword and layer tests */
480 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
482 /* Sampling frequency test */
483 if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
486 /* This looks like an ADTS frame header but
487 we need at least 6 bytes to proceed */
488 if (G_UNLIKELY (avail < 6)) {
493 *framesize = gst_aac_parse_adts_get_frame_len (data);
495 /* If frame has CRC, it needs 2 bytes
496 for it at the end of the header */
497 crc_size = (data[1] & 0x01) ? 0 : 2;
500 if (*framesize < 7 + crc_size) {
501 *needed_data = 7 + crc_size;
505 /* In EOS mode this is enough. No need to examine the data further.
506 We also relax the check when we have sync, on the assumption that
507 if we're not looking at random data, we have a much higher chance
508 to get the correct sync, and this avoids losing two frames when
509 a single bit corruption happens. */
510 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
514 if (*framesize + ADTS_MAX_SIZE > avail) {
515 /* We have found a possible frame header candidate, but can't be
516 sure since we don't have enough data to check the next frame */
517 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
518 *framesize + ADTS_MAX_SIZE, avail);
519 *needed_data = *framesize + ADTS_MAX_SIZE;
520 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
521 *framesize + ADTS_MAX_SIZE);
525 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
526 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
528 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
529 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
530 nextlen + ADTS_MAX_SIZE);
538 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
541 guint8 bytes, i, byte;
544 if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
546 for (i = 0; i <= bytes; ++i) {
548 if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
556 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
557 guint8 * audio_object_type)
559 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
561 if (*audio_object_type == 31) {
562 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
564 *audio_object_type += 32;
566 GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
571 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
574 guint8 sampling_frequency_index;
575 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
577 GST_LOG_OBJECT (aacparse, "sampling_frequency_index: %u",
578 sampling_frequency_index);
579 if (sampling_frequency_index == 0xf) {
580 guint32 sampling_rate;
581 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
583 *sample_rate = sampling_rate;
585 *sample_rate = loas_sample_rate_table[sampling_frequency_index];
589 aacparse->last_parsed_sample_rate = *sample_rate;
593 /* See table 1.13 in ISO/IEC 14496-3 */
595 gst_aac_parse_read_audio_specific_config (GstAacParse * aacparse,
596 GstBitReader * br, gint * object_type, gint * sample_rate, gint * channels,
597 gint * frame_samples)
599 guint8 audio_object_type;
600 guint8 G_GNUC_UNUSED extension_audio_object_type;
601 guint8 channel_configuration, extension_channel_configuration;
602 gboolean G_GNUC_UNUSED sbr = FALSE, ps = FALSE;
604 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
607 *object_type = audio_object_type;
609 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
612 if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
614 *channels = loas_channels_table[channel_configuration];
615 GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
619 if (audio_object_type == 5 || audio_object_type == 29) {
620 extension_audio_object_type = 5;
622 if (audio_object_type == 29) {
624 /* Parametric stereo. If we have a one-channel configuration, we can
625 * override it to stereo */
630 GST_LOG_OBJECT (aacparse,
631 "Audio object type 5 or 29, so rereading sampling rate (was %d)...",
633 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
636 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
639 if (audio_object_type == 22) {
640 /* extension channel configuration */
641 if (!gst_bit_reader_get_bits_uint8 (br, &extension_channel_configuration,
644 GST_LOG_OBJECT (aacparse, "extension channel_configuration: %d",
645 extension_channel_configuration);
646 *channels = loas_channels_table[extension_channel_configuration];
651 extension_audio_object_type = 0;
654 GST_INFO_OBJECT (aacparse, "Parsed AudioSpecificConfig: %d Hz, %d channels",
655 *sample_rate, *channels);
657 if (frame_samples && audio_object_type == 23) {
659 /* Read the Decoder Configuration (GASpecificConfig) if present */
660 /* We only care about the first bit to know what the number of samples
662 if (!gst_bit_reader_get_bits_uint8 (br, &frame_flag, 1))
664 *frame_samples = frame_flag ? 960 : 1024;
667 /* There's LOTS of stuff next, but we ignore it for now as we have
668 what we want (sample rate and number of channels */
669 GST_DEBUG_OBJECT (aacparse,
670 "Need more code to parse humongous LOAS data, currently ignored");
671 aacparse->last_parsed_channels = *channels;
677 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
678 guint avail, gint * sample_rate, gint * channels, gint * version)
683 /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
687 gst_bit_reader_init (&br, data, avail);
689 /* skip sync word (11 bits) and size (13 bits) */
690 if (!gst_bit_reader_skip (&br, 11 + 13))
693 /* First bit is "use last config" */
694 if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
697 GST_LOG_OBJECT (aacparse, "Frame uses previous config");
698 if (!aacparse->last_parsed_sample_rate || !aacparse->last_parsed_channels) {
699 GST_DEBUG_OBJECT (aacparse,
700 "No previous config to use. We'll look for more data.");
703 *sample_rate = aacparse->last_parsed_sample_rate;
704 *channels = aacparse->last_parsed_channels;
708 GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
710 /* audioMuxVersion */
711 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
714 /* audioMuxVersionA */
715 if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
720 GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
722 guint8 same_time, subframes, num_program, prog;
725 /* taraBufferFullness */
726 if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
729 if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
731 if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
733 if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
735 GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
736 same_time, subframes, num_program);
738 for (prog = 0; prog <= num_program; ++prog) {
739 guint8 num_layer, layer;
740 if (!gst_bit_reader_get_bits_uint8 (&br, &num_layer, 3))
742 GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
744 for (layer = 0; layer <= num_layer; ++layer) {
745 guint8 use_same_config;
746 if (prog == 0 && layer == 0) {
749 if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
752 if (!use_same_config) {
754 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
755 sample_rate, channels, NULL))
759 if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
761 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
762 sample_rate, channels, NULL))
764 if (!gst_bit_reader_skip (&br, asc_len))
770 GST_LOG_OBJECT (aacparse, "More data ignored");
772 GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
779 * gst_aac_parse_loas_get_frame_len:
780 * @data: block of data containing a LOAS header.
782 * This function calculates LOAS frame length from the given header.
784 * Returns: size of the LOAS frame.
787 gst_aac_parse_loas_get_frame_len (const guint8 * data)
789 return (((data[1] & 0x1f) << 8) | data[2]) + 3;
794 * gst_aac_parse_check_loas_frame:
795 * @aacparse: #GstAacParse.
796 * @data: Data to be checked.
797 * @avail: Amount of data passed.
798 * @framesize: If valid LOAS frame was found, this will be set to tell the
799 * found frame size in bytes.
800 * @needed_data: If frame was not found, this may be set to tell how much
801 * more data is needed in the next round to detect the frame
802 * reliably. This may happen when a frame header candidate
803 * is found but it cannot be guaranteed to be the header without
804 * peeking the following data.
806 * Check if the given data contains contains LOAS frame. The algorithm
807 * will examine LOAS frame header and calculate the frame size. Also, another
808 * consecutive LOAS frame header need to be present after the found frame.
809 * Otherwise the data is not considered as a valid LOAS frame. However, this
810 * "extra check" is omitted when EOS has been received. In this case it is
811 * enough when data[0] contains a valid LOAS header.
813 * This function may set the #needed_data to indicate that a possible frame
814 * candidate has been found, but more data (#needed_data bytes) is needed to
815 * be absolutely sure. When this situation occurs, FALSE will be returned.
817 * When a valid frame is detected, this function will use
818 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
819 * to set the needed bytes for next frame.This way next data chunk is already
822 * LOAS can have three different formats, if I read the spec correctly. Only
823 * one of them is supported here, as the two samples I have use this one.
825 * Returns: TRUE if the given data contains a valid LOAS header.
828 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
829 const guint8 * data, const guint avail, gboolean drain,
830 guint * framesize, guint * needed_data)
835 if (G_UNLIKELY (avail < 3)) {
840 if ((data[0] == 0x56) && ((data[1] & 0xe0) == 0xe0)) {
841 *framesize = gst_aac_parse_loas_get_frame_len (data);
842 GST_DEBUG_OBJECT (aacparse, "Found possible %u byte LOAS frame",
845 /* In EOS mode this is enough. No need to examine the data further.
846 We also relax the check when we have sync, on the assumption that
847 if we're not looking at random data, we have a much higher chance
848 to get the correct sync, and this avoids losing two frames when
849 a single bit corruption happens. */
850 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
854 if (*framesize + LOAS_MAX_SIZE > avail) {
855 /* We have found a possible frame header candidate, but can't be
856 sure since we don't have enough data to check the next frame */
857 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
858 *framesize + LOAS_MAX_SIZE, avail);
859 *needed_data = *framesize + LOAS_MAX_SIZE;
860 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
861 *framesize + LOAS_MAX_SIZE);
865 if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
866 guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
868 GST_LOG ("LOAS frame found, len: %d bytes", *framesize);
869 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
870 nextlen + LOAS_MAX_SIZE);
873 GST_DEBUG_OBJECT (aacparse, "That was a false positive");
879 /* caller ensure sufficient data */
881 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
882 gint * rate, gint * channels, gint * object, gint * version)
886 gint sr_idx = (data[2] & 0x3c) >> 2;
888 *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
891 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
897 *version = (data[1] & 0x08) ? 2 : 4;
899 *object = ((data[2] & 0xc0) >> 6) + 1;
903 * gst_aac_parse_detect_stream:
904 * @aacparse: #GstAacParse.
905 * @data: A block of data that needs to be examined for stream characteristics.
906 * @avail: Size of the given datablock.
907 * @framesize: If valid stream was found, this will be set to tell the
908 * first frame size in bytes.
909 * @skipsize: If valid stream was found, this will be set to tell the first
910 * audio frame position within the given data.
912 * Examines the given piece of data and try to detect the format of it. It
913 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
914 * header. If the stream is detected, TRUE will be returned and #framesize
915 * is set to indicate the found frame size. Additionally, #skipsize might
916 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
917 * position of the frame inside given data chunk.
919 * Returns: TRUE on success.
922 gst_aac_parse_detect_stream (GstAacParse * aacparse,
923 const guint8 * data, const guint avail, gboolean drain,
924 guint * framesize, gint * skipsize)
926 gboolean found = FALSE;
927 guint need_data_adts = 0, need_data_loas;
930 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
932 /* FIXME: No need to check for ADIF if we are not in the beginning of the
935 /* Can we even parse the header? */
936 if (avail < MAX (ADTS_MAX_SIZE, LOAS_MAX_SIZE)) {
937 GST_DEBUG_OBJECT (aacparse, "Not enough data to check");
941 for (i = 0; i < avail - 4; i++) {
942 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
943 ((data[i] == 0x56) && ((data[i + 1] & 0xe0) == 0xe0)) ||
944 strncmp ((char *) data + i, "ADIF", 4) == 0) {
945 GST_DEBUG_OBJECT (aacparse, "Found signature at offset %u", i);
949 /* Trick: tell the parent class that we didn't find the frame yet,
950 but make it skip 'i' amount of bytes. Next time we arrive
951 here we have full frame in the beginning of the data. */
964 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
965 framesize, &need_data_adts)) {
968 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
970 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
971 &aacparse->object_type, &aacparse->mpegversion);
973 if (!channels || !framesize) {
974 GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
978 aacparse->header_type = DSPAAC_HEADER_ADTS;
979 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
980 aacparse->frame_samples, 2, 2);
982 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
983 rate, channels, aacparse->object_type, aacparse->mpegversion);
985 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
990 if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
991 framesize, &need_data_loas)) {
992 gint rate = 0, channels = 0;
994 GST_INFO ("LOAS, framesize: %d", *framesize);
996 aacparse->header_type = DSPAAC_HEADER_LOAS;
998 if (!gst_aac_parse_read_loas_config (aacparse, data, avail, &rate,
999 &channels, &aacparse->mpegversion)) {
1000 /* This is pretty normal when skipping data at the start of
1001 * random stream (MPEG-TS capture for example) */
1002 GST_LOG_OBJECT (aacparse, "Error reading LOAS config");
1006 if (rate && channels) {
1007 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
1008 aacparse->frame_samples, 2, 2);
1010 /* Don't store the sample rate and channels yet -
1011 * this is just format detection. */
1012 GST_DEBUG ("LOAS: samplerate %d, channels %d, objtype %d, version %d",
1013 rate, channels, aacparse->object_type, aacparse->mpegversion);
1016 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
1021 if (need_data_adts || need_data_loas) {
1022 /* This tells the parent class not to skip any data */
1027 if (avail < ADIF_MAX_SIZE)
1030 if (memcmp (data + i, "ADIF", 4) == 0) {
1037 aacparse->header_type = DSPAAC_HEADER_ADIF;
1038 aacparse->mpegversion = 4;
1040 /* Skip the "ADIF" bytes */
1041 adif = data + i + 4;
1043 /* copyright string */
1045 skip_size += 9; /* skip 9 bytes */
1047 bitstream_type = adif[0 + skip_size] & 0x10;
1049 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
1050 ((unsigned int) adif[1 + skip_size] << 11) |
1051 ((unsigned int) adif[2 + skip_size] << 3) |
1052 ((unsigned int) adif[3 + skip_size] & 0xe0);
1055 if (bitstream_type == 0) {
1057 /* Buffer fullness parsing. Currently not needed... */
1058 guint num_elems = 0;
1061 num_elems = (adif[3 + skip_size] & 0x1e);
1062 GST_INFO ("ADIF num_config_elems: %d", num_elems);
1064 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
1065 ((unsigned int) adif[4 + skip_size] << 11) |
1066 ((unsigned int) adif[5 + skip_size] << 3) |
1067 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
1069 GST_INFO ("ADIF buffer fullness: %d", fullness);
1071 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
1072 ((adif[7 + skip_size] & 0x80) >> 7);
1073 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
1077 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
1078 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
1079 ((adif[5 + skip_size] & 0x80) >> 7);
1082 /* FIXME: This gives totally wrong results. Duration calculation cannot
1084 aacparse->sample_rate =
1085 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1087 /* baseparse is not given any fps,
1088 * so it will give up on timestamps, seeking, etc */
1090 /* FIXME: Can we assume this? */
1091 aacparse->channels = 2;
1093 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1094 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1096 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1098 /* arrange for metadata and get out of the way */
1099 sinkcaps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (aacparse));
1100 gst_aac_parse_set_src_caps (aacparse, sinkcaps);
1102 gst_caps_unref (sinkcaps);
1104 /* not syncable, not easily seekable (unless we push data from start */
1105 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
1106 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
1107 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
1113 /* This should never happen */
1118 * gst_aac_parse_get_audio_profile_object_type
1119 * @aacparse: #GstAacParse.
1121 * Gets the MPEG-2 profile or the MPEG-4 object type value corresponding to the
1122 * mpegversion and profile of @aacparse's src pad caps, according to the
1123 * values defined by table 1.A.11 in ISO/IEC 14496-3.
1125 * Returns: the profile or object type value corresponding to @aacparse's src
1126 * pad caps, if such a value exists; otherwise G_MAXUINT8.
1129 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1132 GstStructure *srcstruct;
1133 const gchar *profile;
1136 srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1137 if (G_UNLIKELY (srccaps == NULL)) {
1141 srcstruct = gst_caps_get_structure (srccaps, 0);
1142 profile = gst_structure_get_string (srcstruct, "profile");
1143 if (G_UNLIKELY (profile == NULL)) {
1144 gst_caps_unref (srccaps);
1148 if (g_strcmp0 (profile, "main") == 0) {
1150 } else if (g_strcmp0 (profile, "lc") == 0) {
1152 } else if (g_strcmp0 (profile, "ssr") == 0) {
1154 } else if (g_strcmp0 (profile, "ltp") == 0) {
1155 if (G_LIKELY (aacparse->mpegversion == 4))
1158 ret = G_MAXUINT8; /* LTP Object Type allowed only for MPEG-4 */
1163 gst_caps_unref (srccaps);
1168 * gst_aac_parse_get_audio_channel_configuration
1169 * @num_channels: number of audio channels.
1171 * Gets the Channel Configuration value, as defined by table 1.19 in ISO/IEC
1172 * 14496-3, for a given number of audio channels.
1174 * Returns: the Channel Configuration value corresponding to @num_channels, if
1175 * such a value exists; otherwise G_MAXUINT8.
1178 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1180 if (num_channels >= 1 && num_channels <= 6) /* Mono up to & including 5.1 */
1181 return (guint8) num_channels;
1182 else if (num_channels == 8) /* 7.1 */
1187 /* FIXME: Add support for configurations 11, 12 and 14 from
1188 * ISO/IEC 14496-3:2009/PDAM 4 based on the actual channel layout
1193 * gst_aac_parse_get_audio_sampling_frequency_index:
1194 * @sample_rate: audio sampling rate.
1196 * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1197 * 14496-3, for a given sampling rate.
1199 * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1200 * if such a value exists; otherwise G_MAXUINT8.
1203 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1205 switch (sample_rate) {
1238 * gst_aac_parse_prepend_adts_headers:
1239 * @aacparse: #GstAacParse.
1240 * @frame: raw AAC frame to which ADTS headers shall be prepended.
1242 * Prepends ADTS headers to a raw AAC audio frame.
1244 * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1247 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1248 GstBaseParseFrame * frame)
1251 guint8 *adts_headers;
1254 guint8 id, profile, channel_configuration, sampling_frequency_index;
1256 id = (aacparse->mpegversion == 4) ? 0x0U : 0x1U;
1257 profile = gst_aac_parse_get_audio_profile_object_type (aacparse);
1258 if (profile == G_MAXUINT8) {
1259 GST_ERROR_OBJECT (aacparse, "Unsupported audio profile or object type");
1262 channel_configuration =
1263 gst_aac_parse_get_audio_channel_configuration (aacparse->channels);
1264 if (channel_configuration == G_MAXUINT8) {
1265 GST_ERROR_OBJECT (aacparse, "Unsupported number of channels");
1268 sampling_frequency_index =
1269 gst_aac_parse_get_audio_sampling_frequency_index (aacparse->sample_rate);
1270 if (sampling_frequency_index == G_MAXUINT8) {
1271 GST_ERROR_OBJECT (aacparse, "Unsupported sampling frequency");
1275 frame->out_buffer = gst_buffer_copy (frame->buffer);
1276 buf_size = gst_buffer_get_size (frame->out_buffer);
1277 frame_size = buf_size + ADTS_HEADERS_LENGTH;
1279 if (G_UNLIKELY (frame_size >= 0x4000)) {
1280 GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1284 adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1286 /* Note: no error correction bits are added to the resulting ADTS frames */
1287 adts_headers[0] = 0xFFU;
1288 adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
1289 adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
1290 ((channel_configuration & 0x4U) >> 2);
1291 adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
1292 (guint8) (frame_size >> 11);
1293 adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
1294 adts_headers[5] = (guint8) (((frame_size & 0x0007) << 5) + 0x1FU);
1295 adts_headers[6] = 0xFCU;
1297 mem = gst_memory_new_wrapped (0, adts_headers, ADTS_HEADERS_LENGTH, 0,
1298 ADTS_HEADERS_LENGTH, adts_headers, g_free);
1299 gst_buffer_prepend_memory (frame->out_buffer, mem);
1305 * gst_aac_parse_check_valid_frame:
1306 * @parse: #GstBaseParse.
1307 * @frame: #GstBaseParseFrame.
1308 * @skipsize: How much data parent class should skip in order to find the
1311 * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1313 * Also determines frame overhead.
1314 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
1315 * a per-frame header. LOAS has 3 bytes.
1317 * We're making a couple of simplifying assumptions:
1319 * 1. We count Program Configuration Elements rather than searching for them
1320 * in the streams to discount them - the overhead is negligible.
1322 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
1323 * bits, which should still not be significant enough to warrant the
1324 * additional parsing through the headers
1326 * Returns: a #GstFlowReturn.
1328 static GstFlowReturn
1329 gst_aac_parse_handle_frame (GstBaseParse * parse,
1330 GstBaseParseFrame * frame, gint * skipsize)
1333 GstAacParse *aacparse;
1334 gboolean ret = FALSE;
1338 gint rate = 0, channels = 0;
1340 aacparse = GST_AAC_PARSE (parse);
1341 buffer = frame->buffer;
1343 gst_buffer_map (buffer, &map, GST_MAP_READ);
1346 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1348 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
1349 aacparse->header_type == DSPAAC_HEADER_NONE) {
1350 /* There is nothing to parse */
1351 framesize = map.size;
1354 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1356 ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1357 GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1359 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1360 guint needed_data = 1024;
1362 ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1363 GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1365 if (!ret && needed_data) {
1366 GST_DEBUG ("buffer didn't contain valid frame");
1368 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1372 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1373 guint needed_data = 1024;
1375 ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1376 map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1378 if (!ret && needed_data) {
1379 GST_DEBUG ("buffer didn't contain valid frame");
1381 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1386 GST_DEBUG ("buffer didn't contain valid frame");
1387 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1391 if (G_UNLIKELY (!ret))
1394 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1396 frame->overhead = 7;
1398 gst_aac_parse_parse_adts_header (aacparse, map.data,
1399 &rate, &channels, NULL, NULL);
1401 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1403 if (G_UNLIKELY (rate != aacparse->sample_rate
1404 || channels != aacparse->channels)) {
1405 aacparse->sample_rate = rate;
1406 aacparse->channels = channels;
1408 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1409 /* If linking fails, we need to return appropriate error */
1410 ret = GST_FLOW_NOT_LINKED;
1413 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1414 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1416 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1417 if (aacparse->first_frame == TRUE) {
1418 gboolean ret = FALSE;
1419 aacparse->first_frame = FALSE;
1421 ret = gst_aac_parse_estimate_duration (parse);
1423 GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1424 ret = GST_FLOW_NOT_SUPPORTED;
1426 gst_aac_parse_check_byte_seekability (parse);
1429 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1430 gboolean setcaps = FALSE;
1433 frame->overhead = 3;
1435 if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
1436 &channels, NULL) || !rate || !channels) {
1437 /* This is pretty normal when skipping data at the start of
1438 * random stream (MPEG-TS capture for example) */
1439 GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
1440 /* Since we don't fully parse the LOAS config, we don't know for sure
1441 * how much to skip. Just skip 1 to end up to the next marker and
1442 * resume parsing from there */
1447 if (G_UNLIKELY (rate != aacparse->sample_rate
1448 || channels != aacparse->channels)) {
1449 aacparse->sample_rate = rate;
1450 aacparse->channels = channels;
1452 GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1456 /* We want to set caps both at start, and when rate/channels change.
1457 Since only some LOAS frames have that info, we may receive frames
1458 before knowing about rate/channels. */
1460 || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
1461 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1462 /* If linking fails, we need to return appropriate error */
1463 ret = GST_FLOW_NOT_LINKED;
1466 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1467 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1470 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1471 else if (aacparse->header_type == DSPAAC_HEADER_ADIF) {
1472 /* to get more correct duration */
1473 float estimated_duration = 0;
1474 gint64 total_file_size;
1475 gst_base_parse_get_upstream_size (parse, &total_file_size);
1476 estimated_duration =
1477 ((total_file_size * 8) / (float) (aacparse->bitrate * 1000)) *
1479 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1480 estimated_duration * 1000, 0);
1484 if (aacparse->header_type == DSPAAC_HEADER_NONE
1485 && aacparse->output_header_type == DSPAAC_HEADER_ADTS) {
1486 if (!gst_aac_parse_prepend_adts_headers (aacparse, frame)) {
1487 GST_ERROR_OBJECT (aacparse, "Failed to prepend ADTS headers to frame");
1488 ret = GST_FLOW_ERROR;
1493 gst_buffer_unmap (buffer, &map);
1496 /* found, skip if needed */
1505 if (ret && framesize <= map.size) {
1506 return gst_base_parse_finish_frame (parse, frame, framesize);
1512 static GstFlowReturn
1513 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1515 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1517 if (!aacparse->sent_codec_tag) {
1518 GstTagList *taglist;
1522 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1524 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1525 GST_INFO_OBJECT (parse, "Src pad is flushing");
1526 return GST_FLOW_FLUSHING;
1528 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1529 return GST_FLOW_NOT_NEGOTIATED;
1533 taglist = gst_tag_list_new_empty ();
1534 gst_pb_utils_add_codec_description_to_tag_list (taglist,
1535 GST_TAG_AUDIO_CODEC, caps);
1536 gst_caps_unref (caps);
1538 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1539 gst_tag_list_unref (taglist);
1541 /* also signals the end of first-frame processing */
1542 aacparse->sent_codec_tag = TRUE;
1545 /* As a special case, we can remove the ADTS framing and output raw AAC. */
1546 if (aacparse->header_type == DSPAAC_HEADER_ADTS
1547 && aacparse->output_header_type == DSPAAC_HEADER_NONE) {
1550 frame->out_buffer = gst_buffer_make_writable (frame->buffer);
1551 frame->buffer = NULL;
1552 gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ);
1553 header_size = (map.data[1] & 1) ? 7 : 9; /* optional CRC */
1554 gst_buffer_unmap (frame->out_buffer, &map);
1555 gst_buffer_resize (frame->out_buffer, header_size,
1556 gst_buffer_get_size (frame->out_buffer) - header_size);
1564 * gst_aac_parse_start:
1565 * @parse: #GstBaseParse.
1567 * Implementation of "start" vmethod in #GstBaseParse class.
1569 * Returns: TRUE if startup succeeded.
1572 gst_aac_parse_start (GstBaseParse * parse)
1574 GstAacParse *aacparse;
1576 aacparse = GST_AAC_PARSE (parse);
1577 GST_DEBUG ("start");
1578 aacparse->frame_samples = 1024;
1579 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
1580 aacparse->sent_codec_tag = FALSE;
1581 aacparse->last_parsed_channels = 0;
1582 aacparse->last_parsed_sample_rate = 0;
1583 aacparse->object_type = 0;
1584 aacparse->bitrate = 0;
1585 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
1586 aacparse->output_header_type = DSPAAC_HEADER_NOT_PARSED;
1587 aacparse->channels = 0;
1588 aacparse->sample_rate = 0;
1594 * gst_aac_parse_stop:
1595 * @parse: #GstBaseParse.
1597 * Implementation of "stop" vmethod in #GstBaseParse class.
1599 * Returns: TRUE is stopping succeeded.
1602 gst_aac_parse_stop (GstBaseParse * parse)
1609 remove_fields (GstCaps * caps)
1613 n = gst_caps_get_size (caps);
1614 for (i = 0; i < n; i++) {
1615 GstStructure *s = gst_caps_get_structure (caps, i);
1617 gst_structure_remove_field (s, "framed");
1622 add_conversion_fields (GstCaps * caps)
1626 n = gst_caps_get_size (caps);
1627 for (i = 0; i < n; i++) {
1628 GstStructure *s = gst_caps_get_structure (caps, i);
1630 if (gst_structure_has_field (s, "stream-format")) {
1631 const GValue *v = gst_structure_get_value (s, "stream-format");
1633 if (G_VALUE_HOLDS_STRING (v)) {
1634 const gchar *str = g_value_get_string (v);
1636 if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1637 GValue va = G_VALUE_INIT;
1638 GValue vs = G_VALUE_INIT;
1640 g_value_init (&va, GST_TYPE_LIST);
1641 g_value_init (&vs, G_TYPE_STRING);
1642 g_value_set_string (&vs, "adts");
1643 gst_value_list_append_value (&va, &vs);
1644 g_value_set_string (&vs, "raw");
1645 gst_value_list_append_value (&va, &vs);
1646 gst_structure_set_value (s, "stream-format", &va);
1647 g_value_unset (&va);
1648 g_value_unset (&vs);
1650 } else if (GST_VALUE_HOLDS_LIST (v)) {
1651 gboolean contains_raw = FALSE;
1652 gboolean contains_adts = FALSE;
1653 guint m = gst_value_list_get_size (v), j;
1655 for (j = 0; j < m; j++) {
1656 const GValue *ve = gst_value_list_get_value (v, j);
1659 if (G_VALUE_HOLDS_STRING (ve) && (str = g_value_get_string (ve))) {
1660 if (strcmp (str, "adts") == 0)
1661 contains_adts = TRUE;
1662 else if (strcmp (str, "raw") == 0)
1663 contains_raw = TRUE;
1667 if (contains_adts || contains_raw) {
1668 GValue va = G_VALUE_INIT;
1669 GValue vs = G_VALUE_INIT;
1671 g_value_init (&va, GST_TYPE_LIST);
1672 g_value_init (&vs, G_TYPE_STRING);
1673 g_value_copy (v, &va);
1675 if (!contains_raw) {
1676 g_value_set_string (&vs, "raw");
1677 gst_value_list_append_value (&va, &vs);
1679 if (!contains_adts) {
1680 g_value_set_string (&vs, "adts");
1681 gst_value_list_append_value (&va, &vs);
1684 gst_structure_set_value (s, "stream-format", &va);
1686 g_value_unset (&vs);
1687 g_value_unset (&va);
1695 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1697 GstCaps *peercaps, *templ;
1700 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1703 GstCaps *fcopy = gst_caps_copy (filter);
1704 /* Remove the fields we convert */
1705 remove_fields (fcopy);
1706 add_conversion_fields (fcopy);
1707 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1708 gst_caps_unref (fcopy);
1710 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1713 peercaps = gst_caps_make_writable (peercaps);
1714 /* Remove the fields we convert */
1715 remove_fields (peercaps);
1716 add_conversion_fields (peercaps);
1718 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1719 gst_caps_unref (peercaps);
1720 gst_caps_unref (templ);
1726 GstCaps *intersection;
1729 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1730 gst_caps_unref (res);
1738 gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1740 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1742 if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1743 aacparse->last_parsed_channels = 0;
1744 aacparse->last_parsed_sample_rate = 0;
1746 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1747 GST_DEBUG ("Entering gst_aac_parse_src_event header type = %d",
1748 aacparse->header_type);
1749 if (aacparse->header_type == DSPAAC_HEADER_ADTS)
1750 return gst_aac_parse_adts_src_eventfunc (parse, event);
1752 return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1756 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1758 * get_aac_parse_get_adts_framelength:
1759 * @data: #GstBufferData.
1760 * @offset: #GstBufferData offset
1762 * Implementation to get adts framelength by using first some frame.
1764 * Returns: frame size
1767 get_aac_parse_get_adts_frame_length (const unsigned char *data, gint64 offset)
1769 const gint adts_header_length_no_crc = 7;
1770 const gint adts_header_length_with_crc = 9;
1771 gint frame_size = 0;
1772 gint protection_absent;
1775 /* check of syncword */
1776 if ((data[offset + 0] != 0xff) || ((data[offset + 1] & 0xf6) != 0xf0)) {
1777 GST_ERROR ("check sync word is fail\n");
1781 /* check of protection absent */
1782 protection_absent = (data[offset + 1] & 0x01);
1784 /*check of frame length */
1786 (data[offset + 3] & 0x3) << 11 | data[offset + 4] << 3 | data[offset +
1789 /* check of header size */
1790 /* protectionAbsent is 0 if there is CRC */
1792 protection_absent ? adts_header_length_no_crc :
1793 adts_header_length_with_crc;
1794 if (head_size > frame_size) {
1795 GST_ERROR ("return frame length as 0 (frameSize %u < headSize %u)",
1796 frame_size, head_size);
1804 * gst_aac_parse_estimate_duration:
1805 * @parse: #GstBaseParse.
1807 * Implementation to get estimated total duration by using first some frame.
1809 * Returns: TRUE if we can get estimated total duraion
1812 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1814 gboolean ret = FALSE;
1815 GstFlowReturn res = GST_FLOW_OK;
1816 gint64 pull_size = 0, file_size = 0, offset = 0, num_frames = 0, duration = 0;
1817 guint sample_rate_index = 0, sample_rate = 0, channel = 0;
1818 guint frame_size = 0, frame_duration_us = 0, estimated_bitrate = 0;
1819 guint lost_sync_count = 0;
1820 GstClockTime estimated_duration = GST_CLOCK_TIME_NONE;
1821 GstBuffer *buffer = NULL;
1824 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1825 GstAacParse *aacparse;
1826 gint64 buffer_size = 0;
1829 aacparse = GST_AAC_PARSE (parse);
1830 GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1832 /* check baseparse define these fuction */
1833 gst_base_parse_get_pad_mode (parse, &pad_mode);
1834 if (pad_mode != GST_PAD_MODE_PULL) {
1835 GST_INFO_OBJECT (aacparse,
1836 "aac parser is not pull mode. can not estimate duration");
1840 gst_base_parse_get_upstream_size (parse, &file_size);
1842 if (file_size < ADIF_MAX_SIZE) {
1843 GST_ERROR_OBJECT (aacparse, "file size is too short");
1847 pull_size = MIN (file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1849 res = gst_pad_pull_range (parse->sinkpad, 0, pull_size, &buffer);
1850 if (res != GST_FLOW_OK) {
1851 GST_ERROR_OBJECT (aacparse, "gst_pad_pull_range failed!");
1855 gst_buffer_map (buffer, &map, GST_MAP_READ);
1857 buffer_size = map.size;
1858 if (buffer_size != pull_size) {
1859 GST_ERROR_OBJECT (aacparse,
1860 "We got different buffer_size(%" G_GINT64_FORMAT ") with pull_size(%"
1861 G_GINT64_FORMAT ").", buffer_size, pull_size);
1864 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1865 for (i = 0; i < buffer_size; i++) {
1866 if ((buf[i] == 0xff) && ((buf[i + 1] & 0xf6) == 0xf0)) { /* aac sync word */
1867 //guint profile = (buf[i+2] >> 6) & 0x3;
1868 sample_rate_index = (buf[i + 2] >> 2) & 0xf;
1870 gst_aac_parse_get_sample_rate_from_index (sample_rate_index);
1871 if (sample_rate == 0) {
1872 GST_WARNING_OBJECT (aacparse, "Invalid sample rate index (0)");
1875 channel = (buf[i + 2] & 0x1) << 2 | (buf[i + 3] >> 6);
1877 GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate,
1880 /* count number of frames */
1881 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1882 //while (offset < pull_size) {
1883 while (offset < buffer_size) {
1884 frame_size = get_aac_parse_get_adts_frame_length (buf, i + offset);
1885 if (frame_size == 0) {
1886 GST_ERROR_OBJECT (aacparse,
1887 "framesize error at offset %" G_GINT64_FORMAT, offset);
1889 } else if (frame_size == -1) {
1891 lost_sync_count++; // lost sync count limmitation 2K Bytes
1892 if (lost_sync_count > (1024 * 2)) {
1893 GST_WARNING_OBJECT (aacparse,
1894 "lost_sync_count is larger than 2048");
1898 offset += frame_size;
1900 lost_sync_count = 0;
1904 /* if we can got full file, we can calculate the accurate duration */
1905 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1906 //if (pull_size == file_size) {
1907 if (buffer_size == file_size) {
1908 gfloat duration_for_one_frame = 0;
1909 GstClockTime calculated_duration = GST_CLOCK_TIME_NONE;
1911 GST_INFO_OBJECT (aacparse,
1912 "we got total file (%" G_GINT64_FORMAT
1913 " bytes). do not estimate but make Accurate total duration.",
1916 duration_for_one_frame =
1917 (gfloat) AAC_SAMPLE_PER_FRAME / (gfloat) sample_rate;
1918 calculated_duration =
1919 num_frames * duration_for_one_frame * 1000 * 1000 * 1000;
1921 GST_INFO_OBJECT (aacparse, "duration_for_one_frame %f ms",
1922 duration_for_one_frame);
1923 GST_INFO_OBJECT (aacparse, "calculated duration = %" GST_TIME_FORMAT,
1924 GST_TIME_ARGS (calculated_duration));
1925 /* 0 means disable estimate */
1926 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1927 calculated_duration, 0);
1930 GST_INFO_OBJECT (aacparse,
1931 "we got %" G_GUINT64_FORMAT " bytes in total file (%"
1932 G_GINT64_FORMAT "). can not make accurate duration but Estimate.",
1933 pull_size, file_size);
1935 (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1936 duration = num_frames * frame_duration_us;
1938 if (duration == 0) {
1939 GST_WARNING_OBJECT (aacparse, "Invalid duration");
1943 (gint) ((gfloat) (offset * 8) / (gfloat) (duration / 1000));
1945 if (estimated_bitrate == 0) {
1946 GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1949 estimated_duration =
1950 (GstClockTime) ((file_size * 8) / (estimated_bitrate * 1000)) *
1953 GST_INFO_OBJECT (aacparse, "number of frame = %" G_GINT64_FORMAT,
1955 GST_INFO_OBJECT (aacparse, "duration = %" G_GINT64_FORMAT,
1956 duration / 1000000);
1957 GST_INFO_OBJECT (aacparse, "byte = %" G_GINT64_FORMAT, offset);
1958 GST_INFO_OBJECT (aacparse, "estimated bitrate = %d bps",
1960 GST_INFO_OBJECT (aacparse, "estimated duration = %" GST_TIME_FORMAT,
1961 GST_TIME_ARGS (estimated_duration));
1963 gst_base_parse_set_average_bitrate (parse, estimated_bitrate * 1000);
1964 /* set update_interval as duration(sec)/2 */
1965 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration,
1966 (gint) (duration / 2));
1975 gst_buffer_unmap (buffer, &map);
1976 gst_buffer_unref (buffer);
1981 /* perform seek in push based mode:
1982 find BYTE position to move to based on time and delegate to upstream
1985 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1986 GstPad * pad, GstEvent * event)
1988 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1992 GstSeekType cur_type, stop_type;
1996 gint64 esimate_byte;
1998 gint64 upstream_total_bytes = 0;
1999 GstFormat fmt = GST_FORMAT_BYTES;
2001 GST_INFO_OBJECT (parse, "doing aac push-based seek");
2003 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2006 /* FIXME, always play to the end */
2009 /* only forward streaming and seeking is possible */
2011 goto unsupported_seek;
2014 /* handle rewind only */
2015 cur_type = GST_SEEK_TYPE_SET;
2017 stop_type = GST_SEEK_TYPE_NONE;
2019 flags |= GST_SEEK_FLAG_FLUSH;
2021 /* handle normal seek */
2022 cur_type = GST_SEEK_TYPE_SET;
2023 stop_type = GST_SEEK_TYPE_NONE;
2025 flags |= GST_SEEK_FLAG_FLUSH;
2027 esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
2028 if (aacparse->sample_rate > 0)
2029 frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
2031 goto unsupported_seek;
2033 byte_cur = esimate_byte / (frame_dur);
2035 goto unsupported_seek;
2037 GST_INFO_OBJECT (parse, "frame_byte(%d) spf(%d) rate (%d) ",
2038 aacparse->frame_byte, aacparse->spf, aacparse->sample_rate);
2039 GST_INFO_OBJECT (parse,
2040 "seek cur (%" G_GINT64_FORMAT ") = (%" GST_TIME_FORMAT ") ", cur,
2041 GST_TIME_ARGS (cur));
2042 GST_INFO_OBJECT (parse,
2043 "esimate_byte(%" G_GINT64_FORMAT ") esimate_byte (%d)", esimate_byte,
2047 /* obtain real upstream total bytes */
2048 if (!gst_pad_peer_query_duration (parse->sinkpad, fmt, &upstream_total_bytes))
2049 upstream_total_bytes = 0;
2050 GST_INFO_OBJECT (aacparse,
2051 "gst_pad_query_peer_duration -upstream_total_bytes (%" G_GUINT64_FORMAT
2052 ")", upstream_total_bytes);
2053 aacparse->file_size = upstream_total_bytes;
2055 if ((byte_cur == -1) || (byte_cur > aacparse->file_size)) {
2056 GST_INFO_OBJECT (parse,
2057 "[WEB-ERROR] seek cur (%" G_GINT64_FORMAT ") > file_size (%"
2058 G_GINT64_FORMAT ") ", cur, aacparse->file_size);
2062 GST_INFO_OBJECT (parse,
2063 "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %"
2064 G_GINT64_FORMAT, rate, byte_cur, stop);
2066 if (!(flags & GST_SEEK_FLAG_KEY_UNIT)) {
2067 GST_INFO_OBJECT (parse,
2068 "Requested seek time: %" GST_TIME_FORMAT ", calculated seek offset: %"
2069 G_GUINT64_FORMAT, GST_TIME_ARGS (cur), byte_cur);
2072 /* BYTE seek event */
2074 gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
2076 res = gst_pad_push_event (parse->sinkpad, event);
2084 GST_DEBUG_OBJECT (parse,
2085 "could not determine byte position to seek to, " "seek aborted.");
2091 GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
2098 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
2101 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
2103 ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
2111 * gst_aac_parse_adts_src_eventfunc:
2112 * @parse: #GstBaseParse. #event
2114 * before baseparse handles seek event, make full amr index table.
2116 * Returns: TRUE on success.
2119 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
2121 gboolean handled = FALSE;
2122 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2124 switch (GST_EVENT_TYPE (event)) {
2125 case GST_EVENT_SEEK:
2127 GstFlowReturn res = GST_FLOW_OK;
2128 gint64 base_offset = 0, cur = 0;
2129 gint32 frame_count = 1; /* do not add first frame because it is already in index table */
2130 gint64 second_count = 0; /* initial 1 second */
2131 gint64 total_file_size = 0, start_offset = 0;
2132 GstClockTime current_ts = GST_CLOCK_TIME_NONE;
2133 GstPadMode pad_mode = GST_PAD_MODE_NONE;
2135 /* check baseparse define these fuction */
2136 gst_base_parse_get_pad_mode (parse, &pad_mode);
2137 if (pad_mode != GST_PAD_MODE_PULL) {
2138 gboolean ret = FALSE;
2139 GstPad *srcpad = parse->srcpad;
2140 GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
2142 if (aacparse->byte_seekable)
2143 return gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
2145 GST_INFO_OBJECT (aacparse, "not support byte seek");
2146 goto aac_seek_null_exit;
2149 gst_base_parse_get_upstream_size (parse, &total_file_size);
2150 gst_base_parse_get_index_last_offset (parse, &start_offset);
2151 gst_base_parse_get_index_last_ts (parse, ¤t_ts);
2153 if (total_file_size > AAC_LARGE_FILE_SIZE) {
2154 gst_base_parse_set_seek_mode (parse, 0);
2155 GST_INFO_OBJECT (aacparse, "larger than big size (2MB).");
2156 goto aac_seek_null_exit;
2159 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2161 if (total_file_size == 0 || start_offset >= total_file_size) {
2162 GST_ERROR ("last index offset %" G_GINT64_FORMAT
2163 " is larger than file size %" G_GINT64_FORMAT, start_offset,
2168 gst_event_parse_seek (event, NULL, NULL, NULL, NULL, &cur, NULL, NULL);
2169 if (cur <= current_ts) {
2170 GST_INFO ("seek to %" GST_TIME_FORMAT " within index table %"
2171 GST_TIME_FORMAT ". do not make index table", GST_TIME_ARGS (cur),
2172 GST_TIME_ARGS (current_ts));
2175 GST_INFO ("seek to %" GST_TIME_FORMAT " without index table %"
2176 GST_TIME_FORMAT ". make index table", GST_TIME_ARGS (cur),
2177 GST_TIME_ARGS (current_ts));
2180 GST_INFO ("make AAC(ADTS) Index Table. file_size = %" G_GINT64_FORMAT
2181 " last idx offset=%" G_GINT64_FORMAT ", last idx ts=%"
2182 GST_TIME_FORMAT, total_file_size, start_offset,
2183 GST_TIME_ARGS (current_ts));
2185 base_offset = start_offset; /* set base by start offset */
2186 second_count = current_ts + GST_SECOND; /* 1sec */
2188 /************************************/
2189 /* STEP 0: Setting parse information */
2190 /************************************/
2191 aacparse->spf = aacparse->frame_samples;
2192 aacparse->frame_duration = (aacparse->spf * 1000 * 100) / aacparse->sample_rate; /* duration per frame (msec) */
2193 aacparse->frame_per_sec = (aacparse->sample_rate) / aacparse->spf; /* frames per second (ea) */
2195 /************************************/
2196 /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2197 /************************************/
2198 while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2200 GstBuffer *buffer = NULL;
2203 GST_INFO ("gst_pad_pull_range %d bytes (from %" G_GINT64_FORMAT
2204 ") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2206 gst_pad_pull_range (parse->sinkpad, base_offset,
2207 base_offset + AAC_MAX_PULL_RANGE_BUF, &buffer);
2208 if (res != GST_FLOW_OK) {
2209 GST_ERROR ("gst_pad_pull_range failed!");
2213 gst_buffer_map (buffer, &map, GST_MAP_READ);
2216 gst_buffer_unmap (buffer, &map);
2217 GST_WARNING ("buffer is NULL in make aac seek table's STEP1");
2218 gst_buffer_unref (buffer);
2219 goto aac_seek_null_exit;
2222 while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2223 gint frame_size = 0;
2225 /* make sure the values in the frame header look sane */
2226 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2228 if ((frame_size > 0)
2229 && (frame_size < (AAC_MAX_PULL_RANGE_BUF - offset))) {
2230 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2231 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2232 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2233 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2234 base_offset + offset);
2235 second_count += GST_SECOND; /* 1sec */
2238 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2239 offset += frame_size;
2242 } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2243 GST_DEBUG ("we need refill buffer");
2246 GST_WARNING ("we lost sync");
2252 base_offset = base_offset + offset;
2254 gst_buffer_unmap (buffer, &map);
2255 gst_buffer_unref (buffer);
2256 } /* end MAX buffer cycle */
2258 /*******************************/
2259 /* STEP 2: Remain Buffer cycle */
2260 /*******************************/
2261 if (total_file_size - base_offset > 0) {
2263 GstBuffer *buffer = NULL;
2267 GST_INFO ("gst_pad_pull_range %" G_GINT64_FORMAT " bytes (from %"
2268 G_GINT64_FORMAT ") use remain_buf size",
2269 total_file_size - base_offset, base_offset);
2271 gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size,
2273 if (res != GST_FLOW_OK) {
2274 GST_ERROR ("gst_pad_pull_range failed!");
2278 gst_buffer_map (buffer, &map, GST_MAP_READ);
2281 gst_buffer_unmap (buffer, &map);
2282 GST_WARNING ("buffer is NULL in make aac seek table's STEP2");
2283 gst_buffer_unref (buffer);
2284 goto aac_seek_null_exit;
2287 while (base_offset + offset < total_file_size) {
2288 gint frame_size = 0;
2290 /* make sure the values in the frame header look sane */
2291 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2293 if ((frame_size > 0)
2294 && (frame_size <= (total_file_size - (base_offset + offset)))) {
2295 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2296 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2297 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2298 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2299 base_offset + offset);
2300 second_count += GST_SECOND; /* 1sec */
2303 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2304 offset += frame_size;
2307 } else if (frame_size == 0) {
2308 GST_DEBUG ("Frame size is 0 so, Decoding end..");
2311 GST_WARNING ("we lost sync");
2317 gst_buffer_unmap (buffer, &map);
2318 gst_buffer_unref (buffer);
2320 /* end remain_buf buffer cycle */
2321 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2331 /* call baseparse src_event function to handle event */
2332 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2337 gst_aac_parse_check_byte_seekability (GstBaseParse * parse)
2340 gboolean seekable = FALSE;
2341 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2342 GST_LOG_OBJECT (aacparse, "gst_aac_parse_check_byte_seekability enter");
2344 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2345 if (gst_pad_peer_query (parse->sinkpad, query))
2346 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
2348 GST_DEBUG_OBJECT (aacparse, "seeking query failed");
2350 gst_query_unref (query);
2352 GST_INFO_OBJECT (aacparse, "byte seekable: %d", seekable);
2354 aacparse->byte_seekable = seekable;
2356 #endif /* TIZEN_FEATURE_AACPARSE_MODIFICATION */