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
25 * @short_description: AAC parser
26 * @see_also: #GstAmrParse
28 * This is an AAC parser which handles both ADIF and ADTS stream formats.
30 * As ADIF format is not framed, it is not seekable and stream duration cannot
31 * be determined either. However, ADTS format AAC clips can be seeked, and parser
32 * can also estimate playback position and clip duration.
34 * ## Example launch line
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 "gstaudioparserselements.h"
50 #include "gstaacparse.h"
53 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
56 GST_STATIC_CAPS ("audio/mpeg, "
57 "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
58 "stream-format = (string) { raw, adts, adif, loas };"));
60 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
63 GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) { 2, 4 };"));
65 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
66 #define GST_CAT_DEFAULT aacparse_debug
69 #define ADIF_MAX_SIZE 40 /* Should be enough */
70 #define ADTS_MAX_SIZE 10 /* Should be enough */
71 #define LOAS_MAX_SIZE 3 /* Should be enough */
72 #define RAW_MAX_SIZE 1 /* Correct framing is required */
74 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
75 headers prepended during raw to ADTS
78 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION /* to get more accurate duration */
79 #define AAC_MAX_ESTIMATE_DURATION_BUF (1024 * 1024) /* use first 1 Mbyte */
80 #define AAC_SAMPLE_PER_FRAME 1024
82 #define AAC_MAX_PULL_RANGE_BUF (1 * 1024 * 1024) /* 1 MByte */
83 #define AAC_LARGE_FILE_SIZE (2 * 1024 * 1024) /* 2 MByte */
84 #define gst_aac_parse_parent_class parent_class
87 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
89 static const gint loas_sample_rate_table[16] = {
90 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
91 16000, 12000, 11025, 8000, 7350, 0, 0, 0
94 static const gint loas_channels_table[16] = {
95 0, 1, 2, 3, 4, 5, 6, 8,
96 0, 0, 0, 7, 8, 0, 8, 0
99 static gboolean gst_aac_parse_start (GstBaseParse * parse);
100 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
102 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
104 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
107 static GstFlowReturn gst_aac_parse_handle_frame (GstBaseParse * parse,
108 GstBaseParseFrame * frame, gint * skipsize);
109 static GstFlowReturn gst_aac_parse_pre_push_frame (GstBaseParse * parse,
110 GstBaseParseFrame * frame);
111 static gboolean gst_aac_parse_src_event (GstBaseParse * parse,
114 static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
115 aacparse, GstBitReader * br, gint * object_type, gint * sample_rate,
116 gint * channels, gint * frame_samples);
118 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
119 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
120 /* make full aac(adts) index table when seek */
121 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
123 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
125 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
126 static void gst_aac_parse_check_byte_seekability (GstBaseParse * parse);
129 #define gst_aac_parse_parent_class parent_class
130 G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
131 GST_ELEMENT_REGISTER_DEFINE (aacparse, "aacparse",
132 GST_RANK_PRIMARY + 1, GST_TYPE_AAC_PARSE);
134 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
136 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
138 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
139 32000, 24000, 22050, 16000, 12000, 11025, 8000
142 if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
143 return aac_sample_rates[sr_idx];
144 GST_WARNING ("Invalid sample rate index %u", sr_idx);
149 * gst_aac_parse_class_init:
150 * @klass: #GstAacParseClass.
154 gst_aac_parse_class_init (GstAacParseClass * klass)
156 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
157 GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
159 GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
160 "AAC audio stream parser");
162 gst_element_class_add_static_pad_template (element_class, &sink_template);
163 gst_element_class_add_static_pad_template (element_class, &src_template);
165 gst_element_class_set_static_metadata (element_class,
166 "AAC audio stream parser", "Codec/Parser/Audio",
167 "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
169 parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
170 parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
171 parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
172 parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
173 parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_handle_frame);
174 parse_class->pre_push_frame =
175 GST_DEBUG_FUNCPTR (gst_aac_parse_pre_push_frame);
176 parse_class->src_event = GST_DEBUG_FUNCPTR (gst_aac_parse_src_event);
181 * gst_aac_parse_init:
182 * @aacparse: #GstAacParse.
183 * @klass: #GstAacParseClass.
187 gst_aac_parse_init (GstAacParse * aacparse)
189 GST_DEBUG ("initialized");
190 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (aacparse));
191 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (aacparse));
193 aacparse->last_parsed_sample_rate = 0;
194 aacparse->last_parsed_channels = 0;
195 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
196 /* to get more correct duration */
197 aacparse->first_frame = TRUE;
203 * gst_aac_parse_set_src_caps:
204 * @aacparse: #GstAacParse.
205 * @sink_caps: (proposed) caps of sink pad
207 * Set source pad caps according to current knowledge about the
210 * Returns: TRUE if caps were successfully set.
213 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
216 GstCaps *src_caps = NULL, *peercaps;
217 gboolean res = FALSE;
218 const gchar *stream_format;
219 guint8 codec_data[2];
220 guint16 codec_data_data;
221 gint sample_rate_idx;
223 GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
225 src_caps = gst_caps_copy (sink_caps);
227 src_caps = gst_caps_new_empty_simple ("audio/mpeg");
229 gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
230 "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
232 aacparse->output_header_type = aacparse->header_type;
233 switch (aacparse->header_type) {
234 case DSPAAC_HEADER_NONE:
235 stream_format = "raw";
237 case DSPAAC_HEADER_ADTS:
238 stream_format = "adts";
240 case DSPAAC_HEADER_ADIF:
241 stream_format = "adif";
243 case DSPAAC_HEADER_LOAS:
244 stream_format = "loas";
247 stream_format = NULL;
250 /* Generate codec data to be able to set profile/level on the caps */
252 gst_codec_utils_aac_get_index_from_sample_rate (aacparse->sample_rate);
253 if (sample_rate_idx < 0)
254 goto not_a_known_rate;
256 (aacparse->object_type << 11) |
257 (sample_rate_idx << 7) | (aacparse->channels << 3);
258 GST_WRITE_UINT16_BE (codec_data, codec_data_data);
259 gst_codec_utils_aac_caps_set_level_and_profile (src_caps, codec_data, 2);
261 s = gst_caps_get_structure (src_caps, 0);
262 if (aacparse->sample_rate > 0)
263 gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
264 if (aacparse->channels > 0)
265 gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
267 gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
269 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
270 if (!gst_structure_get_value (s, "codec_data")) {
271 GstBuffer *codec_data_buffer;
272 GST_WARNING("Insert codec_data to src_caps");
273 /* The codec_data data is according to AudioSpecificConfig,
274 ISO/IEC 14496-3, 1.6.2.1 */
275 codec_data_buffer = gst_buffer_new_and_alloc (2);
276 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
277 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER, codec_data_buffer, NULL);
278 gst_buffer_unref (codec_data_buffer);
282 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (aacparse), NULL);
283 if (peercaps && !gst_caps_can_intersect (src_caps, peercaps)) {
284 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
285 "Caps can not intersect");
286 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
287 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
288 "Input is ADTS, trying raw");
289 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "raw",
291 if (gst_caps_can_intersect (src_caps, peercaps)) {
292 GstBuffer *codec_data_buffer;
294 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
295 "Caps can intersect, we will drop the ADTS layer");
296 aacparse->output_header_type = DSPAAC_HEADER_NONE;
298 /* The codec_data data is according to AudioSpecificConfig,
299 ISO/IEC 14496-3, 1.6.2.1 */
300 codec_data_buffer = gst_buffer_new_and_alloc (2);
301 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
302 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
303 codec_data_buffer, NULL);
304 gst_buffer_unref (codec_data_buffer);
306 } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
307 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
308 "Input is raw, trying ADTS");
309 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
311 if (gst_caps_can_intersect (src_caps, peercaps)) {
312 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
313 "Caps can intersect, we will prepend ADTS headers");
314 aacparse->output_header_type = DSPAAC_HEADER_ADTS;
319 gst_caps_unref (peercaps);
321 aacparse->last_parsed_channels = 0;
322 aacparse->last_parsed_sample_rate = 0;
324 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
326 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
327 gst_caps_unref (src_caps);
331 GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
332 aacparse->sample_rate);
333 gst_caps_unref (src_caps);
339 * gst_aac_parse_sink_setcaps:
343 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
345 * Returns: TRUE on success.
348 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
350 GstAacParse *aacparse;
351 GstStructure *structure;
355 aacparse = GST_AAC_PARSE (parse);
356 structure = gst_caps_get_structure (caps, 0);
357 caps_str = gst_caps_to_string (caps);
359 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
362 /* This is needed at least in case of RTP
363 * Parses the codec_data information to get ObjectType,
364 * number of channels and samplerate */
365 value = gst_structure_get_value (structure, "codec_data");
367 GstBuffer *buf = gst_value_get_buffer (value);
369 if (buf && gst_buffer_get_size (buf) >= 2) {
373 if (!gst_buffer_map (buf, &map, GST_MAP_READ))
375 gst_bit_reader_init (&br, map.data, map.size);
376 gst_aac_parse_read_audio_specific_config (aacparse, &br,
377 &aacparse->object_type, &aacparse->sample_rate, &aacparse->channels,
378 &aacparse->frame_samples);
380 aacparse->header_type = DSPAAC_HEADER_NONE;
381 aacparse->mpegversion = 4;
382 gst_buffer_unmap (buf, &map);
384 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
385 "samples=%d", aacparse->object_type, aacparse->sample_rate,
386 aacparse->channels, aacparse->frame_samples);
388 /* arrange for metadata and get out of the way */
389 gst_aac_parse_set_src_caps (aacparse, caps);
390 if (aacparse->header_type == aacparse->output_header_type)
391 gst_base_parse_set_passthrough (parse, TRUE);
393 /* input is already correctly framed */
394 gst_base_parse_set_min_frame_size (parse, RAW_MAX_SIZE);
399 /* caps info overrides */
400 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
401 gst_structure_get_int (structure, "channels", &aacparse->channels);
403 const gchar *stream_format =
404 gst_structure_get_string (structure, "stream-format");
406 if (g_strcmp0 (stream_format, "raw") == 0) {
407 GST_ERROR_OBJECT (parse, "Need codec_data for raw AAC");
410 aacparse->sample_rate = 0;
411 aacparse->channels = 0;
412 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
413 gst_base_parse_set_passthrough (parse, FALSE);
421 * gst_aac_parse_adts_get_frame_len:
422 * @data: block of data containing an ADTS header.
424 * This function calculates ADTS frame length from the given header.
426 * Returns: size of the ADTS frame.
429 gst_aac_parse_adts_get_frame_len (const guint8 * data)
431 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
436 * gst_aac_parse_check_adts_frame:
437 * @aacparse: #GstAacParse.
438 * @data: Data to be checked.
439 * @avail: Amount of data passed.
440 * @framesize: If valid ADTS frame was found, this will be set to tell the
441 * found frame size in bytes.
442 * @needed_data: If frame was not found, this may be set to tell how much
443 * more data is needed in the next round to detect the frame
444 * reliably. This may happen when a frame header candidate
445 * is found but it cannot be guaranteed to be the header without
446 * peeking the following data.
448 * Check if the given data contains contains ADTS frame. The algorithm
449 * will examine ADTS frame header and calculate the frame size. Also, another
450 * consecutive ADTS frame header need to be present after the found frame.
451 * Otherwise the data is not considered as a valid ADTS frame. However, this
452 * "extra check" is omitted when EOS has been received. In this case it is
453 * enough when data[0] contains a valid ADTS header.
455 * This function may set the #needed_data to indicate that a possible frame
456 * candidate has been found, but more data (#needed_data bytes) is needed to
457 * be absolutely sure. When this situation occurs, FALSE will be returned.
459 * When a valid frame is detected, this function will use
460 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
461 * to set the needed bytes for next frame.This way next data chunk is already
464 * Returns: TRUE if the given data contains a valid ADTS header.
467 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
468 const guint8 * data, const guint avail, gboolean drain,
469 guint * framesize, guint * needed_data)
475 /* Absolute minimum to perform the ADTS syncword,
476 layer and sampling frequency tests */
477 if (G_UNLIKELY (avail < 3)) {
482 /* Syncword and layer tests */
483 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
485 /* Sampling frequency test */
486 if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
489 /* This looks like an ADTS frame header but
490 we need at least 6 bytes to proceed */
491 if (G_UNLIKELY (avail < 6)) {
496 *framesize = gst_aac_parse_adts_get_frame_len (data);
498 /* If frame has CRC, it needs 2 bytes
499 for it at the end of the header */
500 crc_size = (data[1] & 0x01) ? 0 : 2;
503 if (*framesize < 7 + crc_size) {
504 *needed_data = 7 + crc_size;
508 /* In EOS mode this is enough. No need to examine the data further.
509 We also relax the check when we have sync, on the assumption that
510 if we're not looking at random data, we have a much higher chance
511 to get the correct sync, and this avoids losing two frames when
512 a single bit corruption happens. */
513 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
517 if (*framesize + ADTS_MAX_SIZE > avail) {
518 /* We have found a possible frame header candidate, but can't be
519 sure since we don't have enough data to check the next frame */
520 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
521 *framesize + ADTS_MAX_SIZE, avail);
522 *needed_data = *framesize + ADTS_MAX_SIZE;
523 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
524 *framesize + ADTS_MAX_SIZE);
528 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
529 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
531 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
532 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
533 nextlen + ADTS_MAX_SIZE);
541 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
544 guint8 bytes, i, byte;
547 if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
549 for (i = 0; i <= bytes; ++i) {
551 if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
559 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
560 guint8 * audio_object_type)
562 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
564 if (*audio_object_type == 31) {
565 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
567 *audio_object_type += 32;
569 GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
574 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
577 guint8 sampling_frequency_index;
578 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
580 GST_LOG_OBJECT (aacparse, "sampling_frequency_index: %u",
581 sampling_frequency_index);
582 if (sampling_frequency_index == 0xf) {
583 guint32 sampling_rate;
584 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
586 *sample_rate = sampling_rate;
588 *sample_rate = loas_sample_rate_table[sampling_frequency_index];
592 aacparse->last_parsed_sample_rate = *sample_rate;
596 /* See table 1.13 in ISO/IEC 14496-3 */
598 gst_aac_parse_read_audio_specific_config (GstAacParse * aacparse,
599 GstBitReader * br, gint * object_type, gint * sample_rate, gint * channels,
600 gint * frame_samples)
602 guint8 audio_object_type;
603 guint8 G_GNUC_UNUSED extension_audio_object_type;
604 guint8 channel_configuration, extension_channel_configuration;
605 gboolean G_GNUC_UNUSED sbr = FALSE, ps = FALSE;
607 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
610 *object_type = audio_object_type;
612 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
615 if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
617 *channels = loas_channels_table[channel_configuration];
618 GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
622 if (audio_object_type == 5 || audio_object_type == 29) {
623 extension_audio_object_type = 5;
625 if (audio_object_type == 29) {
627 /* Parametric stereo. If we have a one-channel configuration, we can
628 * override it to stereo */
633 GST_LOG_OBJECT (aacparse,
634 "Audio object type 5 or 29, so rereading sampling rate (was %d)...",
636 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
639 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
642 if (audio_object_type == 22) {
643 /* extension channel configuration */
644 if (!gst_bit_reader_get_bits_uint8 (br, &extension_channel_configuration,
647 GST_LOG_OBJECT (aacparse, "extension channel_configuration: %d",
648 extension_channel_configuration);
649 *channels = loas_channels_table[extension_channel_configuration];
654 extension_audio_object_type = 0;
657 GST_INFO_OBJECT (aacparse, "Parsed AudioSpecificConfig: %d Hz, %d channels",
658 *sample_rate, *channels);
660 if (frame_samples && audio_object_type == 23) {
662 /* Read the Decoder Configuration (GASpecificConfig) if present */
663 /* We only care about the first bit to know what the number of samples
665 if (!gst_bit_reader_get_bits_uint8 (br, &frame_flag, 1))
667 *frame_samples = frame_flag ? 960 : 1024;
670 /* There's LOTS of stuff next, but we ignore it for now as we have
671 what we want (sample rate and number of channels */
672 GST_DEBUG_OBJECT (aacparse,
673 "Need more code to parse humongous LOAS data, currently ignored");
674 aacparse->last_parsed_channels = *channels;
680 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
681 guint avail, gint * sample_rate, gint * channels, gint * version)
686 /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
690 gst_bit_reader_init (&br, data, avail);
692 /* skip sync word (11 bits) and size (13 bits) */
693 if (!gst_bit_reader_skip (&br, 11 + 13))
696 /* First bit is "use last config" */
697 if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
700 GST_LOG_OBJECT (aacparse, "Frame uses previous config");
701 if (!aacparse->last_parsed_sample_rate || !aacparse->last_parsed_channels) {
702 GST_DEBUG_OBJECT (aacparse,
703 "No previous config to use. We'll look for more data.");
706 *sample_rate = aacparse->last_parsed_sample_rate;
707 *channels = aacparse->last_parsed_channels;
711 GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
713 /* audioMuxVersion */
714 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
717 /* audioMuxVersionA */
718 if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
723 GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
725 guint8 same_time, subframes, num_program, prog;
728 /* taraBufferFullness */
729 if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
732 if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
734 if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
736 if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
738 GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
739 same_time, subframes, num_program);
741 for (prog = 0; prog <= num_program; ++prog) {
742 guint8 num_layer, layer;
743 if (!gst_bit_reader_get_bits_uint8 (&br, &num_layer, 3))
745 GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
747 for (layer = 0; layer <= num_layer; ++layer) {
748 guint8 use_same_config;
749 if (prog == 0 && layer == 0) {
752 if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
755 if (!use_same_config) {
757 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
758 sample_rate, channels, NULL))
762 if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
764 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
765 sample_rate, channels, NULL))
767 if (!gst_bit_reader_skip (&br, asc_len))
773 GST_LOG_OBJECT (aacparse, "More data ignored");
775 GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
782 * gst_aac_parse_loas_get_frame_len:
783 * @data: block of data containing a LOAS header.
785 * This function calculates LOAS frame length from the given header.
787 * Returns: size of the LOAS frame.
790 gst_aac_parse_loas_get_frame_len (const guint8 * data)
792 return (((data[1] & 0x1f) << 8) | data[2]) + 3;
797 * gst_aac_parse_check_loas_frame:
798 * @aacparse: #GstAacParse.
799 * @data: Data to be checked.
800 * @avail: Amount of data passed.
801 * @framesize: If valid LOAS frame was found, this will be set to tell the
802 * found frame size in bytes.
803 * @needed_data: If frame was not found, this may be set to tell how much
804 * more data is needed in the next round to detect the frame
805 * reliably. This may happen when a frame header candidate
806 * is found but it cannot be guaranteed to be the header without
807 * peeking the following data.
809 * Check if the given data contains contains LOAS frame. The algorithm
810 * will examine LOAS frame header and calculate the frame size. Also, another
811 * consecutive LOAS frame header need to be present after the found frame.
812 * Otherwise the data is not considered as a valid LOAS frame. However, this
813 * "extra check" is omitted when EOS has been received. In this case it is
814 * enough when data[0] contains a valid LOAS header.
816 * This function may set the #needed_data to indicate that a possible frame
817 * candidate has been found, but more data (#needed_data bytes) is needed to
818 * be absolutely sure. When this situation occurs, FALSE will be returned.
820 * When a valid frame is detected, this function will use
821 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
822 * to set the needed bytes for next frame.This way next data chunk is already
825 * LOAS can have three different formats, if I read the spec correctly. Only
826 * one of them is supported here, as the two samples I have use this one.
828 * Returns: TRUE if the given data contains a valid LOAS header.
831 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
832 const guint8 * data, const guint avail, gboolean drain,
833 guint * framesize, guint * needed_data)
838 if (G_UNLIKELY (avail < 3)) {
843 if ((data[0] == 0x56) && ((data[1] & 0xe0) == 0xe0)) {
844 *framesize = gst_aac_parse_loas_get_frame_len (data);
845 GST_DEBUG_OBJECT (aacparse, "Found possible %u byte LOAS frame",
848 /* In EOS mode this is enough. No need to examine the data further.
849 We also relax the check when we have sync, on the assumption that
850 if we're not looking at random data, we have a much higher chance
851 to get the correct sync, and this avoids losing two frames when
852 a single bit corruption happens. */
853 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
857 if (*framesize + LOAS_MAX_SIZE > avail) {
858 /* We have found a possible frame header candidate, but can't be
859 sure since we don't have enough data to check the next frame */
860 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
861 *framesize + LOAS_MAX_SIZE, avail);
862 *needed_data = *framesize + LOAS_MAX_SIZE;
863 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
864 *framesize + LOAS_MAX_SIZE);
868 if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
869 guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
871 GST_LOG ("LOAS frame found, len: %d bytes", *framesize);
872 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
873 nextlen + LOAS_MAX_SIZE);
876 GST_DEBUG_OBJECT (aacparse, "That was a false positive");
882 /* caller ensure sufficient data */
884 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
885 gint * rate, gint * channels, gint * object, gint * version)
889 gint sr_idx = (data[2] & 0x3c) >> 2;
891 *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
894 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
900 *version = (data[1] & 0x08) ? 2 : 4;
902 *object = ((data[2] & 0xc0) >> 6) + 1;
906 * gst_aac_parse_detect_stream:
907 * @aacparse: #GstAacParse.
908 * @data: A block of data that needs to be examined for stream characteristics.
909 * @avail: Size of the given datablock.
910 * @framesize: If valid stream was found, this will be set to tell the
911 * first frame size in bytes.
912 * @skipsize: If valid stream was found, this will be set to tell the first
913 * audio frame position within the given data.
915 * Examines the given piece of data and try to detect the format of it. It
916 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
917 * header. If the stream is detected, TRUE will be returned and #framesize
918 * is set to indicate the found frame size. Additionally, #skipsize might
919 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
920 * position of the frame inside given data chunk.
922 * Returns: TRUE on success.
925 gst_aac_parse_detect_stream (GstAacParse * aacparse,
926 const guint8 * data, const guint avail, gboolean drain,
927 guint * framesize, gint * skipsize)
929 gboolean found = FALSE;
930 guint need_data_adts = 0, need_data_loas;
933 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
935 /* FIXME: No need to check for ADIF if we are not in the beginning of the
938 /* Can we even parse the header? */
939 if (avail < MAX (ADTS_MAX_SIZE, LOAS_MAX_SIZE)) {
940 GST_DEBUG_OBJECT (aacparse, "Not enough data to check");
944 for (i = 0; i < avail - 4; i++) {
945 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
946 ((data[i] == 0x56) && ((data[i + 1] & 0xe0) == 0xe0)) ||
947 strncmp ((char *) data + i, "ADIF", 4) == 0) {
948 GST_DEBUG_OBJECT (aacparse, "Found signature at offset %u", i);
952 /* Trick: tell the parent class that we didn't find the frame yet,
953 but make it skip 'i' amount of bytes. Next time we arrive
954 here we have full frame in the beginning of the data. */
967 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
968 framesize, &need_data_adts)) {
971 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
973 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
974 &aacparse->object_type, &aacparse->mpegversion);
976 if (!channels || !framesize) {
977 GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
981 aacparse->header_type = DSPAAC_HEADER_ADTS;
982 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
983 aacparse->frame_samples, 2, 2);
985 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
986 rate, channels, aacparse->object_type, aacparse->mpegversion);
988 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
993 if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
994 framesize, &need_data_loas)) {
995 gint rate = 0, channels = 0;
997 GST_INFO ("LOAS, framesize: %d", *framesize);
999 aacparse->header_type = DSPAAC_HEADER_LOAS;
1001 if (!gst_aac_parse_read_loas_config (aacparse, data, avail, &rate,
1002 &channels, &aacparse->mpegversion)) {
1003 /* This is pretty normal when skipping data at the start of
1004 * random stream (MPEG-TS capture for example) */
1005 GST_LOG_OBJECT (aacparse, "Error reading LOAS config");
1009 if (rate && channels) {
1010 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
1011 aacparse->frame_samples, 2, 2);
1013 /* Don't store the sample rate and channels yet -
1014 * this is just format detection. */
1015 GST_DEBUG ("LOAS: samplerate %d, channels %d, objtype %d, version %d",
1016 rate, channels, aacparse->object_type, aacparse->mpegversion);
1019 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
1024 if (need_data_adts || need_data_loas) {
1025 /* This tells the parent class not to skip any data */
1030 if (avail < ADIF_MAX_SIZE)
1033 if (memcmp (data + i, "ADIF", 4) == 0) {
1040 aacparse->header_type = DSPAAC_HEADER_ADIF;
1041 aacparse->mpegversion = 4;
1043 /* Skip the "ADIF" bytes */
1044 adif = data + i + 4;
1046 /* copyright string */
1048 skip_size += 9; /* skip 9 bytes */
1050 bitstream_type = adif[0 + skip_size] & 0x10;
1052 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
1053 ((unsigned int) adif[1 + skip_size] << 11) |
1054 ((unsigned int) adif[2 + skip_size] << 3) |
1055 ((unsigned int) adif[3 + skip_size] & 0xe0);
1058 if (bitstream_type == 0) {
1060 /* Buffer fullness parsing. Currently not needed... */
1061 guint num_elems = 0;
1064 num_elems = (adif[3 + skip_size] & 0x1e);
1065 GST_INFO ("ADIF num_config_elems: %d", num_elems);
1067 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
1068 ((unsigned int) adif[4 + skip_size] << 11) |
1069 ((unsigned int) adif[5 + skip_size] << 3) |
1070 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
1072 GST_INFO ("ADIF buffer fullness: %d", fullness);
1074 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
1075 ((adif[7 + skip_size] & 0x80) >> 7);
1076 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
1080 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
1081 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
1082 ((adif[5 + skip_size] & 0x80) >> 7);
1085 /* FIXME: This gives totally wrong results. Duration calculation cannot
1087 aacparse->sample_rate =
1088 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1090 /* baseparse is not given any fps,
1091 * so it will give up on timestamps, seeking, etc */
1093 /* FIXME: Can we assume this? */
1094 aacparse->channels = 2;
1096 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1097 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1099 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1101 /* arrange for metadata and get out of the way */
1102 sinkcaps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (aacparse));
1103 gst_aac_parse_set_src_caps (aacparse, sinkcaps);
1105 gst_caps_unref (sinkcaps);
1107 /* not syncable, not easily seekable (unless we push data from start */
1108 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
1109 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
1110 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
1116 /* This should never happen */
1121 * gst_aac_parse_get_audio_profile_object_type
1122 * @aacparse: #GstAacParse.
1124 * Gets the MPEG-2 profile or the MPEG-4 object type value corresponding to the
1125 * mpegversion and profile of @aacparse's src pad caps, according to the
1126 * values defined by table 1.A.11 in ISO/IEC 14496-3.
1128 * Returns: the profile or object type value corresponding to @aacparse's src
1129 * pad caps, if such a value exists; otherwise G_MAXUINT8.
1132 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1135 GstStructure *srcstruct;
1136 const gchar *profile;
1139 srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1140 if (G_UNLIKELY (srccaps == NULL)) {
1144 srcstruct = gst_caps_get_structure (srccaps, 0);
1145 profile = gst_structure_get_string (srcstruct, "profile");
1146 if (G_UNLIKELY (profile == NULL)) {
1147 gst_caps_unref (srccaps);
1151 if (g_strcmp0 (profile, "main") == 0) {
1153 } else if (g_strcmp0 (profile, "lc") == 0) {
1155 } else if (g_strcmp0 (profile, "ssr") == 0) {
1157 } else if (g_strcmp0 (profile, "ltp") == 0) {
1158 if (G_LIKELY (aacparse->mpegversion == 4))
1161 ret = G_MAXUINT8; /* LTP Object Type allowed only for MPEG-4 */
1166 gst_caps_unref (srccaps);
1171 * gst_aac_parse_get_audio_channel_configuration
1172 * @num_channels: number of audio channels.
1174 * Gets the Channel Configuration value, as defined by table 1.19 in ISO/IEC
1175 * 14496-3, for a given number of audio channels.
1177 * Returns: the Channel Configuration value corresponding to @num_channels, if
1178 * such a value exists; otherwise G_MAXUINT8.
1181 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1183 if (num_channels >= 1 && num_channels <= 6) /* Mono up to & including 5.1 */
1184 return (guint8) num_channels;
1185 else if (num_channels == 8) /* 7.1 */
1190 /* FIXME: Add support for configurations 11, 12 and 14 from
1191 * ISO/IEC 14496-3:2009/PDAM 4 based on the actual channel layout
1196 * gst_aac_parse_get_audio_sampling_frequency_index:
1197 * @sample_rate: audio sampling rate.
1199 * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1200 * 14496-3, for a given sampling rate.
1202 * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1203 * if such a value exists; otherwise G_MAXUINT8.
1206 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1208 switch (sample_rate) {
1241 * gst_aac_parse_prepend_adts_headers:
1242 * @aacparse: #GstAacParse.
1243 * @frame: raw AAC frame to which ADTS headers shall be prepended.
1245 * Prepends ADTS headers to a raw AAC audio frame.
1247 * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1250 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1251 GstBaseParseFrame * frame)
1254 guint8 *adts_headers;
1257 guint8 id, profile, channel_configuration, sampling_frequency_index;
1259 id = (aacparse->mpegversion == 4) ? 0x0U : 0x1U;
1260 profile = gst_aac_parse_get_audio_profile_object_type (aacparse);
1261 if (profile == G_MAXUINT8) {
1262 GST_ERROR_OBJECT (aacparse, "Unsupported audio profile or object type");
1265 channel_configuration =
1266 gst_aac_parse_get_audio_channel_configuration (aacparse->channels);
1267 if (channel_configuration == G_MAXUINT8) {
1268 GST_ERROR_OBJECT (aacparse, "Unsupported number of channels");
1271 sampling_frequency_index =
1272 gst_aac_parse_get_audio_sampling_frequency_index (aacparse->sample_rate);
1273 if (sampling_frequency_index == G_MAXUINT8) {
1274 GST_ERROR_OBJECT (aacparse, "Unsupported sampling frequency");
1278 frame->out_buffer = gst_buffer_copy (frame->buffer);
1279 buf_size = gst_buffer_get_size (frame->out_buffer);
1280 frame_size = buf_size + ADTS_HEADERS_LENGTH;
1282 if (G_UNLIKELY (frame_size >= 0x4000)) {
1283 GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1287 adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1289 /* Note: no error correction bits are added to the resulting ADTS frames */
1290 adts_headers[0] = 0xFFU;
1291 adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
1292 adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
1293 ((channel_configuration & 0x4U) >> 2);
1294 adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
1295 (guint8) (frame_size >> 11);
1296 adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
1297 adts_headers[5] = (guint8) (((frame_size & 0x0007) << 5) + 0x1FU);
1298 adts_headers[6] = 0xFCU;
1300 mem = gst_memory_new_wrapped (0, adts_headers, ADTS_HEADERS_LENGTH, 0,
1301 ADTS_HEADERS_LENGTH, adts_headers, g_free);
1302 gst_buffer_prepend_memory (frame->out_buffer, mem);
1308 * gst_aac_parse_check_valid_frame:
1309 * @parse: #GstBaseParse.
1310 * @frame: #GstBaseParseFrame.
1311 * @skipsize: How much data parent class should skip in order to find the
1314 * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1316 * Also determines frame overhead.
1317 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
1318 * a per-frame header. LOAS has 3 bytes.
1320 * We're making a couple of simplifying assumptions:
1322 * 1. We count Program Configuration Elements rather than searching for them
1323 * in the streams to discount them - the overhead is negligible.
1325 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
1326 * bits, which should still not be significant enough to warrant the
1327 * additional parsing through the headers
1329 * Returns: a #GstFlowReturn.
1331 static GstFlowReturn
1332 gst_aac_parse_handle_frame (GstBaseParse * parse,
1333 GstBaseParseFrame * frame, gint * skipsize)
1336 GstAacParse *aacparse;
1337 gboolean ret = FALSE;
1341 gint rate = 0, channels = 0;
1343 aacparse = GST_AAC_PARSE (parse);
1344 buffer = frame->buffer;
1346 gst_buffer_map (buffer, &map, GST_MAP_READ);
1349 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1351 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
1352 aacparse->header_type == DSPAAC_HEADER_NONE) {
1353 /* There is nothing to parse */
1354 framesize = map.size;
1357 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1359 ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1360 GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1362 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1363 guint needed_data = 1024;
1365 ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1366 GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1368 if (!ret && needed_data) {
1369 GST_DEBUG ("buffer didn't contain valid frame");
1371 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1375 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1376 guint needed_data = 1024;
1378 ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1379 map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1381 if (!ret && needed_data) {
1382 GST_DEBUG ("buffer didn't contain valid frame");
1384 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1389 GST_DEBUG ("buffer didn't contain valid frame");
1390 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1394 if (G_UNLIKELY (!ret))
1397 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1399 frame->overhead = 7;
1401 gst_aac_parse_parse_adts_header (aacparse, map.data,
1402 &rate, &channels, NULL, NULL);
1404 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1406 if (G_UNLIKELY (rate != aacparse->sample_rate
1407 || channels != aacparse->channels)) {
1408 aacparse->sample_rate = rate;
1409 aacparse->channels = channels;
1411 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1412 /* If linking fails, we need to return appropriate error */
1413 ret = GST_FLOW_NOT_LINKED;
1416 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1417 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1419 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1420 if (aacparse->first_frame == TRUE) {
1421 gboolean ret = FALSE;
1422 aacparse->first_frame = FALSE;
1424 ret = gst_aac_parse_estimate_duration (parse);
1426 GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1427 ret = GST_FLOW_NOT_SUPPORTED;
1429 gst_aac_parse_check_byte_seekability (parse);
1432 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1433 gboolean setcaps = FALSE;
1436 frame->overhead = 3;
1438 if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
1439 &channels, NULL) || !rate || !channels) {
1440 /* This is pretty normal when skipping data at the start of
1441 * random stream (MPEG-TS capture for example) */
1442 GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
1443 /* Since we don't fully parse the LOAS config, we don't know for sure
1444 * how much to skip. Just skip 1 to end up to the next marker and
1445 * resume parsing from there */
1450 if (G_UNLIKELY (rate != aacparse->sample_rate
1451 || channels != aacparse->channels)) {
1452 aacparse->sample_rate = rate;
1453 aacparse->channels = channels;
1455 GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1459 /* We want to set caps both at start, and when rate/channels change.
1460 Since only some LOAS frames have that info, we may receive frames
1461 before knowing about rate/channels. */
1463 || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
1464 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1465 /* If linking fails, we need to return appropriate error */
1466 ret = GST_FLOW_NOT_LINKED;
1469 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1470 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1473 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1474 else if (aacparse->header_type == DSPAAC_HEADER_ADIF) {
1475 /* to get more correct duration */
1476 float estimated_duration = 0;
1477 gint64 total_file_size;
1478 gst_base_parse_get_upstream_size (parse, &total_file_size);
1479 estimated_duration =
1480 ((total_file_size * 8) / (float) (aacparse->bitrate * 1000)) *
1482 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1483 estimated_duration * 1000, 0);
1487 if (aacparse->header_type == DSPAAC_HEADER_NONE
1488 && aacparse->output_header_type == DSPAAC_HEADER_ADTS) {
1489 if (!gst_aac_parse_prepend_adts_headers (aacparse, frame)) {
1490 GST_ERROR_OBJECT (aacparse, "Failed to prepend ADTS headers to frame");
1491 ret = GST_FLOW_ERROR;
1496 gst_buffer_unmap (buffer, &map);
1499 /* found, skip if needed */
1508 if (ret && framesize <= map.size) {
1509 return gst_base_parse_finish_frame (parse, frame, framesize);
1515 static GstFlowReturn
1516 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1518 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1520 if (!aacparse->sent_codec_tag) {
1521 GstTagList *taglist;
1525 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1527 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1528 GST_INFO_OBJECT (parse, "Src pad is flushing");
1529 return GST_FLOW_FLUSHING;
1531 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1532 return GST_FLOW_NOT_NEGOTIATED;
1536 taglist = gst_tag_list_new_empty ();
1537 gst_pb_utils_add_codec_description_to_tag_list (taglist,
1538 GST_TAG_AUDIO_CODEC, caps);
1539 gst_caps_unref (caps);
1541 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1542 gst_tag_list_unref (taglist);
1544 /* also signals the end of first-frame processing */
1545 aacparse->sent_codec_tag = TRUE;
1548 /* As a special case, we can remove the ADTS framing and output raw AAC. */
1549 if (aacparse->header_type == DSPAAC_HEADER_ADTS
1550 && aacparse->output_header_type == DSPAAC_HEADER_NONE) {
1553 frame->out_buffer = gst_buffer_make_writable (frame->buffer);
1554 frame->buffer = NULL;
1555 gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ);
1556 header_size = (map.data[1] & 1) ? 7 : 9; /* optional CRC */
1557 gst_buffer_unmap (frame->out_buffer, &map);
1558 gst_buffer_resize (frame->out_buffer, header_size,
1559 gst_buffer_get_size (frame->out_buffer) - header_size);
1562 frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1569 * gst_aac_parse_start:
1570 * @parse: #GstBaseParse.
1572 * Implementation of "start" vmethod in #GstBaseParse class.
1574 * Returns: TRUE if startup succeeded.
1577 gst_aac_parse_start (GstBaseParse * parse)
1579 GstAacParse *aacparse;
1581 aacparse = GST_AAC_PARSE (parse);
1582 GST_DEBUG ("start");
1583 aacparse->frame_samples = 1024;
1584 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
1585 aacparse->sent_codec_tag = FALSE;
1586 aacparse->last_parsed_channels = 0;
1587 aacparse->last_parsed_sample_rate = 0;
1588 aacparse->object_type = 0;
1589 aacparse->bitrate = 0;
1590 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
1591 aacparse->output_header_type = DSPAAC_HEADER_NOT_PARSED;
1592 aacparse->channels = 0;
1593 aacparse->sample_rate = 0;
1599 * gst_aac_parse_stop:
1600 * @parse: #GstBaseParse.
1602 * Implementation of "stop" vmethod in #GstBaseParse class.
1604 * Returns: TRUE is stopping succeeded.
1607 gst_aac_parse_stop (GstBaseParse * parse)
1614 remove_fields (GstCaps * caps)
1618 n = gst_caps_get_size (caps);
1619 for (i = 0; i < n; i++) {
1620 GstStructure *s = gst_caps_get_structure (caps, i);
1622 gst_structure_remove_field (s, "framed");
1627 add_conversion_fields (GstCaps * caps)
1631 n = gst_caps_get_size (caps);
1632 for (i = 0; i < n; i++) {
1633 GstStructure *s = gst_caps_get_structure (caps, i);
1635 if (gst_structure_has_field (s, "stream-format")) {
1636 const GValue *v = gst_structure_get_value (s, "stream-format");
1638 if (G_VALUE_HOLDS_STRING (v)) {
1639 const gchar *str = g_value_get_string (v);
1641 if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1642 GValue va = G_VALUE_INIT;
1643 GValue vs = G_VALUE_INIT;
1645 g_value_init (&va, GST_TYPE_LIST);
1646 g_value_init (&vs, G_TYPE_STRING);
1647 g_value_set_string (&vs, "adts");
1648 gst_value_list_append_value (&va, &vs);
1649 g_value_set_string (&vs, "raw");
1650 gst_value_list_append_value (&va, &vs);
1651 gst_structure_set_value (s, "stream-format", &va);
1652 g_value_unset (&va);
1653 g_value_unset (&vs);
1655 } else if (GST_VALUE_HOLDS_LIST (v)) {
1656 gboolean contains_raw = FALSE;
1657 gboolean contains_adts = FALSE;
1658 guint m = gst_value_list_get_size (v), j;
1660 for (j = 0; j < m; j++) {
1661 const GValue *ve = gst_value_list_get_value (v, j);
1664 if (G_VALUE_HOLDS_STRING (ve) && (str = g_value_get_string (ve))) {
1665 if (strcmp (str, "adts") == 0)
1666 contains_adts = TRUE;
1667 else if (strcmp (str, "raw") == 0)
1668 contains_raw = TRUE;
1672 if (contains_adts || contains_raw) {
1673 GValue va = G_VALUE_INIT;
1674 GValue vs = G_VALUE_INIT;
1676 g_value_init (&va, GST_TYPE_LIST);
1677 g_value_init (&vs, G_TYPE_STRING);
1678 g_value_copy (v, &va);
1680 if (!contains_raw) {
1681 g_value_set_string (&vs, "raw");
1682 gst_value_list_append_value (&va, &vs);
1684 if (!contains_adts) {
1685 g_value_set_string (&vs, "adts");
1686 gst_value_list_append_value (&va, &vs);
1689 gst_structure_set_value (s, "stream-format", &va);
1691 g_value_unset (&vs);
1692 g_value_unset (&va);
1700 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1702 GstCaps *peercaps, *templ;
1705 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1708 GstCaps *fcopy = gst_caps_copy (filter);
1709 /* Remove the fields we convert */
1710 remove_fields (fcopy);
1711 add_conversion_fields (fcopy);
1712 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1713 gst_caps_unref (fcopy);
1715 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1718 peercaps = gst_caps_make_writable (peercaps);
1719 /* Remove the fields we convert */
1720 remove_fields (peercaps);
1721 add_conversion_fields (peercaps);
1723 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1724 gst_caps_unref (peercaps);
1725 gst_caps_unref (templ);
1731 GstCaps *intersection;
1734 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1735 gst_caps_unref (res);
1743 gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1745 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1747 if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1748 aacparse->last_parsed_channels = 0;
1749 aacparse->last_parsed_sample_rate = 0;
1751 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1752 GST_DEBUG ("Entering gst_aac_parse_src_event header type = %d",
1753 aacparse->header_type);
1754 if (aacparse->header_type == DSPAAC_HEADER_ADTS)
1755 return gst_aac_parse_adts_src_eventfunc (parse, event);
1757 return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1761 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1763 * get_aac_parse_get_adts_framelength:
1764 * @data: #GstBufferData.
1765 * @offset: #GstBufferData offset
1767 * Implementation to get adts framelength by using first some frame.
1769 * Returns: frame size
1772 get_aac_parse_get_adts_frame_length (const unsigned char *data, gint64 offset)
1774 const gint adts_header_length_no_crc = 7;
1775 const gint adts_header_length_with_crc = 9;
1776 gint frame_size = 0;
1777 gint protection_absent;
1780 /* check of syncword */
1781 if ((data[offset + 0] != 0xff) || ((data[offset + 1] & 0xf6) != 0xf0)) {
1782 GST_ERROR ("check sync word is fail\n");
1786 /* check of protection absent */
1787 protection_absent = (data[offset + 1] & 0x01);
1789 /*check of frame length */
1791 (data[offset + 3] & 0x3) << 11 | data[offset + 4] << 3 | data[offset +
1794 /* check of header size */
1795 /* protectionAbsent is 0 if there is CRC */
1797 protection_absent ? adts_header_length_no_crc :
1798 adts_header_length_with_crc;
1799 if (head_size > frame_size) {
1800 GST_ERROR ("return frame length as 0 (frameSize %u < headSize %u)",
1801 frame_size, head_size);
1809 * gst_aac_parse_estimate_duration:
1810 * @parse: #GstBaseParse.
1812 * Implementation to get estimated total duration by using first some frame.
1814 * Returns: TRUE if we can get estimated total duraion
1817 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1819 gboolean ret = FALSE;
1820 GstFlowReturn res = GST_FLOW_OK;
1821 gint64 pull_size = 0, file_size = 0, offset = 0, num_frames = 0, duration = 0;
1822 guint sample_rate_index = 0, sample_rate = 0, channel = 0;
1823 guint frame_size = 0, frame_duration_us = 0, estimated_bitrate = 0;
1824 guint lost_sync_count = 0;
1825 GstClockTime estimated_duration = GST_CLOCK_TIME_NONE;
1826 GstBuffer *buffer = NULL;
1829 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1830 GstAacParse *aacparse;
1831 gint64 buffer_size = 0;
1834 aacparse = GST_AAC_PARSE (parse);
1835 GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1837 /* check baseparse define these fuction */
1838 gst_base_parse_get_pad_mode (parse, &pad_mode);
1839 if (pad_mode != GST_PAD_MODE_PULL) {
1840 GST_INFO_OBJECT (aacparse,
1841 "aac parser is not pull mode. can not estimate duration");
1845 gst_base_parse_get_upstream_size (parse, &file_size);
1847 if (file_size < ADIF_MAX_SIZE) {
1848 GST_ERROR_OBJECT (aacparse, "file size is too short");
1852 pull_size = MIN (file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1854 res = gst_pad_pull_range (parse->sinkpad, 0, pull_size, &buffer);
1855 if (res != GST_FLOW_OK) {
1856 GST_ERROR_OBJECT (aacparse, "gst_pad_pull_range failed!");
1860 gst_buffer_map (buffer, &map, GST_MAP_READ);
1862 buffer_size = map.size;
1863 if (buffer_size != pull_size) {
1864 GST_ERROR_OBJECT (aacparse,
1865 "We got different buffer_size(%" G_GINT64_FORMAT ") with pull_size(%"
1866 G_GINT64_FORMAT ").", buffer_size, pull_size);
1869 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1870 for (i = 0; i < buffer_size; i++) {
1871 if ((buf[i] == 0xff) && ((buf[i + 1] & 0xf6) == 0xf0)) { /* aac sync word */
1872 //guint profile = (buf[i+2] >> 6) & 0x3;
1873 sample_rate_index = (buf[i + 2] >> 2) & 0xf;
1875 gst_aac_parse_get_sample_rate_from_index (sample_rate_index);
1876 if (sample_rate == 0) {
1877 GST_WARNING_OBJECT (aacparse, "Invalid sample rate index (0)");
1880 channel = (buf[i + 2] & 0x1) << 2 | (buf[i + 3] >> 6);
1882 GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate,
1885 /* count number of frames */
1886 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1887 //while (offset < pull_size) {
1888 while (offset < buffer_size) {
1889 frame_size = get_aac_parse_get_adts_frame_length (buf, i + offset);
1890 if (frame_size == 0) {
1891 GST_ERROR_OBJECT (aacparse,
1892 "framesize error at offset %" G_GINT64_FORMAT, offset);
1894 } else if (frame_size == -1) {
1896 lost_sync_count++; // lost sync count limmitation 2K Bytes
1897 if (lost_sync_count > (1024 * 2)) {
1898 GST_WARNING_OBJECT (aacparse,
1899 "lost_sync_count is larger than 2048");
1903 offset += frame_size;
1905 lost_sync_count = 0;
1909 /* if we can got full file, we can calculate the accurate duration */
1910 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1911 //if (pull_size == file_size) {
1912 if (buffer_size == file_size) {
1913 gfloat duration_for_one_frame = 0;
1914 GstClockTime calculated_duration = GST_CLOCK_TIME_NONE;
1916 GST_INFO_OBJECT (aacparse,
1917 "we got total file (%" G_GINT64_FORMAT
1918 " bytes). do not estimate but make Accurate total duration.",
1921 duration_for_one_frame =
1922 (gfloat) AAC_SAMPLE_PER_FRAME / (gfloat) sample_rate;
1923 calculated_duration =
1924 num_frames * duration_for_one_frame * 1000 * 1000 * 1000;
1926 GST_INFO_OBJECT (aacparse, "duration_for_one_frame %f ms",
1927 duration_for_one_frame);
1928 GST_INFO_OBJECT (aacparse, "calculated duration = %" GST_TIME_FORMAT,
1929 GST_TIME_ARGS (calculated_duration));
1930 /* 0 means disable estimate */
1931 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1932 calculated_duration, 0);
1935 GST_INFO_OBJECT (aacparse,
1936 "we got %" G_GUINT64_FORMAT " bytes in total file (%"
1937 G_GINT64_FORMAT "). can not make accurate duration but Estimate.",
1938 pull_size, file_size);
1940 (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1941 duration = num_frames * frame_duration_us;
1943 if (duration == 0) {
1944 GST_WARNING_OBJECT (aacparse, "Invalid duration");
1948 (gint) ((gfloat) (offset * 8) / (gfloat) (duration / 1000));
1950 if (estimated_bitrate == 0) {
1951 GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1954 estimated_duration =
1955 (GstClockTime) ((file_size * 8) / (estimated_bitrate * 1000)) *
1958 GST_INFO_OBJECT (aacparse, "number of frame = %" G_GINT64_FORMAT,
1960 GST_INFO_OBJECT (aacparse, "duration = %" G_GINT64_FORMAT,
1961 duration / 1000000);
1962 GST_INFO_OBJECT (aacparse, "byte = %" G_GINT64_FORMAT, offset);
1963 GST_INFO_OBJECT (aacparse, "estimated bitrate = %d bps",
1965 GST_INFO_OBJECT (aacparse, "estimated duration = %" GST_TIME_FORMAT,
1966 GST_TIME_ARGS (estimated_duration));
1968 gst_base_parse_set_average_bitrate (parse, estimated_bitrate * 1000);
1969 /* set update_interval as duration(sec)/2 */
1970 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration,
1971 (gint) (duration / 2));
1980 gst_buffer_unmap (buffer, &map);
1981 gst_buffer_unref (buffer);
1986 /* perform seek in push based mode:
1987 find BYTE position to move to based on time and delegate to upstream
1990 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1991 GstPad * pad, GstEvent * event)
1993 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1997 GstSeekType cur_type, stop_type;
2001 gint64 esimate_byte;
2003 gint64 upstream_total_bytes = 0;
2004 GstFormat fmt = GST_FORMAT_BYTES;
2006 GST_INFO_OBJECT (parse, "doing aac push-based seek");
2008 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2011 /* FIXME, always play to the end */
2014 /* only forward streaming and seeking is possible */
2016 goto unsupported_seek;
2019 /* handle rewind only */
2020 cur_type = GST_SEEK_TYPE_SET;
2022 stop_type = GST_SEEK_TYPE_NONE;
2024 flags |= GST_SEEK_FLAG_FLUSH;
2026 /* handle normal seek */
2027 cur_type = GST_SEEK_TYPE_SET;
2028 stop_type = GST_SEEK_TYPE_NONE;
2030 flags |= GST_SEEK_FLAG_FLUSH;
2032 esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
2033 if (aacparse->sample_rate > 0)
2034 frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
2036 goto unsupported_seek;
2038 byte_cur = esimate_byte / (frame_dur);
2040 goto unsupported_seek;
2042 GST_INFO_OBJECT (parse, "frame_byte(%d) spf(%d) rate (%d) ",
2043 aacparse->frame_byte, aacparse->spf, aacparse->sample_rate);
2044 GST_INFO_OBJECT (parse,
2045 "seek cur (%" G_GINT64_FORMAT ") = (%" GST_TIME_FORMAT ") ", cur,
2046 GST_TIME_ARGS (cur));
2047 GST_INFO_OBJECT (parse,
2048 "esimate_byte(%" G_GINT64_FORMAT ") esimate_byte (%d)", esimate_byte,
2052 /* obtain real upstream total bytes */
2053 if (!gst_pad_peer_query_duration (parse->sinkpad, fmt, &upstream_total_bytes))
2054 upstream_total_bytes = 0;
2055 GST_INFO_OBJECT (aacparse,
2056 "gst_pad_query_peer_duration -upstream_total_bytes (%" G_GUINT64_FORMAT
2057 ")", upstream_total_bytes);
2058 aacparse->file_size = upstream_total_bytes;
2060 if ((byte_cur == -1) || (byte_cur > aacparse->file_size)) {
2061 GST_INFO_OBJECT (parse,
2062 "[WEB-ERROR] seek cur (%" G_GINT64_FORMAT ") > file_size (%"
2063 G_GINT64_FORMAT ") ", cur, aacparse->file_size);
2067 GST_INFO_OBJECT (parse,
2068 "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %"
2069 G_GINT64_FORMAT, rate, byte_cur, stop);
2071 if (!(flags & GST_SEEK_FLAG_KEY_UNIT)) {
2072 GST_INFO_OBJECT (parse,
2073 "Requested seek time: %" GST_TIME_FORMAT ", calculated seek offset: %"
2074 G_GUINT64_FORMAT, GST_TIME_ARGS (cur), byte_cur);
2077 /* BYTE seek event */
2079 gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
2081 res = gst_pad_push_event (parse->sinkpad, event);
2089 GST_DEBUG_OBJECT (parse,
2090 "could not determine byte position to seek to, " "seek aborted.");
2096 GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
2103 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
2106 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
2108 ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
2116 * gst_aac_parse_adts_src_eventfunc:
2117 * @parse: #GstBaseParse. #event
2119 * before baseparse handles seek event, make full amr index table.
2121 * Returns: TRUE on success.
2124 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
2126 gboolean handled = FALSE;
2127 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2129 switch (GST_EVENT_TYPE (event)) {
2130 case GST_EVENT_SEEK:
2132 GstFlowReturn res = GST_FLOW_OK;
2133 gint64 base_offset = 0, cur = 0;
2134 gint32 frame_count = 1; /* do not add first frame because it is already in index table */
2135 gint64 second_count = 0; /* initial 1 second */
2136 gint64 total_file_size = 0, start_offset = 0;
2137 GstClockTime current_ts = GST_CLOCK_TIME_NONE;
2138 GstPadMode pad_mode = GST_PAD_MODE_NONE;
2140 /* check baseparse define these fuction */
2141 gst_base_parse_get_pad_mode (parse, &pad_mode);
2142 if (pad_mode != GST_PAD_MODE_PULL) {
2143 gboolean ret = FALSE;
2144 GstPad *srcpad = parse->srcpad;
2145 GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
2147 if (aacparse->byte_seekable)
2148 return gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
2150 GST_INFO_OBJECT (aacparse, "not support byte seek");
2151 goto aac_seek_null_exit;
2154 gst_base_parse_get_upstream_size (parse, &total_file_size);
2155 gst_base_parse_get_index_last_offset (parse, &start_offset);
2156 gst_base_parse_get_index_last_ts (parse, ¤t_ts);
2158 if (total_file_size > AAC_LARGE_FILE_SIZE) {
2159 gst_base_parse_set_seek_mode (parse, 0);
2160 GST_INFO_OBJECT (aacparse, "larger than big size (2MB).");
2161 goto aac_seek_null_exit;
2164 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2166 if (total_file_size == 0 || start_offset >= total_file_size) {
2167 GST_ERROR ("last index offset %" G_GINT64_FORMAT
2168 " is larger than file size %" G_GINT64_FORMAT, start_offset,
2173 gst_event_parse_seek (event, NULL, NULL, NULL, NULL, &cur, NULL, NULL);
2174 if (cur <= current_ts) {
2175 GST_INFO ("seek to %" GST_TIME_FORMAT " within index table %"
2176 GST_TIME_FORMAT ". do not make index table", GST_TIME_ARGS (cur),
2177 GST_TIME_ARGS (current_ts));
2180 GST_INFO ("seek to %" GST_TIME_FORMAT " without index table %"
2181 GST_TIME_FORMAT ". make index table", GST_TIME_ARGS (cur),
2182 GST_TIME_ARGS (current_ts));
2185 GST_INFO ("make AAC(ADTS) Index Table. file_size = %" G_GINT64_FORMAT
2186 " last idx offset=%" G_GINT64_FORMAT ", last idx ts=%"
2187 GST_TIME_FORMAT, total_file_size, start_offset,
2188 GST_TIME_ARGS (current_ts));
2190 base_offset = start_offset; /* set base by start offset */
2191 second_count = current_ts + GST_SECOND; /* 1sec */
2193 /************************************/
2194 /* STEP 0: Setting parse information */
2195 /************************************/
2196 aacparse->spf = aacparse->frame_samples;
2197 aacparse->frame_duration = (aacparse->spf * 1000 * 100) / aacparse->sample_rate; /* duration per frame (msec) */
2198 aacparse->frame_per_sec = (aacparse->sample_rate) / aacparse->spf; /* frames per second (ea) */
2200 /************************************/
2201 /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2202 /************************************/
2203 while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2205 GstBuffer *buffer = NULL;
2208 GST_INFO ("gst_pad_pull_range %d bytes (from %" G_GINT64_FORMAT
2209 ") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2211 gst_pad_pull_range (parse->sinkpad, base_offset,
2212 base_offset + AAC_MAX_PULL_RANGE_BUF, &buffer);
2213 if (res != GST_FLOW_OK) {
2214 GST_ERROR ("gst_pad_pull_range failed!");
2218 gst_buffer_map (buffer, &map, GST_MAP_READ);
2221 gst_buffer_unmap (buffer, &map);
2222 GST_WARNING ("buffer is NULL in make aac seek table's STEP1");
2223 gst_buffer_unref (buffer);
2224 goto aac_seek_null_exit;
2227 while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2228 gint frame_size = 0;
2230 /* make sure the values in the frame header look sane */
2231 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2233 if ((frame_size > 0)
2234 && (frame_size < (AAC_MAX_PULL_RANGE_BUF - offset))) {
2235 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2236 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2237 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2238 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2239 base_offset + offset);
2240 second_count += GST_SECOND; /* 1sec */
2243 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2244 offset += frame_size;
2247 } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2248 GST_DEBUG ("we need refill buffer");
2251 GST_WARNING ("we lost sync");
2257 base_offset = base_offset + offset;
2259 gst_buffer_unmap (buffer, &map);
2260 gst_buffer_unref (buffer);
2261 } /* end MAX buffer cycle */
2263 /*******************************/
2264 /* STEP 2: Remain Buffer cycle */
2265 /*******************************/
2266 if (total_file_size - base_offset > 0) {
2268 GstBuffer *buffer = NULL;
2272 GST_INFO ("gst_pad_pull_range %" G_GINT64_FORMAT " bytes (from %"
2273 G_GINT64_FORMAT ") use remain_buf size",
2274 total_file_size - base_offset, base_offset);
2276 gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size,
2278 if (res != GST_FLOW_OK) {
2279 GST_ERROR ("gst_pad_pull_range failed!");
2283 gst_buffer_map (buffer, &map, GST_MAP_READ);
2286 gst_buffer_unmap (buffer, &map);
2287 GST_WARNING ("buffer is NULL in make aac seek table's STEP2");
2288 gst_buffer_unref (buffer);
2289 goto aac_seek_null_exit;
2292 while (base_offset + offset < total_file_size) {
2293 gint frame_size = 0;
2295 /* make sure the values in the frame header look sane */
2296 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2298 if ((frame_size > 0)
2299 && (frame_size <= (total_file_size - (base_offset + offset)))) {
2300 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2301 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2302 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2303 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2304 base_offset + offset);
2305 second_count += GST_SECOND; /* 1sec */
2308 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2309 offset += frame_size;
2312 } else if (frame_size == 0) {
2313 GST_DEBUG ("Frame size is 0 so, Decoding end..");
2316 GST_WARNING ("we lost sync");
2322 gst_buffer_unmap (buffer, &map);
2323 gst_buffer_unref (buffer);
2325 /* end remain_buf buffer cycle */
2326 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2336 /* call baseparse src_event function to handle event */
2337 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2342 gst_aac_parse_check_byte_seekability (GstBaseParse * parse)
2345 gboolean seekable = FALSE;
2346 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2347 GST_LOG_OBJECT (aacparse, "gst_aac_parse_check_byte_seekability enter");
2349 query = gst_query_new_seeking (GST_FORMAT_BYTES);
2350 if (gst_pad_peer_query (parse->sinkpad, query))
2351 gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
2353 GST_DEBUG_OBJECT (aacparse, "seeking query failed");
2355 gst_query_unref (query);
2357 GST_INFO_OBJECT (aacparse, "byte seekable: %d", seekable);
2359 aacparse->byte_seekable = seekable;
2361 #endif /* TIZEN_FEATURE_AACPARSE_MODIFICATION */