1 /* GStreamer AAC parser plugin
2 * Copyright (C) 2008 Nokia Corporation. All rights reserved.
4 * Contact: Stefan Kost <stefan.kost@nokia.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 * SECTION:element-aacparse
24 * @short_description: AAC parser
25 * @see_also: #GstAmrParse
27 * This is an AAC parser which handles both ADIF and ADTS stream formats.
29 * As ADIF format is not framed, it is not seekable and stream duration cannot
30 * be determined either. However, ADTS format AAC clips can be seeked, and parser
31 * can also estimate playback position and clip duration.
34 * <title>Example launch line</title>
36 * gst-launch-1.0 filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
47 #include <gst/base/gstbitreader.h>
48 #include <gst/pbutils/pbutils.h>
49 #include "gstaacparse.h"
52 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
55 GST_STATIC_CAPS ("audio/mpeg, "
56 "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
57 "stream-format = (string) { raw, adts, adif, loas };"));
59 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
62 GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) { 2, 4 };"));
64 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
65 #define GST_CAT_DEFAULT aacparse_debug
68 #define ADIF_MAX_SIZE 40 /* Should be enough */
69 #define ADTS_MAX_SIZE 10 /* Should be enough */
70 #define LOAS_MAX_SIZE 3 /* Should be enough */
72 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
73 headers prepended during raw to ADTS
76 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION /* to get more accurate duration */
77 #define AAC_MAX_ESTIMATE_DURATION_BUF (1024 * 1024) /* use first 1 Mbyte */
78 #define AAC_SAMPLE_PER_FRAME 1024
80 #define AAC_MAX_PULL_RANGE_BUF (1 * 1024 * 1024) /* 1 MByte */
81 #define AAC_LARGE_FILE_SIZE (2 * 1024 * 1024) /* 2 MByte */
82 #define gst_aac_parse_parent_class parent_class
85 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
87 static const gint loas_sample_rate_table[16] = {
88 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
89 16000, 12000, 11025, 8000, 7350, 0, 0, 0
92 static const gint loas_channels_table[16] = {
93 0, 1, 2, 3, 4, 5, 6, 8,
94 0, 0, 0, 7, 8, 0, 8, 0
97 static gboolean gst_aac_parse_start (GstBaseParse * parse);
98 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
100 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
102 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
105 static GstFlowReturn gst_aac_parse_handle_frame (GstBaseParse * parse,
106 GstBaseParseFrame * frame, gint * skipsize);
107 static GstFlowReturn gst_aac_parse_pre_push_frame (GstBaseParse * parse,
108 GstBaseParseFrame * frame);
109 static gboolean gst_aac_parse_src_event (GstBaseParse * parse,
112 static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
113 aacparse, GstBitReader * br, gint * object_type, gint * sample_rate,
114 gint * channels, gint * frame_samples);
116 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
117 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
118 /* make full aac(adts) index table when seek */
119 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
121 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
123 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
126 #define gst_aac_parse_parent_class parent_class
127 G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
129 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
131 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
133 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
134 32000, 24000, 22050, 16000, 12000, 11025, 8000
137 if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
138 return aac_sample_rates[sr_idx];
139 GST_WARNING ("Invalid sample rate index %u", sr_idx);
144 * gst_aac_parse_class_init:
145 * @klass: #GstAacParseClass.
149 gst_aac_parse_class_init (GstAacParseClass * klass)
151 GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
152 GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
154 GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
155 "AAC audio stream parser");
157 gst_element_class_add_static_pad_template (element_class, &sink_template);
158 gst_element_class_add_static_pad_template (element_class, &src_template);
160 gst_element_class_set_static_metadata (element_class,
161 "AAC audio stream parser", "Codec/Parser/Audio",
162 "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
164 parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
165 parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
166 parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
167 parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_getcaps);
168 parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_handle_frame);
169 parse_class->pre_push_frame =
170 GST_DEBUG_FUNCPTR (gst_aac_parse_pre_push_frame);
171 parse_class->src_event = GST_DEBUG_FUNCPTR (gst_aac_parse_src_event);
176 * gst_aac_parse_init:
177 * @aacparse: #GstAacParse.
178 * @klass: #GstAacParseClass.
182 gst_aac_parse_init (GstAacParse * aacparse)
184 GST_DEBUG ("initialized");
185 GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (aacparse));
186 GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (aacparse));
188 aacparse->last_parsed_sample_rate = 0;
189 aacparse->last_parsed_channels = 0;
190 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
191 /* to get more correct duration */
192 aacparse->first_frame = TRUE;
198 * gst_aac_parse_set_src_caps:
199 * @aacparse: #GstAacParse.
200 * @sink_caps: (proposed) caps of sink pad
202 * Set source pad caps according to current knowledge about the
205 * Returns: TRUE if caps were successfully set.
208 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
211 GstCaps *src_caps = NULL, *allowed;
212 gboolean res = FALSE;
213 const gchar *stream_format;
214 guint8 codec_data[2];
215 guint16 codec_data_data;
216 gint sample_rate_idx;
218 GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
220 src_caps = gst_caps_copy (sink_caps);
222 src_caps = gst_caps_new_empty_simple ("audio/mpeg");
224 gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
225 "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
227 aacparse->output_header_type = aacparse->header_type;
228 switch (aacparse->header_type) {
229 case DSPAAC_HEADER_NONE:
230 stream_format = "raw";
232 case DSPAAC_HEADER_ADTS:
233 stream_format = "adts";
235 case DSPAAC_HEADER_ADIF:
236 stream_format = "adif";
238 case DSPAAC_HEADER_LOAS:
239 stream_format = "loas";
242 stream_format = NULL;
245 /* Generate codec data to be able to set profile/level on the caps */
247 gst_codec_utils_aac_get_index_from_sample_rate (aacparse->sample_rate);
248 if (sample_rate_idx < 0)
249 goto not_a_known_rate;
251 (aacparse->object_type << 11) |
252 (sample_rate_idx << 7) | (aacparse->channels << 3);
253 GST_WRITE_UINT16_BE (codec_data, codec_data_data);
254 gst_codec_utils_aac_caps_set_level_and_profile (src_caps, codec_data, 2);
256 s = gst_caps_get_structure (src_caps, 0);
257 if (aacparse->sample_rate > 0)
258 gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
259 if (aacparse->channels > 0)
260 gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
262 gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
264 allowed = gst_pad_get_allowed_caps (GST_BASE_PARSE (aacparse)->srcpad);
265 if (allowed && !gst_caps_can_intersect (src_caps, allowed)) {
266 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
267 "Caps can not intersect");
268 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
269 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
270 "Input is ADTS, trying raw");
271 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "raw",
273 if (gst_caps_can_intersect (src_caps, allowed)) {
274 GstBuffer *codec_data_buffer;
276 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
277 "Caps can intersect, we will drop the ADTS layer");
278 aacparse->output_header_type = DSPAAC_HEADER_NONE;
280 /* The codec_data data is according to AudioSpecificConfig,
281 ISO/IEC 14496-3, 1.6.2.1 */
282 codec_data_buffer = gst_buffer_new_and_alloc (2);
283 gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
284 gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
285 codec_data_buffer, NULL);
287 } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
288 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
289 "Input is raw, trying ADTS");
290 gst_caps_set_simple (src_caps, "stream-format", G_TYPE_STRING, "adts",
292 if (gst_caps_can_intersect (src_caps, allowed)) {
293 GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
294 "Caps can intersect, we will prepend ADTS headers");
295 aacparse->output_header_type = DSPAAC_HEADER_ADTS;
300 gst_caps_unref (allowed);
302 aacparse->last_parsed_channels = 0;
303 aacparse->last_parsed_sample_rate = 0;
305 GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
307 res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
308 gst_caps_unref (src_caps);
312 GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
313 aacparse->sample_rate);
314 gst_caps_unref (src_caps);
320 * gst_aac_parse_sink_setcaps:
324 * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
326 * Returns: TRUE on success.
329 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
331 GstAacParse *aacparse;
332 GstStructure *structure;
336 aacparse = GST_AAC_PARSE (parse);
337 structure = gst_caps_get_structure (caps, 0);
338 caps_str = gst_caps_to_string (caps);
340 GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
343 /* This is needed at least in case of RTP
344 * Parses the codec_data information to get ObjectType,
345 * number of channels and samplerate */
346 value = gst_structure_get_value (structure, "codec_data");
348 GstBuffer *buf = gst_value_get_buffer (value);
350 if (buf && gst_buffer_get_size (buf) >= 2) {
354 if (!gst_buffer_map (buf, &map, GST_MAP_READ))
356 gst_bit_reader_init (&br, map.data, map.size);
357 gst_aac_parse_read_audio_specific_config (aacparse, &br,
358 &aacparse->object_type, &aacparse->sample_rate, &aacparse->channels,
359 &aacparse->frame_samples);
361 aacparse->header_type = DSPAAC_HEADER_NONE;
362 aacparse->mpegversion = 4;
363 gst_buffer_unmap (buf, &map);
365 GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d, "
366 "samples=%d", aacparse->object_type, aacparse->sample_rate,
367 aacparse->channels, aacparse->frame_samples);
369 /* arrange for metadata and get out of the way */
370 gst_aac_parse_set_src_caps (aacparse, caps);
371 if (aacparse->header_type == aacparse->output_header_type)
372 gst_base_parse_set_passthrough (parse, TRUE);
377 /* caps info overrides */
378 gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
379 gst_structure_get_int (structure, "channels", &aacparse->channels);
381 const gchar *stream_format =
382 gst_structure_get_string (structure, "stream-format");
384 if (g_strcmp0 (stream_format, "raw") == 0) {
385 GST_ERROR_OBJECT (parse, "Need codec_data for raw AAC");
388 aacparse->sample_rate = 0;
389 aacparse->channels = 0;
390 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
391 gst_base_parse_set_passthrough (parse, FALSE);
399 * gst_aac_parse_adts_get_frame_len:
400 * @data: block of data containing an ADTS header.
402 * This function calculates ADTS frame length from the given header.
404 * Returns: size of the ADTS frame.
407 gst_aac_parse_adts_get_frame_len (const guint8 * data)
409 return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
414 * gst_aac_parse_check_adts_frame:
415 * @aacparse: #GstAacParse.
416 * @data: Data to be checked.
417 * @avail: Amount of data passed.
418 * @framesize: If valid ADTS frame was found, this will be set to tell the
419 * found frame size in bytes.
420 * @needed_data: If frame was not found, this may be set to tell how much
421 * more data is needed in the next round to detect the frame
422 * reliably. This may happen when a frame header candidate
423 * is found but it cannot be guaranteed to be the header without
424 * peeking the following data.
426 * Check if the given data contains contains ADTS frame. The algorithm
427 * will examine ADTS frame header and calculate the frame size. Also, another
428 * consecutive ADTS frame header need to be present after the found frame.
429 * Otherwise the data is not considered as a valid ADTS frame. However, this
430 * "extra check" is omitted when EOS has been received. In this case it is
431 * enough when data[0] contains a valid ADTS header.
433 * This function may set the #needed_data to indicate that a possible frame
434 * candidate has been found, but more data (#needed_data bytes) is needed to
435 * be absolutely sure. When this situation occurs, FALSE will be returned.
437 * When a valid frame is detected, this function will use
438 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
439 * to set the needed bytes for next frame.This way next data chunk is already
442 * Returns: TRUE if the given data contains a valid ADTS header.
445 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
446 const guint8 * data, const guint avail, gboolean drain,
447 guint * framesize, guint * needed_data)
453 /* Absolute minimum to perform the ADTS syncword,
454 layer and sampling frequency tests */
455 if (G_UNLIKELY (avail < 3)) {
460 /* Syncword and layer tests */
461 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
463 /* Sampling frequency test */
464 if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
467 /* This looks like an ADTS frame header but
468 we need at least 6 bytes to proceed */
469 if (G_UNLIKELY (avail < 6)) {
474 *framesize = gst_aac_parse_adts_get_frame_len (data);
476 /* If frame has CRC, it needs 2 bytes
477 for it at the end of the header */
478 crc_size = (data[1] & 0x01) ? 0 : 2;
481 if (*framesize < 7 + crc_size) {
482 *needed_data = 7 + crc_size;
486 /* In EOS mode this is enough. No need to examine the data further.
487 We also relax the check when we have sync, on the assumption that
488 if we're not looking at random data, we have a much higher chance
489 to get the correct sync, and this avoids losing two frames when
490 a single bit corruption happens. */
491 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
495 if (*framesize + ADTS_MAX_SIZE > avail) {
496 /* We have found a possible frame header candidate, but can't be
497 sure since we don't have enough data to check the next frame */
498 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
499 *framesize + ADTS_MAX_SIZE, avail);
500 *needed_data = *framesize + ADTS_MAX_SIZE;
501 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
502 *framesize + ADTS_MAX_SIZE);
506 if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
507 guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
509 GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
510 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
511 nextlen + ADTS_MAX_SIZE);
519 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
522 guint8 bytes, i, byte;
525 if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
527 for (i = 0; i <= bytes; ++i) {
529 if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
537 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
538 guint8 * audio_object_type)
540 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
542 if (*audio_object_type == 31) {
543 if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
545 *audio_object_type += 32;
547 GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
552 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
555 guint8 sampling_frequency_index;
556 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
558 GST_LOG_OBJECT (aacparse, "sampling_frequency_index: %u",
559 sampling_frequency_index);
560 if (sampling_frequency_index == 0xf) {
561 guint32 sampling_rate;
562 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
564 *sample_rate = sampling_rate;
566 *sample_rate = loas_sample_rate_table[sampling_frequency_index];
570 aacparse->last_parsed_sample_rate = *sample_rate;
574 /* See table 1.13 in ISO/IEC 14496-3 */
576 gst_aac_parse_read_audio_specific_config (GstAacParse * aacparse,
577 GstBitReader * br, gint * object_type, gint * sample_rate, gint * channels,
578 gint * frame_samples)
580 guint8 audio_object_type;
581 guint8 G_GNUC_UNUSED extension_audio_object_type;
582 guint8 channel_configuration, extension_channel_configuration;
583 gboolean G_GNUC_UNUSED sbr = FALSE, ps = FALSE;
585 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
588 *object_type = audio_object_type;
590 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
593 if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
595 *channels = loas_channels_table[channel_configuration];
596 GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
600 if (audio_object_type == 5 || audio_object_type == 29) {
601 extension_audio_object_type = 5;
603 if (audio_object_type == 29) {
605 /* Parametric stereo. If we have a one-channel configuration, we can
606 * override it to stereo */
611 GST_LOG_OBJECT (aacparse,
612 "Audio object type 5 or 29, so rereading sampling rate (was %d)...",
614 if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
617 if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
620 if (audio_object_type == 22) {
621 /* extension channel configuration */
622 if (!gst_bit_reader_get_bits_uint8 (br, &extension_channel_configuration,
625 GST_LOG_OBJECT (aacparse, "extension channel_configuration: %d",
626 extension_channel_configuration);
627 *channels = loas_channels_table[extension_channel_configuration];
632 extension_audio_object_type = 0;
635 GST_INFO_OBJECT (aacparse, "Parsed AudioSpecificConfig: %d Hz, %d channels",
636 *sample_rate, *channels);
638 if (frame_samples && audio_object_type == 23) {
640 /* Read the Decoder Configuration (GASpecificConfig) if present */
641 /* We only care about the first bit to know what the number of samples
643 if (!gst_bit_reader_get_bits_uint8 (br, &frame_flag, 1))
645 *frame_samples = frame_flag ? 960 : 1024;
648 /* There's LOTS of stuff next, but we ignore it for now as we have
649 what we want (sample rate and number of channels */
650 GST_DEBUG_OBJECT (aacparse,
651 "Need more code to parse humongous LOAS data, currently ignored");
652 aacparse->last_parsed_channels = *channels;
658 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
659 guint avail, gint * sample_rate, gint * channels, gint * version)
664 /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
668 gst_bit_reader_init (&br, data, avail);
670 /* skip sync word (11 bits) and size (13 bits) */
671 if (!gst_bit_reader_skip (&br, 11 + 13))
674 /* First bit is "use last config" */
675 if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
678 GST_LOG_OBJECT (aacparse, "Frame uses previous config");
679 if (!aacparse->last_parsed_sample_rate || !aacparse->last_parsed_channels) {
680 GST_DEBUG_OBJECT (aacparse,
681 "No previous config to use. We'll look for more data.");
684 *sample_rate = aacparse->last_parsed_sample_rate;
685 *channels = aacparse->last_parsed_channels;
689 GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
691 /* audioMuxVersion */
692 if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
695 /* audioMuxVersionA */
696 if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
701 GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
703 guint8 same_time, subframes, num_program, prog;
706 /* taraBufferFullness */
707 if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
710 if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
712 if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
714 if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
716 GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
717 same_time, subframes, num_program);
719 for (prog = 0; prog <= num_program; ++prog) {
720 guint8 num_layer, layer;
721 if (!gst_bit_reader_get_bits_uint8 (&br, &num_layer, 3))
723 GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
725 for (layer = 0; layer <= num_layer; ++layer) {
726 guint8 use_same_config;
727 if (prog == 0 && layer == 0) {
730 if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
733 if (!use_same_config) {
735 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
736 sample_rate, channels, NULL))
740 if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
742 if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
743 sample_rate, channels, NULL))
745 if (!gst_bit_reader_skip (&br, asc_len))
751 GST_LOG_OBJECT (aacparse, "More data ignored");
753 GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
760 * gst_aac_parse_loas_get_frame_len:
761 * @data: block of data containing a LOAS header.
763 * This function calculates LOAS frame length from the given header.
765 * Returns: size of the LOAS frame.
768 gst_aac_parse_loas_get_frame_len (const guint8 * data)
770 return (((data[1] & 0x1f) << 8) | data[2]) + 3;
775 * gst_aac_parse_check_loas_frame:
776 * @aacparse: #GstAacParse.
777 * @data: Data to be checked.
778 * @avail: Amount of data passed.
779 * @framesize: If valid LOAS frame was found, this will be set to tell the
780 * found frame size in bytes.
781 * @needed_data: If frame was not found, this may be set to tell how much
782 * more data is needed in the next round to detect the frame
783 * reliably. This may happen when a frame header candidate
784 * is found but it cannot be guaranteed to be the header without
785 * peeking the following data.
787 * Check if the given data contains contains LOAS frame. The algorithm
788 * will examine LOAS frame header and calculate the frame size. Also, another
789 * consecutive LOAS frame header need to be present after the found frame.
790 * Otherwise the data is not considered as a valid LOAS frame. However, this
791 * "extra check" is omitted when EOS has been received. In this case it is
792 * enough when data[0] contains a valid LOAS header.
794 * This function may set the #needed_data to indicate that a possible frame
795 * candidate has been found, but more data (#needed_data bytes) is needed to
796 * be absolutely sure. When this situation occurs, FALSE will be returned.
798 * When a valid frame is detected, this function will use
799 * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
800 * to set the needed bytes for next frame.This way next data chunk is already
803 * LOAS can have three different formats, if I read the spec correctly. Only
804 * one of them is supported here, as the two samples I have use this one.
806 * Returns: TRUE if the given data contains a valid LOAS header.
809 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
810 const guint8 * data, const guint avail, gboolean drain,
811 guint * framesize, guint * needed_data)
816 if (G_UNLIKELY (avail < 3)) {
821 if ((data[0] == 0x56) && ((data[1] & 0xe0) == 0xe0)) {
822 *framesize = gst_aac_parse_loas_get_frame_len (data);
823 GST_DEBUG_OBJECT (aacparse, "Found possible %u byte LOAS frame",
826 /* In EOS mode this is enough. No need to examine the data further.
827 We also relax the check when we have sync, on the assumption that
828 if we're not looking at random data, we have a much higher chance
829 to get the correct sync, and this avoids losing two frames when
830 a single bit corruption happens. */
831 if (drain || !GST_BASE_PARSE_LOST_SYNC (aacparse)) {
835 if (*framesize + LOAS_MAX_SIZE > avail) {
836 /* We have found a possible frame header candidate, but can't be
837 sure since we don't have enough data to check the next frame */
838 GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
839 *framesize + LOAS_MAX_SIZE, avail);
840 *needed_data = *framesize + LOAS_MAX_SIZE;
841 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
842 *framesize + LOAS_MAX_SIZE);
846 if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
847 guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
849 GST_LOG ("LOAS frame found, len: %d bytes", *framesize);
850 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
851 nextlen + LOAS_MAX_SIZE);
854 GST_DEBUG_OBJECT (aacparse, "That was a false positive");
860 /* caller ensure sufficient data */
862 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
863 gint * rate, gint * channels, gint * object, gint * version)
867 gint sr_idx = (data[2] & 0x3c) >> 2;
869 *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
872 *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
878 *version = (data[1] & 0x08) ? 2 : 4;
880 *object = ((data[2] & 0xc0) >> 6) + 1;
884 * gst_aac_parse_detect_stream:
885 * @aacparse: #GstAacParse.
886 * @data: A block of data that needs to be examined for stream characteristics.
887 * @avail: Size of the given datablock.
888 * @framesize: If valid stream was found, this will be set to tell the
889 * first frame size in bytes.
890 * @skipsize: If valid stream was found, this will be set to tell the first
891 * audio frame position within the given data.
893 * Examines the given piece of data and try to detect the format of it. It
894 * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
895 * header. If the stream is detected, TRUE will be returned and #framesize
896 * is set to indicate the found frame size. Additionally, #skipsize might
897 * be set to indicate the number of bytes that need to be skipped, a.k.a. the
898 * position of the frame inside given data chunk.
900 * Returns: TRUE on success.
903 gst_aac_parse_detect_stream (GstAacParse * aacparse,
904 const guint8 * data, const guint avail, gboolean drain,
905 guint * framesize, gint * skipsize)
907 gboolean found = FALSE;
908 guint need_data_adts = 0, need_data_loas;
911 GST_DEBUG_OBJECT (aacparse, "Parsing header data");
913 /* FIXME: No need to check for ADIF if we are not in the beginning of the
916 /* Can we even parse the header? */
917 if (avail < MAX (ADTS_MAX_SIZE, LOAS_MAX_SIZE)) {
918 GST_DEBUG_OBJECT (aacparse, "Not enough data to check");
922 for (i = 0; i < avail - 4; i++) {
923 if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
924 ((data[i] == 0x56) && ((data[i + 1] & 0xe0) == 0xe0)) ||
925 strncmp ((char *) data + i, "ADIF", 4) == 0) {
926 GST_DEBUG_OBJECT (aacparse, "Found signature at offset %u", i);
930 /* Trick: tell the parent class that we didn't find the frame yet,
931 but make it skip 'i' amount of bytes. Next time we arrive
932 here we have full frame in the beginning of the data. */
945 if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
946 framesize, &need_data_adts)) {
949 GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
951 gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
952 &aacparse->object_type, &aacparse->mpegversion);
954 if (!channels || !framesize) {
955 GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
959 aacparse->header_type = DSPAAC_HEADER_ADTS;
960 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
961 aacparse->frame_samples, 2, 2);
963 GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
964 rate, channels, aacparse->object_type, aacparse->mpegversion);
966 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
971 if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
972 framesize, &need_data_loas)) {
973 gint rate = 0, channels = 0;
975 GST_INFO ("LOAS, framesize: %d", *framesize);
977 aacparse->header_type = DSPAAC_HEADER_LOAS;
979 if (!gst_aac_parse_read_loas_config (aacparse, data, avail, &rate,
980 &channels, &aacparse->mpegversion)) {
981 /* This is pretty normal when skipping data at the start of
982 * random stream (MPEG-TS capture for example) */
983 GST_LOG_OBJECT (aacparse, "Error reading LOAS config");
987 if (rate && channels) {
988 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
989 aacparse->frame_samples, 2, 2);
991 /* Don't store the sample rate and channels yet -
992 * this is just format detection. */
993 GST_DEBUG ("LOAS: samplerate %d, channels %d, objtype %d, version %d",
994 rate, channels, aacparse->object_type, aacparse->mpegversion);
997 gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
1002 if (need_data_adts || need_data_loas) {
1003 /* This tells the parent class not to skip any data */
1008 if (avail < ADIF_MAX_SIZE)
1011 if (memcmp (data + i, "ADIF", 4) == 0) {
1018 aacparse->header_type = DSPAAC_HEADER_ADIF;
1019 aacparse->mpegversion = 4;
1021 /* Skip the "ADIF" bytes */
1022 adif = data + i + 4;
1024 /* copyright string */
1026 skip_size += 9; /* skip 9 bytes */
1028 bitstream_type = adif[0 + skip_size] & 0x10;
1030 ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
1031 ((unsigned int) adif[1 + skip_size] << 11) |
1032 ((unsigned int) adif[2 + skip_size] << 3) |
1033 ((unsigned int) adif[3 + skip_size] & 0xe0);
1036 if (bitstream_type == 0) {
1038 /* Buffer fullness parsing. Currently not needed... */
1039 guint num_elems = 0;
1042 num_elems = (adif[3 + skip_size] & 0x1e);
1043 GST_INFO ("ADIF num_config_elems: %d", num_elems);
1045 fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
1046 ((unsigned int) adif[4 + skip_size] << 11) |
1047 ((unsigned int) adif[5 + skip_size] << 3) |
1048 ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
1050 GST_INFO ("ADIF buffer fullness: %d", fullness);
1052 aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
1053 ((adif[7 + skip_size] & 0x80) >> 7);
1054 sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
1058 aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
1059 sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
1060 ((adif[5 + skip_size] & 0x80) >> 7);
1063 /* FIXME: This gives totally wrong results. Duration calculation cannot
1065 aacparse->sample_rate =
1066 gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1068 /* baseparse is not given any fps,
1069 * so it will give up on timestamps, seeking, etc */
1071 /* FIXME: Can we assume this? */
1072 aacparse->channels = 2;
1074 GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1075 aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1077 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1079 /* arrange for metadata and get out of the way */
1080 sinkcaps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (aacparse));
1081 gst_aac_parse_set_src_caps (aacparse, sinkcaps);
1083 gst_caps_unref (sinkcaps);
1085 /* not syncable, not easily seekable (unless we push data from start */
1086 gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
1087 gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
1088 gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
1094 /* This should never happen */
1099 * gst_aac_parse_get_audio_profile_object_type
1100 * @aacparse: #GstAacParse.
1102 * Gets the MPEG-2 profile or the MPEG-4 object type value corresponding to the
1103 * mpegversion and profile of @aacparse's src pad caps, according to the
1104 * values defined by table 1.A.11 in ISO/IEC 14496-3.
1106 * Returns: the profile or object type value corresponding to @aacparse's src
1107 * pad caps, if such a value exists; otherwise G_MAXUINT8.
1110 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1113 GstStructure *srcstruct;
1114 const gchar *profile;
1117 srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1118 if (G_UNLIKELY (srccaps == NULL)) {
1122 srcstruct = gst_caps_get_structure (srccaps, 0);
1123 profile = gst_structure_get_string (srcstruct, "profile");
1124 if (G_UNLIKELY (profile == NULL)) {
1125 gst_caps_unref (srccaps);
1129 if (g_strcmp0 (profile, "main") == 0) {
1131 } else if (g_strcmp0 (profile, "lc") == 0) {
1133 } else if (g_strcmp0 (profile, "ssr") == 0) {
1135 } else if (g_strcmp0 (profile, "ltp") == 0) {
1136 if (G_LIKELY (aacparse->mpegversion == 4))
1139 ret = G_MAXUINT8; /* LTP Object Type allowed only for MPEG-4 */
1144 gst_caps_unref (srccaps);
1149 * gst_aac_parse_get_audio_channel_configuration
1150 * @num_channels: number of audio channels.
1152 * Gets the Channel Configuration value, as defined by table 1.19 in ISO/IEC
1153 * 14496-3, for a given number of audio channels.
1155 * Returns: the Channel Configuration value corresponding to @num_channels, if
1156 * such a value exists; otherwise G_MAXUINT8.
1159 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1161 if (num_channels >= 1 && num_channels <= 6) /* Mono up to & including 5.1 */
1162 return (guint8) num_channels;
1163 else if (num_channels == 8) /* 7.1 */
1168 /* FIXME: Add support for configurations 11, 12 and 14 from
1169 * ISO/IEC 14496-3:2009/PDAM 4 based on the actual channel layout
1174 * gst_aac_parse_get_audio_sampling_frequency_index:
1175 * @sample_rate: audio sampling rate.
1177 * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1178 * 14496-3, for a given sampling rate.
1180 * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1181 * if such a value exists; otherwise G_MAXUINT8.
1184 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1186 switch (sample_rate) {
1219 * gst_aac_parse_prepend_adts_headers:
1220 * @aacparse: #GstAacParse.
1221 * @frame: raw AAC frame to which ADTS headers shall be prepended.
1223 * Prepends ADTS headers to a raw AAC audio frame.
1225 * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1228 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1229 GstBaseParseFrame * frame)
1232 guint8 *adts_headers;
1235 guint8 id, profile, channel_configuration, sampling_frequency_index;
1237 id = (aacparse->mpegversion == 4) ? 0x0U : 0x1U;
1238 profile = gst_aac_parse_get_audio_profile_object_type (aacparse);
1239 if (profile == G_MAXUINT8) {
1240 GST_ERROR_OBJECT (aacparse, "Unsupported audio profile or object type");
1243 channel_configuration =
1244 gst_aac_parse_get_audio_channel_configuration (aacparse->channels);
1245 if (channel_configuration == G_MAXUINT8) {
1246 GST_ERROR_OBJECT (aacparse, "Unsupported number of channels");
1249 sampling_frequency_index =
1250 gst_aac_parse_get_audio_sampling_frequency_index (aacparse->sample_rate);
1251 if (sampling_frequency_index == G_MAXUINT8) {
1252 GST_ERROR_OBJECT (aacparse, "Unsupported sampling frequency");
1256 frame->out_buffer = gst_buffer_copy (frame->buffer);
1257 buf_size = gst_buffer_get_size (frame->out_buffer);
1258 frame_size = buf_size + ADTS_HEADERS_LENGTH;
1260 if (G_UNLIKELY (frame_size >= 0x4000)) {
1261 GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1265 adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1267 /* Note: no error correction bits are added to the resulting ADTS frames */
1268 adts_headers[0] = 0xFFU;
1269 adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
1270 adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
1271 (channel_configuration & 0x4U);
1272 adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
1273 (guint8) (frame_size >> 11);
1274 adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
1275 adts_headers[5] = (guint8) (((frame_size & 0x0007) << 5) + 0x1FU);
1276 adts_headers[6] = 0xFCU;
1278 mem = gst_memory_new_wrapped (0, adts_headers, ADTS_HEADERS_LENGTH, 0,
1279 ADTS_HEADERS_LENGTH, adts_headers, g_free);
1280 gst_buffer_prepend_memory (frame->out_buffer, mem);
1286 * gst_aac_parse_check_valid_frame:
1287 * @parse: #GstBaseParse.
1288 * @frame: #GstBaseParseFrame.
1289 * @skipsize: How much data parent class should skip in order to find the
1292 * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1294 * Also determines frame overhead.
1295 * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
1296 * a per-frame header. LOAS has 3 bytes.
1298 * We're making a couple of simplifying assumptions:
1300 * 1. We count Program Configuration Elements rather than searching for them
1301 * in the streams to discount them - the overhead is negligible.
1303 * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
1304 * bits, which should still not be significant enough to warrant the
1305 * additional parsing through the headers
1307 * Returns: a #GstFlowReturn.
1309 static GstFlowReturn
1310 gst_aac_parse_handle_frame (GstBaseParse * parse,
1311 GstBaseParseFrame * frame, gint * skipsize)
1314 GstAacParse *aacparse;
1315 gboolean ret = FALSE;
1319 gint rate = 0, channels = 0;
1321 aacparse = GST_AAC_PARSE (parse);
1322 buffer = frame->buffer;
1324 gst_buffer_map (buffer, &map, GST_MAP_READ);
1327 lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1329 if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
1330 aacparse->header_type == DSPAAC_HEADER_NONE) {
1331 /* There is nothing to parse */
1332 framesize = map.size;
1335 } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1337 ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1338 GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1340 } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1341 guint needed_data = 1024;
1343 ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1344 GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1346 if (!ret && needed_data) {
1347 GST_DEBUG ("buffer didn't contain valid frame");
1349 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1353 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1354 guint needed_data = 1024;
1356 ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1357 map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1359 if (!ret && needed_data) {
1360 GST_DEBUG ("buffer didn't contain valid frame");
1362 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1367 GST_DEBUG ("buffer didn't contain valid frame");
1368 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1372 if (G_UNLIKELY (!ret))
1375 if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1377 frame->overhead = 7;
1379 gst_aac_parse_parse_adts_header (aacparse, map.data,
1380 &rate, &channels, NULL, NULL);
1382 GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1384 if (G_UNLIKELY (rate != aacparse->sample_rate
1385 || channels != aacparse->channels)) {
1386 aacparse->sample_rate = rate;
1387 aacparse->channels = channels;
1389 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1390 /* If linking fails, we need to return appropriate error */
1391 ret = GST_FLOW_NOT_LINKED;
1394 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1395 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1397 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1398 if (aacparse->first_frame == TRUE) {
1399 gboolean ret = FALSE;
1400 aacparse->first_frame = FALSE;
1402 ret = gst_aac_parse_estimate_duration (parse);
1404 GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1405 ret = GST_FLOW_NOT_SUPPORTED;
1409 } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1410 gboolean setcaps = FALSE;
1413 frame->overhead = 3;
1415 if (!gst_aac_parse_read_loas_config (aacparse, map.data, map.size, &rate,
1416 &channels, NULL) || !rate || !channels) {
1417 /* This is pretty normal when skipping data at the start of
1418 * random stream (MPEG-TS capture for example) */
1419 GST_DEBUG_OBJECT (aacparse, "Error reading LOAS config. Skipping.");
1420 /* Since we don't fully parse the LOAS config, we don't know for sure
1421 * how much to skip. Just skip 1 to end up to the next marker and
1422 * resume parsing from there */
1427 if (G_UNLIKELY (rate != aacparse->sample_rate
1428 || channels != aacparse->channels)) {
1429 aacparse->sample_rate = rate;
1430 aacparse->channels = channels;
1432 GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1436 /* We want to set caps both at start, and when rate/channels change.
1437 Since only some LOAS frames have that info, we may receive frames
1438 before knowing about rate/channels. */
1440 || !gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse))) {
1441 if (!gst_aac_parse_set_src_caps (aacparse, NULL)) {
1442 /* If linking fails, we need to return appropriate error */
1443 ret = GST_FLOW_NOT_LINKED;
1446 gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1447 aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1450 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1451 else if (aacparse->header_type == DSPAAC_HEADER_ADIF) {
1452 /* to get more correct duration */
1453 float estimated_duration = 0;
1454 gint64 total_file_size;
1455 gst_base_parse_get_upstream_size (parse, &total_file_size);
1456 estimated_duration =
1457 ((total_file_size * 8) / (float) (aacparse->bitrate * 1000)) *
1459 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1460 estimated_duration * 1000, 0);
1464 if (aacparse->header_type == DSPAAC_HEADER_NONE
1465 && aacparse->output_header_type == DSPAAC_HEADER_ADTS) {
1466 if (!gst_aac_parse_prepend_adts_headers (aacparse, frame)) {
1467 GST_ERROR_OBJECT (aacparse, "Failed to prepend ADTS headers to frame");
1468 ret = GST_FLOW_ERROR;
1473 gst_buffer_unmap (buffer, &map);
1476 /* found, skip if needed */
1485 if (ret && framesize <= map.size) {
1486 return gst_base_parse_finish_frame (parse, frame, framesize);
1492 static GstFlowReturn
1493 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1495 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1497 if (!aacparse->sent_codec_tag) {
1498 GstTagList *taglist;
1502 caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1504 if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
1505 GST_INFO_OBJECT (parse, "Src pad is flushing");
1506 return GST_FLOW_FLUSHING;
1508 GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1509 return GST_FLOW_NOT_NEGOTIATED;
1513 taglist = gst_tag_list_new_empty ();
1514 gst_pb_utils_add_codec_description_to_tag_list (taglist,
1515 GST_TAG_AUDIO_CODEC, caps);
1516 gst_caps_unref (caps);
1518 gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1519 gst_tag_list_unref (taglist);
1521 /* also signals the end of first-frame processing */
1522 aacparse->sent_codec_tag = TRUE;
1525 /* As a special case, we can remove the ADTS framing and output raw AAC. */
1526 if (aacparse->header_type == DSPAAC_HEADER_ADTS
1527 && aacparse->output_header_type == DSPAAC_HEADER_NONE) {
1530 frame->out_buffer = gst_buffer_make_writable (frame->buffer);
1531 frame->buffer = NULL;
1532 gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ);
1533 header_size = (map.data[1] & 1) ? 7 : 9; /* optional CRC */
1534 gst_buffer_unmap (frame->out_buffer, &map);
1535 gst_buffer_resize (frame->out_buffer, header_size,
1536 gst_buffer_get_size (frame->out_buffer) - header_size);
1544 * gst_aac_parse_start:
1545 * @parse: #GstBaseParse.
1547 * Implementation of "start" vmethod in #GstBaseParse class.
1549 * Returns: TRUE if startup succeeded.
1552 gst_aac_parse_start (GstBaseParse * parse)
1554 GstAacParse *aacparse;
1556 aacparse = GST_AAC_PARSE (parse);
1557 GST_DEBUG ("start");
1558 aacparse->frame_samples = 1024;
1559 gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), ADTS_MAX_SIZE);
1560 aacparse->sent_codec_tag = FALSE;
1561 aacparse->last_parsed_channels = 0;
1562 aacparse->last_parsed_sample_rate = 0;
1563 aacparse->object_type = 0;
1564 aacparse->bitrate = 0;
1565 aacparse->header_type = DSPAAC_HEADER_NOT_PARSED;
1566 aacparse->output_header_type = DSPAAC_HEADER_NOT_PARSED;
1567 aacparse->channels = 0;
1568 aacparse->sample_rate = 0;
1574 * gst_aac_parse_stop:
1575 * @parse: #GstBaseParse.
1577 * Implementation of "stop" vmethod in #GstBaseParse class.
1579 * Returns: TRUE is stopping succeeded.
1582 gst_aac_parse_stop (GstBaseParse * parse)
1589 remove_fields (GstCaps * caps)
1593 n = gst_caps_get_size (caps);
1594 for (i = 0; i < n; i++) {
1595 GstStructure *s = gst_caps_get_structure (caps, i);
1597 gst_structure_remove_field (s, "framed");
1602 add_conversion_fields (GstCaps * caps)
1606 n = gst_caps_get_size (caps);
1607 for (i = 0; i < n; i++) {
1608 GstStructure *s = gst_caps_get_structure (caps, i);
1610 if (gst_structure_has_field (s, "stream-format")) {
1611 const GValue *v = gst_structure_get_value (s, "stream-format");
1613 if (G_VALUE_HOLDS_STRING (v)) {
1614 const gchar *str = g_value_get_string (v);
1616 if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1617 GValue va = G_VALUE_INIT;
1618 GValue vs = G_VALUE_INIT;
1620 g_value_init (&va, GST_TYPE_LIST);
1621 g_value_init (&vs, G_TYPE_STRING);
1622 g_value_set_string (&vs, "adts");
1623 gst_value_list_append_value (&va, &vs);
1624 g_value_set_string (&vs, "raw");
1625 gst_value_list_append_value (&va, &vs);
1626 gst_structure_set_value (s, "stream-format", &va);
1627 g_value_unset (&va);
1628 g_value_unset (&vs);
1630 } else if (GST_VALUE_HOLDS_LIST (v)) {
1631 gboolean contains_raw = FALSE;
1632 gboolean contains_adts = FALSE;
1633 guint m = gst_value_list_get_size (v), j;
1635 for (j = 0; j < m; j++) {
1636 const GValue *ve = gst_value_list_get_value (v, j);
1639 if (G_VALUE_HOLDS_STRING (ve) && (str = g_value_get_string (ve))) {
1640 if (strcmp (str, "adts") == 0)
1641 contains_adts = TRUE;
1642 else if (strcmp (str, "raw") == 0)
1643 contains_raw = TRUE;
1647 if (contains_adts || contains_raw) {
1648 GValue va = G_VALUE_INIT;
1649 GValue vs = G_VALUE_INIT;
1651 g_value_init (&va, GST_TYPE_LIST);
1652 g_value_init (&vs, G_TYPE_STRING);
1653 g_value_copy (v, &va);
1655 if (!contains_raw) {
1656 g_value_set_string (&vs, "raw");
1657 gst_value_list_append_value (&va, &vs);
1659 if (!contains_adts) {
1660 g_value_set_string (&vs, "adts");
1661 gst_value_list_append_value (&va, &vs);
1664 gst_structure_set_value (s, "stream-format", &va);
1666 g_value_unset (&vs);
1667 g_value_unset (&va);
1675 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1677 GstCaps *peercaps, *templ;
1680 templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1683 GstCaps *fcopy = gst_caps_copy (filter);
1684 /* Remove the fields we convert */
1685 remove_fields (fcopy);
1686 add_conversion_fields (fcopy);
1687 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
1688 gst_caps_unref (fcopy);
1690 peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1693 peercaps = gst_caps_make_writable (peercaps);
1694 /* Remove the fields we convert */
1695 remove_fields (peercaps);
1696 add_conversion_fields (peercaps);
1698 res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1699 gst_caps_unref (peercaps);
1700 gst_caps_unref (templ);
1706 GstCaps *intersection;
1709 gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1710 gst_caps_unref (res);
1718 gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1720 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1722 if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1723 aacparse->last_parsed_channels = 0;
1724 aacparse->last_parsed_sample_rate = 0;
1726 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1727 GST_DEBUG ("Entering gst_aac_parse_src_event header type = %d",
1728 aacparse->header_type);
1729 if (aacparse->header_type == DSPAAC_HEADER_ADTS)
1730 return gst_aac_parse_adts_src_eventfunc (parse, event);
1732 return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1736 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1738 * get_aac_parse_get_adts_framelength:
1739 * @data: #GstBufferData.
1740 * @offset: #GstBufferData offset
1742 * Implementation to get adts framelength by using first some frame.
1744 * Returns: frame size
1747 get_aac_parse_get_adts_frame_length (const unsigned char *data, gint64 offset)
1749 const gint adts_header_length_no_crc = 7;
1750 const gint adts_header_length_with_crc = 9;
1751 gint frame_size = 0;
1752 gint protection_absent;
1755 /* check of syncword */
1756 if ((data[offset + 0] != 0xff) || ((data[offset + 1] & 0xf6) != 0xf0)) {
1757 GST_ERROR ("check sync word is fail\n");
1761 /* check of protection absent */
1762 protection_absent = (data[offset + 1] & 0x01);
1764 /*check of frame length */
1766 (data[offset + 3] & 0x3) << 11 | data[offset + 4] << 3 | data[offset +
1769 /* check of header size */
1770 /* protectionAbsent is 0 if there is CRC */
1772 protection_absent ? adts_header_length_no_crc :
1773 adts_header_length_with_crc;
1774 if (head_size > frame_size) {
1775 GST_ERROR ("return frame length as 0 (frameSize %u < headSize %u)",
1776 frame_size, head_size);
1784 * gst_aac_parse_estimate_duration:
1785 * @parse: #GstBaseParse.
1787 * Implementation to get estimated total duration by using first some frame.
1789 * Returns: TRUE if we can get estimated total duraion
1792 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1794 gboolean ret = FALSE;
1795 GstFlowReturn res = GST_FLOW_OK;
1796 gint64 pull_size = 0, file_size = 0, offset = 0, num_frames = 0, duration = 0;
1797 guint sample_rate_index = 0, sample_rate = 0, channel = 0;
1798 guint frame_size = 0, frame_duration_us = 0, estimated_bitrate = 0;
1799 guint lost_sync_count = 0;
1800 GstClockTime estimated_duration = GST_CLOCK_TIME_NONE;
1801 GstBuffer *buffer = NULL;
1804 GstPadMode pad_mode = GST_PAD_MODE_NONE;
1805 GstAacParse *aacparse;
1806 gint64 buffer_size = 0;
1809 aacparse = GST_AAC_PARSE (parse);
1810 GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1812 /* check baseparse define these fuction */
1813 gst_base_parse_get_pad_mode (parse, &pad_mode);
1814 if (pad_mode != GST_PAD_MODE_PULL) {
1815 GST_INFO_OBJECT (aacparse,
1816 "aac parser is not pull mode. can not estimate duration");
1820 gst_base_parse_get_upstream_size (parse, &file_size);
1822 if (file_size < ADIF_MAX_SIZE) {
1823 GST_ERROR_OBJECT (aacparse, "file size is too short");
1827 pull_size = MIN (file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1829 res = gst_pad_pull_range (parse->sinkpad, 0, pull_size, &buffer);
1830 if (res != GST_FLOW_OK) {
1831 GST_ERROR_OBJECT (aacparse, "gst_pad_pull_range failed!");
1835 gst_buffer_map (buffer, &map, GST_MAP_READ);
1837 buffer_size = map.size;
1838 if (buffer_size != pull_size) {
1839 GST_ERROR_OBJECT (aacparse,
1840 "We got different buffer_size(%" G_GINT64_FORMAT ") with pull_size(%"
1841 G_GINT64_FORMAT ").", buffer_size, pull_size);
1844 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1845 for (i = 0; i < buffer_size; i++) {
1846 if ((buf[i] == 0xff) && ((buf[i + 1] & 0xf6) == 0xf0)) { /* aac sync word */
1847 //guint profile = (buf[i+2] >> 6) & 0x3;
1848 sample_rate_index = (buf[i + 2] >> 2) & 0xf;
1850 gst_aac_parse_get_sample_rate_from_index (sample_rate_index);
1851 if (sample_rate == 0) {
1852 GST_WARNING_OBJECT (aacparse, "Invalid sample rate index (0)");
1855 channel = (buf[i + 2] & 0x1) << 2 | (buf[i + 3] >> 6);
1857 GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate,
1860 /* count number of frames */
1861 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1862 //while (offset < pull_size) {
1863 while (offset < buffer_size) {
1864 frame_size = get_aac_parse_get_adts_frame_length (buf, i + offset);
1865 if (frame_size == 0) {
1866 GST_ERROR_OBJECT (aacparse,
1867 "framesize error at offset %" G_GINT64_FORMAT, offset);
1869 } else if (frame_size == -1) {
1871 lost_sync_count++; // lost sync count limmitation 2K Bytes
1872 if (lost_sync_count > (1024 * 2)) {
1873 GST_WARNING_OBJECT (aacparse,
1874 "lost_sync_count is larger than 2048");
1878 offset += frame_size;
1880 lost_sync_count = 0;
1884 /* if we can got full file, we can calculate the accurate duration */
1885 /* MODIFICATION : add defence codes for real buffer_size is different with pull_size */
1886 //if (pull_size == file_size) {
1887 if (buffer_size == file_size) {
1888 gfloat duration_for_one_frame = 0;
1889 GstClockTime calculated_duration = GST_CLOCK_TIME_NONE;
1891 GST_INFO_OBJECT (aacparse,
1892 "we got total file (%" G_GINT64_FORMAT
1893 " bytes). do not estimate but make Accurate total duration.",
1896 duration_for_one_frame =
1897 (gfloat) AAC_SAMPLE_PER_FRAME / (gfloat) sample_rate;
1898 calculated_duration =
1899 num_frames * duration_for_one_frame * 1000 * 1000 * 1000;
1901 GST_INFO_OBJECT (aacparse, "duration_for_one_frame %f ms",
1902 duration_for_one_frame);
1903 GST_INFO_OBJECT (aacparse, "calculated duration = %" GST_TIME_FORMAT,
1904 GST_TIME_ARGS (calculated_duration));
1905 /* 0 means disable estimate */
1906 gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1907 calculated_duration, 0);
1910 GST_INFO_OBJECT (aacparse,
1911 "we got %" G_GUINT64_FORMAT " bytes in total file (%"
1912 G_GINT64_FORMAT "). can not make accurate duration but Estimate.",
1913 pull_size, file_size);
1915 (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1916 duration = num_frames * frame_duration_us;
1918 if (duration == 0) {
1919 GST_WARNING_OBJECT (aacparse, "Invalid duration");
1923 (gint) ((gfloat) (offset * 8) / (gfloat) (duration / 1000));
1925 if (estimated_bitrate == 0) {
1926 GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1929 estimated_duration =
1930 (GstClockTime) ((file_size * 8) / (estimated_bitrate * 1000)) *
1933 GST_INFO_OBJECT (aacparse, "number of frame = %" G_GINT64_FORMAT,
1935 GST_INFO_OBJECT (aacparse, "duration = %" G_GINT64_FORMAT,
1936 duration / 1000000);
1937 GST_INFO_OBJECT (aacparse, "byte = %" G_GINT64_FORMAT, offset);
1938 GST_INFO_OBJECT (aacparse, "estimated bitrate = %d bps",
1940 GST_INFO_OBJECT (aacparse, "estimated duration = %" GST_TIME_FORMAT,
1941 GST_TIME_ARGS (estimated_duration));
1943 gst_base_parse_set_average_bitrate (parse, estimated_bitrate * 1000);
1944 /* set update_interval as duration(sec)/2 */
1945 gst_base_parse_set_duration (parse, GST_FORMAT_TIME, estimated_duration,
1946 (gint) (duration / 2));
1955 gst_buffer_unmap (buffer, &map);
1956 gst_buffer_unref (buffer);
1961 /* perform seek in push based mode:
1962 find BYTE position to move to based on time and delegate to upstream
1965 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1966 GstPad * pad, GstEvent * event)
1968 GstAacParse *aacparse = GST_AAC_PARSE (parse);
1972 GstSeekType cur_type, stop_type;
1976 gint64 esimate_byte;
1978 gint64 upstream_total_bytes = 0;
1979 GstFormat fmt = GST_FORMAT_BYTES;
1981 GST_INFO_OBJECT (parse, "doing aac push-based seek");
1983 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
1986 /* FIXME, always play to the end */
1989 /* only forward streaming and seeking is possible */
1991 goto unsupported_seek;
1994 /* handle rewind only */
1995 cur_type = GST_SEEK_TYPE_SET;
1997 stop_type = GST_SEEK_TYPE_NONE;
1999 flags |= GST_SEEK_FLAG_FLUSH;
2001 /* handle normal seek */
2002 cur_type = GST_SEEK_TYPE_SET;
2003 stop_type = GST_SEEK_TYPE_NONE;
2005 flags |= GST_SEEK_FLAG_FLUSH;
2007 esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
2008 if (aacparse->sample_rate > 0)
2009 frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
2011 goto unsupported_seek;
2013 byte_cur = esimate_byte / (frame_dur);
2015 goto unsupported_seek;
2017 GST_INFO_OBJECT (parse, "frame_byte(%d) spf(%d) rate (%d) ",
2018 aacparse->frame_byte, aacparse->spf, aacparse->sample_rate);
2019 GST_INFO_OBJECT (parse,
2020 "seek cur (%" G_GINT64_FORMAT ") = (%" GST_TIME_FORMAT ") ", cur,
2021 GST_TIME_ARGS (cur));
2022 GST_INFO_OBJECT (parse,
2023 "esimate_byte(%" G_GINT64_FORMAT ") esimate_byte (%d)", esimate_byte,
2027 /* obtain real upstream total bytes */
2028 if (!gst_pad_peer_query_duration (parse->sinkpad, fmt, &upstream_total_bytes))
2029 upstream_total_bytes = 0;
2030 GST_INFO_OBJECT (aacparse,
2031 "gst_pad_query_peer_duration -upstream_total_bytes (%" G_GUINT64_FORMAT
2032 ")", upstream_total_bytes);
2033 aacparse->file_size = upstream_total_bytes;
2035 if ((byte_cur == -1) || (byte_cur > aacparse->file_size)) {
2036 GST_INFO_OBJECT (parse,
2037 "[WEB-ERROR] seek cur (%" G_GINT64_FORMAT ") > file_size (%"
2038 G_GINT64_FORMAT ") ", cur, aacparse->file_size);
2042 GST_INFO_OBJECT (parse,
2043 "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %"
2044 G_GINT64_FORMAT, rate, byte_cur, stop);
2046 if (!(flags & GST_SEEK_FLAG_KEY_UNIT)) {
2047 GST_INFO_OBJECT (parse,
2048 "Requested seek time: %" GST_TIME_FORMAT ", calculated seek offset: %"
2049 G_GUINT64_FORMAT, GST_TIME_ARGS (cur), byte_cur);
2052 /* BYTE seek event */
2054 gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
2056 res = gst_pad_push_event (parse->sinkpad, event);
2064 GST_DEBUG_OBJECT (parse,
2065 "could not determine byte position to seek to, " "seek aborted.");
2071 GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
2078 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
2081 if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
2083 ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
2091 * gst_aac_parse_adts_src_eventfunc:
2092 * @parse: #GstBaseParse. #event
2094 * before baseparse handles seek event, make full amr index table.
2096 * Returns: TRUE on success.
2099 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
2101 gboolean handled = FALSE;
2102 GstAacParse *aacparse = GST_AAC_PARSE (parse);
2104 switch (GST_EVENT_TYPE (event)) {
2105 case GST_EVENT_SEEK:
2107 GstFlowReturn res = GST_FLOW_OK;
2108 gint64 base_offset = 0, cur = 0;
2109 gint32 frame_count = 1; /* do not add first frame because it is already in index table */
2110 gint64 second_count = 0; /* initial 1 second */
2111 gint64 total_file_size = 0, start_offset = 0;
2112 GstClockTime current_ts = GST_CLOCK_TIME_NONE;
2113 GstPadMode pad_mode = GST_PAD_MODE_NONE;
2115 /* check baseparse define these fuction */
2116 gst_base_parse_get_pad_mode (parse, &pad_mode);
2117 if (pad_mode != GST_PAD_MODE_PULL) {
2118 gboolean ret = FALSE;
2119 GstPad *srcpad = parse->srcpad;
2120 GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
2122 ret = gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
2123 gst_object_unref (srcpad);
2126 gst_base_parse_get_upstream_size (parse, &total_file_size);
2127 gst_base_parse_get_index_last_offset (parse, &start_offset);
2128 gst_base_parse_get_index_last_ts (parse, ¤t_ts);
2130 if (total_file_size > AAC_LARGE_FILE_SIZE) {
2131 gst_base_parse_set_seek_mode (parse, 0);
2132 GST_INFO_OBJECT (aacparse, "larger than big size (2MB).");
2133 goto aac_seek_null_exit;
2136 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2138 if (total_file_size == 0 || start_offset >= total_file_size) {
2139 GST_ERROR ("last index offset %" G_GINT64_FORMAT
2140 " is larger than file size %" G_GINT64_FORMAT, start_offset,
2145 gst_event_parse_seek (event, NULL, NULL, NULL, NULL, &cur, NULL, NULL);
2146 if (cur <= current_ts) {
2147 GST_INFO ("seek to %" GST_TIME_FORMAT " within index table %"
2148 GST_TIME_FORMAT ". do not make index table", GST_TIME_ARGS (cur),
2149 GST_TIME_ARGS (current_ts));
2152 GST_INFO ("seek to %" GST_TIME_FORMAT " without index table %"
2153 GST_TIME_FORMAT ". make index table", GST_TIME_ARGS (cur),
2154 GST_TIME_ARGS (current_ts));
2157 GST_INFO ("make AAC(ADTS) Index Table. file_size = %" G_GINT64_FORMAT
2158 " last idx offset=%" G_GINT64_FORMAT ", last idx ts=%"
2159 GST_TIME_FORMAT, total_file_size, start_offset,
2160 GST_TIME_ARGS (current_ts));
2162 base_offset = start_offset; /* set base by start offset */
2163 second_count = current_ts + GST_SECOND; /* 1sec */
2165 /************************************/
2166 /* STEP 0: Setting parse information */
2167 /************************************/
2168 aacparse->spf = aacparse->frame_samples;
2169 aacparse->frame_duration = (aacparse->spf * 1000 * 100) / aacparse->sample_rate; /* duration per frame (msec) */
2170 aacparse->frame_per_sec = (aacparse->sample_rate) / aacparse->spf; /* frames per second (ea) */
2172 /************************************/
2173 /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2174 /************************************/
2175 while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2177 GstBuffer *buffer = NULL;
2180 GST_INFO ("gst_pad_pull_range %d bytes (from %" G_GINT64_FORMAT
2181 ") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2183 gst_pad_pull_range (parse->sinkpad, base_offset,
2184 base_offset + AAC_MAX_PULL_RANGE_BUF, &buffer);
2185 if (res != GST_FLOW_OK) {
2186 GST_ERROR ("gst_pad_pull_range failed!");
2190 gst_buffer_map (buffer, &map, GST_MAP_READ);
2193 gst_buffer_unmap (buffer, &map);
2194 GST_WARNING ("buffer is NULL in make aac seek table's STEP1");
2195 gst_buffer_unref (buffer);
2196 goto aac_seek_null_exit;
2199 while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2200 gint frame_size = 0;
2202 /* make sure the values in the frame header look sane */
2203 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2205 if ((frame_size > 0)
2206 && (frame_size < (AAC_MAX_PULL_RANGE_BUF - offset))) {
2207 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2208 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2209 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2210 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2211 base_offset + offset);
2212 second_count += GST_SECOND; /* 1sec */
2215 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2216 offset += frame_size;
2219 } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2220 GST_DEBUG ("we need refill buffer");
2223 GST_WARNING ("we lost sync");
2229 base_offset = base_offset + offset;
2231 gst_buffer_unmap (buffer, &map);
2232 gst_buffer_unref (buffer);
2233 } /* end MAX buffer cycle */
2235 /*******************************/
2236 /* STEP 2: Remain Buffer cycle */
2237 /*******************************/
2238 if (total_file_size - base_offset > 0) {
2240 GstBuffer *buffer = NULL;
2244 GST_INFO ("gst_pad_pull_range %" G_GINT64_FORMAT " bytes (from %"
2245 G_GINT64_FORMAT ") use remain_buf size",
2246 total_file_size - base_offset, base_offset);
2248 gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size,
2250 if (res != GST_FLOW_OK) {
2251 GST_ERROR ("gst_pad_pull_range failed!");
2255 gst_buffer_map (buffer, &map, GST_MAP_READ);
2258 gst_buffer_unmap (buffer, &map);
2259 GST_WARNING ("buffer is NULL in make aac seek table's STEP2");
2260 gst_buffer_unref (buffer);
2261 goto aac_seek_null_exit;
2264 while (base_offset + offset < total_file_size) {
2265 gint frame_size = 0;
2267 /* make sure the values in the frame header look sane */
2268 frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2270 if ((frame_size > 0)
2271 && (frame_size <= (total_file_size - (base_offset + offset)))) {
2272 if (current_ts > second_count) { /* 1 sec == xx frames. we make idx per sec */
2273 gst_base_parse_add_index_entry (parse, base_offset + offset, current_ts, TRUE, TRUE); /* force */
2274 GST_DEBUG ("Adding index ts=%" GST_TIME_FORMAT " offset %"
2275 G_GINT64_FORMAT, GST_TIME_ARGS (current_ts),
2276 base_offset + offset);
2277 second_count += GST_SECOND; /* 1sec */
2280 current_ts += (aacparse->frame_duration * GST_MSECOND) / 100; /* each frame is (frame_duration) ms */
2281 offset += frame_size;
2284 } else if (frame_size == 0) {
2285 GST_DEBUG ("Frame size is 0 so, Decoding end..");
2288 GST_WARNING ("we lost sync");
2294 gst_buffer_unmap (buffer, &map);
2295 gst_buffer_unref (buffer);
2297 /* end remain_buf buffer cycle */
2298 GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2308 /* call baseparse src_event function to handle event */
2309 handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2312 #endif //end of #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION