854b1d0b545228781b8e0c6cb494bd1033692f87
[platform/upstream/gstreamer.git] / gst / audioparsers / gstaacparse.c
1 /* GStreamer AAC parser plugin
2  * Copyright (C) 2008 Nokia Corporation. All rights reserved.
3  *
4  * Contact: Stefan Kost <stefan.kost@nokia.com>
5  *
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.
10  *
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.
15  *
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.
20  */
21
22 /**
23  * SECTION:element-aacparse
24  * @title: aacparse
25  * @short_description: AAC parser
26  * @see_also: #GstAmrParse
27  *
28  * This is an AAC parser which handles both ADIF and ADTS stream formats.
29  *
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.
33  *
34  * ## Example launch line
35  * |[
36  * gst-launch-1.0 filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
37  * ]|
38  *
39  */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include <string.h>
46
47 #include <gst/base/gstbitreader.h>
48 #include <gst/pbutils/pbutils.h>
49 #include "gstaudioparserselements.h"
50 #include "gstaacparse.h"
51
52
53 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
54     GST_PAD_SRC,
55     GST_PAD_ALWAYS,
56     GST_STATIC_CAPS ("audio/mpeg, "
57         "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
58         "stream-format = (string) { raw, adts, adif, loas };"));
59
60 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
61     GST_PAD_SINK,
62     GST_PAD_ALWAYS,
63     GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) { 2, 4 };"));
64
65 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
66 #define GST_CAT_DEFAULT aacparse_debug
67
68
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 */
73
74 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
75                                    headers prepended during raw to ADTS
76                                    conversion */
77
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
81
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
85 #endif
86
87 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
88
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
92 };
93
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
97 };
98
99 static gboolean gst_aac_parse_start (GstBaseParse * parse);
100 static gboolean gst_aac_parse_stop (GstBaseParse * parse);
101
102 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
103     GstCaps * caps);
104 static GstCaps *gst_aac_parse_sink_getcaps (GstBaseParse * parse,
105     GstCaps * filter);
106
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,
112     GstEvent * event);
113
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);
117
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,
122     GstEvent * event);
123 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
124     gint64 offset);
125 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
126 static void gst_aac_parse_check_byte_seekability (GstBaseParse * parse);
127 #endif
128
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);
133
134 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
135 static inline gint
136 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
137 {
138   static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
139     32000, 24000, 22050, 16000, 12000, 11025, 8000
140   };
141
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);
145   return 0;
146 }
147 #endif
148 /**
149  * gst_aac_parse_class_init:
150  * @klass: #GstAacParseClass.
151  *
152  */
153 static void
154 gst_aac_parse_class_init (GstAacParseClass * klass)
155 {
156   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
157   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
158
159   GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
160       "AAC audio stream parser");
161
162   gst_element_class_add_static_pad_template (element_class, &sink_template);
163   gst_element_class_add_static_pad_template (element_class, &src_template);
164
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>");
168
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);
177 }
178
179
180 /**
181  * gst_aac_parse_init:
182  * @aacparse: #GstAacParse.
183  * @klass: #GstAacParseClass.
184  *
185  */
186 static void
187 gst_aac_parse_init (GstAacParse * aacparse)
188 {
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));
192
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;
198 #endif
199 }
200
201
202 /**
203  * gst_aac_parse_set_src_caps:
204  * @aacparse: #GstAacParse.
205  * @sink_caps: (proposed) caps of sink pad
206  *
207  * Set source pad caps according to current knowledge about the
208  * audio stream.
209  *
210  * Returns: TRUE if caps were successfully set.
211  */
212 static gboolean
213 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
214 {
215   GstStructure *s;
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;
222
223   GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
224   if (sink_caps)
225     src_caps = gst_caps_copy (sink_caps);
226   else
227     src_caps = gst_caps_new_empty_simple ("audio/mpeg");
228
229   gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
230       "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
231
232   aacparse->output_header_type = aacparse->header_type;
233   switch (aacparse->header_type) {
234     case DSPAAC_HEADER_NONE:
235       stream_format = "raw";
236       break;
237     case DSPAAC_HEADER_ADTS:
238       stream_format = "adts";
239       break;
240     case DSPAAC_HEADER_ADIF:
241       stream_format = "adif";
242       break;
243     case DSPAAC_HEADER_LOAS:
244       stream_format = "loas";
245       break;
246     default:
247       stream_format = NULL;
248   }
249
250   /* Generate codec data to be able to set profile/level on the caps */
251   sample_rate_idx =
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;
255   codec_data_data =
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);
260
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);
266   if (stream_format)
267     gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
268
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);
279   }
280 #endif
281
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",
290           NULL);
291       if (gst_caps_can_intersect (src_caps, peercaps)) {
292         GstBuffer *codec_data_buffer;
293
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;
297
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);
305       }
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",
310           NULL);
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;
315       }
316     }
317   }
318   if (peercaps)
319     gst_caps_unref (peercaps);
320
321   aacparse->last_parsed_channels = 0;
322   aacparse->last_parsed_sample_rate = 0;
323
324   GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
325
326   res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
327   gst_caps_unref (src_caps);
328   return res;
329
330 not_a_known_rate:
331   GST_ERROR_OBJECT (aacparse, "Not a known sample rate: %d",
332       aacparse->sample_rate);
333   gst_caps_unref (src_caps);
334   return FALSE;
335 }
336
337
338 /**
339  * gst_aac_parse_sink_setcaps:
340  * @sinkpad: GstPad
341  * @caps: GstCaps
342  *
343  * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
344  *
345  * Returns: TRUE on success.
346  */
347 static gboolean
348 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
349 {
350   GstAacParse *aacparse;
351   GstStructure *structure;
352   gchar *caps_str;
353   const GValue *value;
354
355   aacparse = GST_AAC_PARSE (parse);
356   structure = gst_caps_get_structure (caps, 0);
357   caps_str = gst_caps_to_string (caps);
358
359   GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
360   g_free (caps_str);
361
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");
366   if (value) {
367     GstBuffer *buf = gst_value_get_buffer (value);
368
369     if (buf && gst_buffer_get_size (buf) >= 2) {
370       GstMapInfo map;
371       GstBitReader br;
372
373       if (!gst_buffer_map (buf, &map, GST_MAP_READ))
374         return FALSE;
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);
379
380       aacparse->header_type = DSPAAC_HEADER_NONE;
381       aacparse->mpegversion = 4;
382       gst_buffer_unmap (buf, &map);
383
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);
387
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);
392
393       /* input is already correctly framed */
394       gst_base_parse_set_min_frame_size (parse, RAW_MAX_SIZE);
395     } else {
396       return FALSE;
397     }
398
399     /* caps info overrides */
400     gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
401     gst_structure_get_int (structure, "channels", &aacparse->channels);
402   } else {
403     const gchar *stream_format =
404         gst_structure_get_string (structure, "stream-format");
405
406     if (g_strcmp0 (stream_format, "raw") == 0) {
407       GST_ERROR_OBJECT (parse, "Need codec_data for raw AAC");
408       return FALSE;
409     } else {
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);
414     }
415   }
416   return TRUE;
417 }
418
419
420 /**
421  * gst_aac_parse_adts_get_frame_len:
422  * @data: block of data containing an ADTS header.
423  *
424  * This function calculates ADTS frame length from the given header.
425  *
426  * Returns: size of the ADTS frame.
427  */
428 static inline guint
429 gst_aac_parse_adts_get_frame_len (const guint8 * data)
430 {
431   return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
432 }
433
434
435 /**
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.
447  *
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.
454  *
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.
458  *
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
462  * of correct size.
463  *
464  * Returns: TRUE if the given data contains a valid ADTS header.
465  */
466 static gboolean
467 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
468     const guint8 * data, const guint avail, gboolean drain,
469     guint * framesize, guint * needed_data)
470 {
471   guint crc_size;
472
473   *needed_data = 0;
474
475   /* Absolute minimum to perform the ADTS syncword,
476      layer and sampling frequency tests */
477   if (G_UNLIKELY (avail < 3)) {
478     *needed_data = 3;
479     return FALSE;
480   }
481
482   /* Syncword and layer tests */
483   if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
484
485     /* Sampling frequency test */
486     if (G_UNLIKELY ((data[2] & 0x3C) >> 2 == 15))
487       return FALSE;
488
489     /* This looks like an ADTS frame header but
490        we need at least 6 bytes to proceed */
491     if (G_UNLIKELY (avail < 6)) {
492       *needed_data = 6;
493       return FALSE;
494     }
495
496     *framesize = gst_aac_parse_adts_get_frame_len (data);
497
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;
501
502     /* CRC size test */
503     if (*framesize < 7 + crc_size) {
504       *needed_data = 7 + crc_size;
505       return FALSE;
506     }
507
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)) {
514       return TRUE;
515     }
516
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);
525       return FALSE;
526     }
527
528     if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
529       guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
530
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);
534       return TRUE;
535     }
536   }
537   return FALSE;
538 }
539
540 static gboolean
541 gst_aac_parse_latm_get_value (GstAacParse * aacparse, GstBitReader * br,
542     guint32 * value)
543 {
544   guint8 bytes, i, byte;
545
546   *value = 0;
547   if (!gst_bit_reader_get_bits_uint8 (br, &bytes, 2))
548     return FALSE;
549   for (i = 0; i <= bytes; ++i) {
550     *value <<= 8;
551     if (!gst_bit_reader_get_bits_uint8 (br, &byte, 8))
552       return FALSE;
553     *value += byte;
554   }
555   return TRUE;
556 }
557
558 static gboolean
559 gst_aac_parse_get_audio_object_type (GstAacParse * aacparse, GstBitReader * br,
560     guint8 * audio_object_type)
561 {
562   if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 5))
563     return FALSE;
564   if (*audio_object_type == 31) {
565     if (!gst_bit_reader_get_bits_uint8 (br, audio_object_type, 6))
566       return FALSE;
567     *audio_object_type += 32;
568   }
569   GST_LOG_OBJECT (aacparse, "audio object type %u", *audio_object_type);
570   return TRUE;
571 }
572
573 static gboolean
574 gst_aac_parse_get_audio_sample_rate (GstAacParse * aacparse, GstBitReader * br,
575     gint * sample_rate)
576 {
577   guint8 sampling_frequency_index;
578   if (!gst_bit_reader_get_bits_uint8 (br, &sampling_frequency_index, 4))
579     return FALSE;
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))
585       return FALSE;
586     *sample_rate = sampling_rate;
587   } else {
588     *sample_rate = loas_sample_rate_table[sampling_frequency_index];
589     if (!*sample_rate)
590       return FALSE;
591   }
592   aacparse->last_parsed_sample_rate = *sample_rate;
593   return TRUE;
594 }
595
596 /* See table 1.13 in ISO/IEC 14496-3 */
597 static gboolean
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)
601 {
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;
606
607   if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
608     return FALSE;
609   if (object_type)
610     *object_type = audio_object_type;
611
612   if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
613     return FALSE;
614
615   if (!gst_bit_reader_get_bits_uint8 (br, &channel_configuration, 4))
616     return FALSE;
617   *channels = loas_channels_table[channel_configuration];
618   GST_LOG_OBJECT (aacparse, "channel_configuration: %d", channel_configuration);
619   if (!*channels)
620     return FALSE;
621
622   if (audio_object_type == 5 || audio_object_type == 29) {
623     extension_audio_object_type = 5;
624     sbr = TRUE;
625     if (audio_object_type == 29) {
626       ps = TRUE;
627       /* Parametric stereo. If we have a one-channel configuration, we can
628        * override it to stereo */
629       if (*channels == 1)
630         *channels = 2;
631     }
632
633     GST_LOG_OBJECT (aacparse,
634         "Audio object type 5 or 29, so rereading sampling rate (was %d)...",
635         *sample_rate);
636     if (!gst_aac_parse_get_audio_sample_rate (aacparse, br, sample_rate))
637       return FALSE;
638
639     if (!gst_aac_parse_get_audio_object_type (aacparse, br, &audio_object_type))
640       return FALSE;
641
642     if (audio_object_type == 22) {
643       /* extension channel configuration */
644       if (!gst_bit_reader_get_bits_uint8 (br, &extension_channel_configuration,
645               4))
646         return FALSE;
647       GST_LOG_OBJECT (aacparse, "extension channel_configuration: %d",
648           extension_channel_configuration);
649       *channels = loas_channels_table[extension_channel_configuration];
650       if (!*channels)
651         return FALSE;
652     }
653   } else {
654     extension_audio_object_type = 0;
655   }
656
657   GST_INFO_OBJECT (aacparse, "Parsed AudioSpecificConfig: %d Hz, %d channels",
658       *sample_rate, *channels);
659
660   if (frame_samples && audio_object_type == 23) {
661     guint8 frame_flag;
662     /* Read the Decoder Configuration (GASpecificConfig) if present */
663     /* We only care about the first bit to know what the number of samples
664      * in a frame is */
665     if (!gst_bit_reader_get_bits_uint8 (br, &frame_flag, 1))
666       return FALSE;
667     *frame_samples = frame_flag ? 960 : 1024;
668   }
669
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;
675   return TRUE;
676 }
677
678
679 static gboolean
680 gst_aac_parse_read_loas_config (GstAacParse * aacparse, const guint8 * data,
681     guint avail, gint * sample_rate, gint * channels, gint * version)
682 {
683   GstBitReader br;
684   guint8 u8, v, vA;
685
686   /* No version in the bitstream, but the spec has LOAS in the MPEG-4 section */
687   if (version)
688     *version = 4;
689
690   gst_bit_reader_init (&br, data, avail);
691
692   /* skip sync word (11 bits) and size (13 bits) */
693   if (!gst_bit_reader_skip (&br, 11 + 13))
694     return FALSE;
695
696   /* First bit is "use last config" */
697   if (!gst_bit_reader_get_bits_uint8 (&br, &u8, 1))
698     return FALSE;
699   if (u8) {
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.");
704       return FALSE;
705     }
706     *sample_rate = aacparse->last_parsed_sample_rate;
707     *channels = aacparse->last_parsed_channels;
708     return TRUE;
709   }
710
711   GST_DEBUG_OBJECT (aacparse, "Frame contains new config");
712
713   /* audioMuxVersion */
714   if (!gst_bit_reader_get_bits_uint8 (&br, &v, 1))
715     return FALSE;
716   if (v) {
717     /* audioMuxVersionA */
718     if (!gst_bit_reader_get_bits_uint8 (&br, &vA, 1))
719       return FALSE;
720   } else
721     vA = 0;
722
723   GST_LOG_OBJECT (aacparse, "v %d, vA %d", v, vA);
724   if (vA == 0) {
725     guint8 same_time, subframes, num_program, prog;
726     if (v == 1) {
727       guint32 value;
728       /* taraBufferFullness */
729       if (!gst_aac_parse_latm_get_value (aacparse, &br, &value))
730         return FALSE;
731     }
732     if (!gst_bit_reader_get_bits_uint8 (&br, &same_time, 1))
733       return FALSE;
734     if (!gst_bit_reader_get_bits_uint8 (&br, &subframes, 6))
735       return FALSE;
736     if (!gst_bit_reader_get_bits_uint8 (&br, &num_program, 4))
737       return FALSE;
738     GST_LOG_OBJECT (aacparse, "same_time %d, subframes %d, num_program %d",
739         same_time, subframes, num_program);
740
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))
744         return FALSE;
745       GST_LOG_OBJECT (aacparse, "Program %d: %d layers", prog, num_layer);
746
747       for (layer = 0; layer <= num_layer; ++layer) {
748         guint8 use_same_config;
749         if (prog == 0 && layer == 0) {
750           use_same_config = 0;
751         } else {
752           if (!gst_bit_reader_get_bits_uint8 (&br, &use_same_config, 1))
753             return FALSE;
754         }
755         if (!use_same_config) {
756           if (v == 0) {
757             if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
758                     sample_rate, channels, NULL))
759               return FALSE;
760           } else {
761             guint32 asc_len;
762             if (!gst_aac_parse_latm_get_value (aacparse, &br, &asc_len))
763               return FALSE;
764             if (!gst_aac_parse_read_audio_specific_config (aacparse, &br, NULL,
765                     sample_rate, channels, NULL))
766               return FALSE;
767             if (!gst_bit_reader_skip (&br, asc_len))
768               return FALSE;
769           }
770         }
771       }
772     }
773     GST_LOG_OBJECT (aacparse, "More data ignored");
774   } else {
775     GST_WARNING_OBJECT (aacparse, "Spec says \"TBD\"...");
776     return FALSE;
777   }
778   return TRUE;
779 }
780
781 /**
782  * gst_aac_parse_loas_get_frame_len:
783  * @data: block of data containing a LOAS header.
784  *
785  * This function calculates LOAS frame length from the given header.
786  *
787  * Returns: size of the LOAS frame.
788  */
789 static inline guint
790 gst_aac_parse_loas_get_frame_len (const guint8 * data)
791 {
792   return (((data[1] & 0x1f) << 8) | data[2]) + 3;
793 }
794
795
796 /**
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.
808  *
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.
815  *
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.
819  *
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
823  * of correct size.
824  *
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.
827  *
828  * Returns: TRUE if the given data contains a valid LOAS header.
829  */
830 static gboolean
831 gst_aac_parse_check_loas_frame (GstAacParse * aacparse,
832     const guint8 * data, const guint avail, gboolean drain,
833     guint * framesize, guint * needed_data)
834 {
835   *needed_data = 0;
836
837   /* 3 byte header */
838   if (G_UNLIKELY (avail < 3)) {
839     *needed_data = 3;
840     return FALSE;
841   }
842
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",
846         *framesize);
847
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)) {
854       return TRUE;
855     }
856
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);
865       return FALSE;
866     }
867
868     if ((data[*framesize] == 0x56) && ((data[*framesize + 1] & 0xe0) == 0xe0)) {
869       guint nextlen = gst_aac_parse_loas_get_frame_len (data + (*framesize));
870
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);
874       return TRUE;
875     } else {
876       GST_DEBUG_OBJECT (aacparse, "That was a false positive");
877     }
878   }
879   return FALSE;
880 }
881
882 /* caller ensure sufficient data */
883 static inline void
884 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
885     gint * rate, gint * channels, gint * object, gint * version)
886 {
887
888   if (rate) {
889     gint sr_idx = (data[2] & 0x3c) >> 2;
890
891     *rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
892   }
893   if (channels) {
894     *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
895     if (*channels == 7)
896       *channels = 8;
897   }
898
899   if (version)
900     *version = (data[1] & 0x08) ? 2 : 4;
901   if (object)
902     *object = ((data[2] & 0xc0) >> 6) + 1;
903 }
904
905 /**
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.
914  *
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.
921  *
922  * Returns: TRUE on success.
923  */
924 static gboolean
925 gst_aac_parse_detect_stream (GstAacParse * aacparse,
926     const guint8 * data, const guint avail, gboolean drain,
927     guint * framesize, gint * skipsize)
928 {
929   gboolean found = FALSE;
930   guint need_data_adts = 0, need_data_loas;
931   guint i = 0;
932
933   GST_DEBUG_OBJECT (aacparse, "Parsing header data");
934
935   /* FIXME: No need to check for ADIF if we are not in the beginning of the
936      stream */
937
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");
941     return FALSE;
942   }
943
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);
949       found = TRUE;
950
951       if (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. */
955         *skipsize = i;
956         return FALSE;
957       }
958       break;
959     }
960   }
961   if (!found) {
962     if (i)
963       *skipsize = i;
964     return FALSE;
965   }
966
967   if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
968           framesize, &need_data_adts)) {
969     gint rate, channels;
970
971     GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
972
973     gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
974         &aacparse->object_type, &aacparse->mpegversion);
975
976     if (!channels || !framesize) {
977       GST_DEBUG_OBJECT (aacparse, "impossible ADTS configuration");
978       return FALSE;
979     }
980
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);
984
985     GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
986         rate, channels, aacparse->object_type, aacparse->mpegversion);
987
988     gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
989
990     return TRUE;
991   }
992
993   if (gst_aac_parse_check_loas_frame (aacparse, data, avail, drain,
994           framesize, &need_data_loas)) {
995     gint rate = 0, channels = 0;
996
997     GST_INFO ("LOAS, framesize: %d", *framesize);
998
999     aacparse->header_type = DSPAAC_HEADER_LOAS;
1000
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");
1006       return FALSE;
1007     }
1008
1009     if (rate && channels) {
1010       gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate,
1011           aacparse->frame_samples, 2, 2);
1012
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);
1017     }
1018
1019     gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
1020
1021     return TRUE;
1022   }
1023
1024   if (need_data_adts || need_data_loas) {
1025     /* This tells the parent class not to skip any data */
1026     *skipsize = 0;
1027     return FALSE;
1028   }
1029
1030   if (avail < ADIF_MAX_SIZE)
1031     return FALSE;
1032
1033   if (memcmp (data + i, "ADIF", 4) == 0) {
1034     const guint8 *adif;
1035     int skip_size = 0;
1036     int bitstream_type;
1037     int sr_idx;
1038     GstCaps *sinkcaps;
1039
1040     aacparse->header_type = DSPAAC_HEADER_ADIF;
1041     aacparse->mpegversion = 4;
1042
1043     /* Skip the "ADIF" bytes */
1044     adif = data + i + 4;
1045
1046     /* copyright string */
1047     if (adif[0] & 0x80)
1048       skip_size += 9;           /* skip 9 bytes */
1049
1050     bitstream_type = adif[0 + skip_size] & 0x10;
1051     aacparse->bitrate =
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);
1056
1057     /* CBR */
1058     if (bitstream_type == 0) {
1059 #if 0
1060       /* Buffer fullness parsing. Currently not needed... */
1061       guint num_elems = 0;
1062       guint fullness = 0;
1063
1064       num_elems = (adif[3 + skip_size] & 0x1e);
1065       GST_INFO ("ADIF num_config_elems: %d", num_elems);
1066
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);
1071
1072       GST_INFO ("ADIF buffer fullness: %d", fullness);
1073 #endif
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;
1077     }
1078     /* VBR */
1079     else {
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);
1083     }
1084
1085     /* FIXME: This gives totally wrong results. Duration calculation cannot
1086        be based on this */
1087     aacparse->sample_rate =
1088         gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
1089
1090     /* baseparse is not given any fps,
1091      * so it will give up on timestamps, seeking, etc */
1092
1093     /* FIXME: Can we assume this? */
1094     aacparse->channels = 2;
1095
1096     GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
1097         aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
1098
1099     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
1100
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);
1104     if (sinkcaps)
1105       gst_caps_unref (sinkcaps);
1106
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);
1111
1112     *framesize = avail;
1113     return TRUE;
1114   }
1115
1116   /* This should never happen */
1117   return FALSE;
1118 }
1119
1120 /**
1121  * gst_aac_parse_get_audio_profile_object_type
1122  * @aacparse: #GstAacParse.
1123  *
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.
1127  *
1128  * Returns: the profile or object type value corresponding to @aacparse's src
1129  * pad caps, if such a value exists; otherwise G_MAXUINT8.
1130  */
1131 static guint8
1132 gst_aac_parse_get_audio_profile_object_type (GstAacParse * aacparse)
1133 {
1134   GstCaps *srccaps;
1135   GstStructure *srcstruct;
1136   const gchar *profile;
1137   guint8 ret;
1138
1139   srccaps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (aacparse));
1140   if (G_UNLIKELY (srccaps == NULL)) {
1141     return G_MAXUINT8;
1142   }
1143
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);
1148     return G_MAXUINT8;
1149   }
1150
1151   if (g_strcmp0 (profile, "main") == 0) {
1152     ret = (guint8) 0U;
1153   } else if (g_strcmp0 (profile, "lc") == 0) {
1154     ret = (guint8) 1U;
1155   } else if (g_strcmp0 (profile, "ssr") == 0) {
1156     ret = (guint8) 2U;
1157   } else if (g_strcmp0 (profile, "ltp") == 0) {
1158     if (G_LIKELY (aacparse->mpegversion == 4))
1159       ret = (guint8) 3U;
1160     else
1161       ret = G_MAXUINT8;         /* LTP Object Type allowed only for MPEG-4 */
1162   } else {
1163     ret = G_MAXUINT8;
1164   }
1165
1166   gst_caps_unref (srccaps);
1167   return ret;
1168 }
1169
1170 /**
1171  * gst_aac_parse_get_audio_channel_configuration
1172  * @num_channels: number of audio channels.
1173  *
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.
1176  *
1177  * Returns: the Channel Configuration value corresponding to @num_channels, if
1178  * such a value exists; otherwise G_MAXUINT8.
1179  */
1180 static guint8
1181 gst_aac_parse_get_audio_channel_configuration (gint num_channels)
1182 {
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 */
1186     return (guint8) 7U;
1187   else
1188     return G_MAXUINT8;
1189
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
1192    */
1193 }
1194
1195 /**
1196  * gst_aac_parse_get_audio_sampling_frequency_index:
1197  * @sample_rate: audio sampling rate.
1198  *
1199  * Gets the Sampling Frequency Index value, as defined by table 1.18 in ISO/IEC
1200  * 14496-3, for a given sampling rate.
1201  *
1202  * Returns: the Sampling Frequency Index value corresponding to @sample_rate,
1203  * if such a value exists; otherwise G_MAXUINT8.
1204  */
1205 static guint8
1206 gst_aac_parse_get_audio_sampling_frequency_index (gint sample_rate)
1207 {
1208   switch (sample_rate) {
1209     case 96000:
1210       return 0x0U;
1211     case 88200:
1212       return 0x1U;
1213     case 64000:
1214       return 0x2U;
1215     case 48000:
1216       return 0x3U;
1217     case 44100:
1218       return 0x4U;
1219     case 32000:
1220       return 0x5U;
1221     case 24000:
1222       return 0x6U;
1223     case 22050:
1224       return 0x7U;
1225     case 16000:
1226       return 0x8U;
1227     case 12000:
1228       return 0x9U;
1229     case 11025:
1230       return 0xAU;
1231     case 8000:
1232       return 0xBU;
1233     case 7350:
1234       return 0xCU;
1235     default:
1236       return G_MAXUINT8;
1237   }
1238 }
1239
1240 /**
1241  * gst_aac_parse_prepend_adts_headers:
1242  * @aacparse: #GstAacParse.
1243  * @frame: raw AAC frame to which ADTS headers shall be prepended.
1244  *
1245  * Prepends ADTS headers to a raw AAC audio frame.
1246  *
1247  * Returns: TRUE if ADTS headers were successfully prepended; FALSE otherwise.
1248  */
1249 static gboolean
1250 gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
1251     GstBaseParseFrame * frame)
1252 {
1253   GstMemory *mem;
1254   guint8 *adts_headers;
1255   gsize buf_size;
1256   gsize frame_size;
1257   guint8 id, profile, channel_configuration, sampling_frequency_index;
1258
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");
1263     return FALSE;
1264   }
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");
1269     return FALSE;
1270   }
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");
1275     return FALSE;
1276   }
1277
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;
1281
1282   if (G_UNLIKELY (frame_size >= 0x4000)) {
1283     GST_ERROR_OBJECT (aacparse, "Frame size is too big for ADTS");
1284     return FALSE;
1285   }
1286
1287   adts_headers = (guint8 *) g_malloc0 (ADTS_HEADERS_LENGTH);
1288
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;
1299
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);
1303
1304   return TRUE;
1305 }
1306
1307 /**
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
1312  *            frame header.
1313  *
1314  * Implementation of "handle_frame" vmethod in #GstBaseParse class.
1315  *
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.
1319  *
1320  * We're making a couple of simplifying assumptions:
1321  *
1322  * 1. We count Program Configuration Elements rather than searching for them
1323  *    in the streams to discount them - the overhead is negligible.
1324  *
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
1328  *
1329  * Returns: a #GstFlowReturn.
1330  */
1331 static GstFlowReturn
1332 gst_aac_parse_handle_frame (GstBaseParse * parse,
1333     GstBaseParseFrame * frame, gint * skipsize)
1334 {
1335   GstMapInfo map;
1336   GstAacParse *aacparse;
1337   gboolean ret = FALSE;
1338   gboolean lost_sync;
1339   GstBuffer *buffer;
1340   guint framesize;
1341   gint rate = 0, channels = 0;
1342
1343   aacparse = GST_AAC_PARSE (parse);
1344   buffer = frame->buffer;
1345
1346   gst_buffer_map (buffer, &map, GST_MAP_READ);
1347
1348   *skipsize = -1;
1349   lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
1350
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;
1355     ret = TRUE;
1356
1357   } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
1358
1359     ret = gst_aac_parse_detect_stream (aacparse, map.data, map.size,
1360         GST_BASE_PARSE_DRAINING (parse), &framesize, skipsize);
1361
1362   } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1363     guint needed_data = 1024;
1364
1365     ret = gst_aac_parse_check_adts_frame (aacparse, map.data, map.size,
1366         GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1367
1368     if (!ret && needed_data) {
1369       GST_DEBUG ("buffer didn't contain valid frame");
1370       *skipsize = 0;
1371       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1372           needed_data);
1373     }
1374
1375   } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1376     guint needed_data = 1024;
1377
1378     ret = gst_aac_parse_check_loas_frame (aacparse, map.data,
1379         map.size, GST_BASE_PARSE_DRAINING (parse), &framesize, &needed_data);
1380
1381     if (!ret && needed_data) {
1382       GST_DEBUG ("buffer didn't contain valid frame");
1383       *skipsize = 0;
1384       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1385           needed_data);
1386     }
1387
1388   } else {
1389     GST_DEBUG ("buffer didn't contain valid frame");
1390     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
1391         ADTS_MAX_SIZE);
1392   }
1393
1394   if (G_UNLIKELY (!ret))
1395     goto exit;
1396
1397   if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
1398     /* see above */
1399     frame->overhead = 7;
1400
1401     gst_aac_parse_parse_adts_header (aacparse, map.data,
1402         &rate, &channels, NULL, NULL);
1403
1404     GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
1405
1406     if (G_UNLIKELY (rate != aacparse->sample_rate
1407             || channels != aacparse->channels)) {
1408       aacparse->sample_rate = rate;
1409       aacparse->channels = channels;
1410
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;
1414       }
1415
1416       gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1417           aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1418     }
1419 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1420     if (aacparse->first_frame == TRUE) {
1421       gboolean ret = FALSE;
1422       aacparse->first_frame = FALSE;
1423
1424       ret = gst_aac_parse_estimate_duration (parse);
1425       if (!ret) {
1426         GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
1427         ret = GST_FLOW_NOT_SUPPORTED;
1428       }
1429       gst_aac_parse_check_byte_seekability (parse);
1430     }
1431 #endif
1432   } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
1433     gboolean setcaps = FALSE;
1434
1435     /* see above */
1436     frame->overhead = 3;
1437
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 */
1446       *skipsize = 1;
1447       goto exit;
1448     }
1449
1450     if (G_UNLIKELY (rate != aacparse->sample_rate
1451             || channels != aacparse->channels)) {
1452       aacparse->sample_rate = rate;
1453       aacparse->channels = channels;
1454       setcaps = TRUE;
1455       GST_INFO_OBJECT (aacparse, "New LOAS config: %d Hz, %d channels", rate,
1456           channels);
1457     }
1458
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. */
1462     if (setcaps
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;
1467       }
1468
1469       gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
1470           aacparse->sample_rate, aacparse->frame_samples, 2, 2);
1471     }
1472   }
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)) *
1481         GST_SECOND;
1482     gst_base_parse_set_duration (parse, GST_FORMAT_TIME,
1483         estimated_duration * 1000, 0);
1484   }
1485 #endif
1486
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;
1492     }
1493   }
1494
1495 exit:
1496   gst_buffer_unmap (buffer, &map);
1497
1498   if (ret) {
1499     /* found, skip if needed */
1500     if (*skipsize > 0)
1501       return GST_FLOW_OK;
1502     *skipsize = 0;
1503   } else {
1504     if (*skipsize < 0)
1505       *skipsize = 1;
1506   }
1507
1508   if (ret && framesize <= map.size) {
1509     return gst_base_parse_finish_frame (parse, frame, framesize);
1510   }
1511
1512   return GST_FLOW_OK;
1513 }
1514
1515 static GstFlowReturn
1516 gst_aac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1517 {
1518   GstAacParse *aacparse = GST_AAC_PARSE (parse);
1519
1520   if (!aacparse->sent_codec_tag) {
1521     GstTagList *taglist;
1522     GstCaps *caps;
1523
1524     /* codec tag */
1525     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
1526     if (caps == NULL) {
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;
1530       } else {
1531         GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
1532         return GST_FLOW_NOT_NEGOTIATED;
1533       }
1534     }
1535
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);
1540
1541     gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
1542     gst_tag_list_unref (taglist);
1543
1544     /* also signals the end of first-frame processing */
1545     aacparse->sent_codec_tag = TRUE;
1546   }
1547
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) {
1551     guint header_size;
1552     GstMapInfo map;
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);
1560   }
1561
1562   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
1563
1564   return GST_FLOW_OK;
1565 }
1566
1567
1568 /**
1569  * gst_aac_parse_start:
1570  * @parse: #GstBaseParse.
1571  *
1572  * Implementation of "start" vmethod in #GstBaseParse class.
1573  *
1574  * Returns: TRUE if startup succeeded.
1575  */
1576 static gboolean
1577 gst_aac_parse_start (GstBaseParse * parse)
1578 {
1579   GstAacParse *aacparse;
1580
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;
1594   return TRUE;
1595 }
1596
1597
1598 /**
1599  * gst_aac_parse_stop:
1600  * @parse: #GstBaseParse.
1601  *
1602  * Implementation of "stop" vmethod in #GstBaseParse class.
1603  *
1604  * Returns: TRUE is stopping succeeded.
1605  */
1606 static gboolean
1607 gst_aac_parse_stop (GstBaseParse * parse)
1608 {
1609   GST_DEBUG ("stop");
1610   return TRUE;
1611 }
1612
1613 static void
1614 remove_fields (GstCaps * caps)
1615 {
1616   guint i, n;
1617
1618   n = gst_caps_get_size (caps);
1619   for (i = 0; i < n; i++) {
1620     GstStructure *s = gst_caps_get_structure (caps, i);
1621
1622     gst_structure_remove_field (s, "framed");
1623   }
1624 }
1625
1626 static void
1627 add_conversion_fields (GstCaps * caps)
1628 {
1629   guint i, n;
1630
1631   n = gst_caps_get_size (caps);
1632   for (i = 0; i < n; i++) {
1633     GstStructure *s = gst_caps_get_structure (caps, i);
1634
1635     if (gst_structure_has_field (s, "stream-format")) {
1636       const GValue *v = gst_structure_get_value (s, "stream-format");
1637
1638       if (G_VALUE_HOLDS_STRING (v)) {
1639         const gchar *str = g_value_get_string (v);
1640
1641         if (strcmp (str, "adts") == 0 || strcmp (str, "raw") == 0) {
1642           GValue va = G_VALUE_INIT;
1643           GValue vs = G_VALUE_INIT;
1644
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);
1654         }
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;
1659
1660         for (j = 0; j < m; j++) {
1661           const GValue *ve = gst_value_list_get_value (v, j);
1662           const gchar *str;
1663
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;
1669           }
1670         }
1671
1672         if (contains_adts || contains_raw) {
1673           GValue va = G_VALUE_INIT;
1674           GValue vs = G_VALUE_INIT;
1675
1676           g_value_init (&va, GST_TYPE_LIST);
1677           g_value_init (&vs, G_TYPE_STRING);
1678           g_value_copy (v, &va);
1679
1680           if (!contains_raw) {
1681             g_value_set_string (&vs, "raw");
1682             gst_value_list_append_value (&va, &vs);
1683           }
1684           if (!contains_adts) {
1685             g_value_set_string (&vs, "adts");
1686             gst_value_list_append_value (&va, &vs);
1687           }
1688
1689           gst_structure_set_value (s, "stream-format", &va);
1690
1691           g_value_unset (&vs);
1692           g_value_unset (&va);
1693         }
1694       }
1695     }
1696   }
1697 }
1698
1699 static GstCaps *
1700 gst_aac_parse_sink_getcaps (GstBaseParse * parse, GstCaps * filter)
1701 {
1702   GstCaps *peercaps, *templ;
1703   GstCaps *res;
1704
1705   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
1706
1707   if (filter) {
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);
1714   } else
1715     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
1716
1717   if (peercaps) {
1718     peercaps = gst_caps_make_writable (peercaps);
1719     /* Remove the fields we convert */
1720     remove_fields (peercaps);
1721     add_conversion_fields (peercaps);
1722
1723     res = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
1724     gst_caps_unref (peercaps);
1725     gst_caps_unref (templ);
1726   } else {
1727     res = templ;
1728   }
1729
1730   if (filter) {
1731     GstCaps *intersection;
1732
1733     intersection =
1734         gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
1735     gst_caps_unref (res);
1736     res = intersection;
1737   }
1738
1739   return res;
1740 }
1741
1742 static gboolean
1743 gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
1744 {
1745   GstAacParse *aacparse = GST_AAC_PARSE (parse);
1746
1747   if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP) {
1748     aacparse->last_parsed_channels = 0;
1749     aacparse->last_parsed_sample_rate = 0;
1750   }
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);
1756 #endif
1757   return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
1758
1759 }
1760
1761 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
1762 /**
1763  * get_aac_parse_get_adts_framelength:
1764  * @data: #GstBufferData.
1765  * @offset: #GstBufferData offset
1766  *
1767  * Implementation to get adts framelength by using first some frame.
1768  *
1769  * Returns: frame size
1770  */
1771 int
1772 get_aac_parse_get_adts_frame_length (const unsigned char *data, gint64 offset)
1773 {
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;
1778   gint head_size;
1779
1780   /* check of syncword */
1781   if ((data[offset + 0] != 0xff) || ((data[offset + 1] & 0xf6) != 0xf0)) {
1782     GST_ERROR ("check sync word is fail\n");
1783     return -1;
1784   }
1785
1786   /* check of protection absent */
1787   protection_absent = (data[offset + 1] & 0x01);
1788
1789   /*check of frame length */
1790   frame_size =
1791       (data[offset + 3] & 0x3) << 11 | data[offset + 4] << 3 | data[offset +
1792       5] >> 5;
1793
1794   /* check of header size */
1795   /* protectionAbsent is 0 if there is CRC */
1796   head_size =
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);
1802     return 0;
1803   }
1804
1805   return frame_size;
1806 }
1807
1808 /**
1809  * gst_aac_parse_estimate_duration:
1810  * @parse: #GstBaseParse.
1811  *
1812  * Implementation to get estimated total duration by using first some frame.
1813  *
1814  * Returns: TRUE if we can get estimated total duraion
1815  */
1816 static gboolean
1817 gst_aac_parse_estimate_duration (GstBaseParse * parse)
1818 {
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;
1827   guint8 *buf = NULL;
1828   gint i = 0;
1829   GstPadMode pad_mode = GST_PAD_MODE_NONE;
1830   GstAacParse *aacparse;
1831   gint64 buffer_size = 0;
1832   GstMapInfo map;
1833
1834   aacparse = GST_AAC_PARSE (parse);
1835   GST_LOG_OBJECT (aacparse, "gst_aac_parse_estimate_duration enter");
1836
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");
1842     return FALSE;
1843   }
1844
1845   gst_base_parse_get_upstream_size (parse, &file_size);
1846
1847   if (file_size < ADIF_MAX_SIZE) {
1848     GST_ERROR_OBJECT (aacparse, "file size is too short");
1849     return FALSE;
1850   }
1851
1852   pull_size = MIN (file_size, AAC_MAX_ESTIMATE_DURATION_BUF);
1853
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!");
1857     return FALSE;
1858   }
1859
1860   gst_buffer_map (buffer, &map, GST_MAP_READ);
1861   buf = map.data;
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);
1867   }
1868
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;
1874       sample_rate =
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)");
1878         goto EXIT;
1879       }
1880       channel = (buf[i + 2] & 0x1) << 2 | (buf[i + 3] >> 6);
1881
1882       GST_INFO_OBJECT (aacparse, "found sync. aac fs=%d, ch=%d", sample_rate,
1883           channel);
1884
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);
1893           break;
1894         } else if (frame_size == -1) {
1895           offset++;
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");
1900             goto EXIT;
1901           }
1902         } else {
1903           offset += frame_size;
1904           num_frames++;
1905           lost_sync_count = 0;
1906         }
1907       }                         /* while */
1908
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;
1915
1916         GST_INFO_OBJECT (aacparse,
1917             "we got total file (%" G_GINT64_FORMAT
1918             " bytes). do not estimate but make Accurate total duration.",
1919             pull_size);
1920
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;
1925
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);
1933
1934       } else {
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);
1939         frame_duration_us =
1940             (1024 * 1000000ll + (sample_rate - 1)) / sample_rate;
1941         duration = num_frames * frame_duration_us;
1942
1943         if (duration == 0) {
1944           GST_WARNING_OBJECT (aacparse, "Invalid duration");
1945           goto EXIT;
1946         }
1947         estimated_bitrate =
1948             (gint) ((gfloat) (offset * 8) / (gfloat) (duration / 1000));
1949
1950         if (estimated_bitrate == 0) {
1951           GST_WARNING_OBJECT (aacparse, "Invalid estimated_bitrate");
1952           goto EXIT;
1953         }
1954         estimated_duration =
1955             (GstClockTime) ((file_size * 8) / (estimated_bitrate * 1000)) *
1956             GST_SECOND;
1957
1958         GST_INFO_OBJECT (aacparse, "number of frame = %" G_GINT64_FORMAT,
1959             num_frames);
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",
1964             estimated_bitrate);
1965         GST_INFO_OBJECT (aacparse, "estimated duration = %" GST_TIME_FORMAT,
1966             GST_TIME_ARGS (estimated_duration));
1967
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));
1972       }
1973
1974       break;
1975     }
1976   }
1977   ret = TRUE;
1978
1979 EXIT:
1980   gst_buffer_unmap (buffer, &map);
1981   gst_buffer_unref (buffer);
1982   return ret;
1983 }
1984
1985
1986 /* perform seek in push based mode:
1987    find BYTE position to move to based on time and delegate to upstream
1988 */
1989 static gboolean
1990 gst_aac_audio_parse_do_push_seek (GstBaseParse * parse,
1991     GstPad * pad, GstEvent * event)
1992 {
1993   GstAacParse *aacparse = GST_AAC_PARSE (parse);
1994   gdouble rate;
1995   GstFormat format;
1996   GstSeekFlags flags;
1997   GstSeekType cur_type, stop_type;
1998   gint64 cur, stop;
1999   gboolean res;
2000   gint64 byte_cur;
2001   gint64 esimate_byte;
2002   gint32 frame_dur;
2003   gint64 upstream_total_bytes = 0;
2004   GstFormat fmt = GST_FORMAT_BYTES;
2005
2006   GST_INFO_OBJECT (parse, "doing aac push-based seek");
2007
2008   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
2009       &stop_type, &stop);
2010
2011   /* FIXME, always play to the end */
2012   stop = -1;
2013
2014   /* only forward streaming and seeking is possible */
2015   if (rate <= 0)
2016     goto unsupported_seek;
2017
2018   if (cur == 0) {
2019     /* handle rewind only */
2020     cur_type = GST_SEEK_TYPE_SET;
2021     byte_cur = 0;
2022     stop_type = GST_SEEK_TYPE_NONE;
2023     stop = -1;
2024     flags |= GST_SEEK_FLAG_FLUSH;
2025   } else {
2026     /* handle normal seek */
2027     cur_type = GST_SEEK_TYPE_SET;
2028     stop_type = GST_SEEK_TYPE_NONE;
2029     stop = -1;
2030     flags |= GST_SEEK_FLAG_FLUSH;
2031
2032     esimate_byte = (cur / (1000 * 1000)) * aacparse->frame_byte;
2033     if (aacparse->sample_rate > 0)
2034       frame_dur = (aacparse->spf * 1000) / aacparse->sample_rate;
2035     else
2036       goto unsupported_seek;
2037     if (frame_dur > 0)
2038       byte_cur = esimate_byte / (frame_dur);
2039     else
2040       goto unsupported_seek;
2041
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,
2049         frame_dur);
2050   }
2051
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;
2059
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);
2064     goto abort_seek;
2065   }
2066
2067   GST_INFO_OBJECT (parse,
2068       "Pushing BYTE seek rate %g, " "start %" G_GINT64_FORMAT ", stop %"
2069       G_GINT64_FORMAT, rate, byte_cur, stop);
2070
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);
2075   }
2076
2077   /* BYTE seek event */
2078   event =
2079       gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, byte_cur,
2080       stop_type, stop);
2081   res = gst_pad_push_event (parse->sinkpad, event);
2082
2083   return res;
2084
2085   /* ERRORS */
2086
2087 abort_seek:
2088   {
2089     GST_DEBUG_OBJECT (parse,
2090         "could not determine byte position to seek to, " "seek aborted.");
2091     return FALSE;
2092   }
2093
2094 unsupported_seek:
2095   {
2096     GST_DEBUG_OBJECT (parse, "unsupported seek, seek aborted.");
2097     return FALSE;
2098   }
2099 }
2100
2101
2102 static guint
2103 gst_aac_parse_adts_get_fast_frame_len (const guint8 * data)
2104 {
2105   int length;
2106   if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
2107     length =
2108         ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
2109   } else {
2110     length = 0;
2111   }
2112   return length;
2113 }
2114
2115 /**
2116  * gst_aac_parse_adts_src_eventfunc:
2117  * @parse: #GstBaseParse. #event
2118  *
2119  * before baseparse handles seek event, make full amr index table.
2120  *
2121  * Returns: TRUE on success.
2122  */
2123 static gboolean
2124 gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
2125 {
2126   gboolean handled = FALSE;
2127   GstAacParse *aacparse = GST_AAC_PARSE (parse);
2128
2129   switch (GST_EVENT_TYPE (event)) {
2130     case GST_EVENT_SEEK:
2131     {
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;
2139
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.");
2146         /* check NULL */
2147         if (aacparse->byte_seekable)
2148           return gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
2149
2150         GST_INFO_OBJECT (aacparse, "not support byte seek");
2151         goto aac_seek_null_exit;
2152       }
2153
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, &current_ts);
2157
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;
2162       }
2163
2164       GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK enter");
2165
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,
2169             total_file_size);
2170         break;
2171       }
2172
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));
2178         break;
2179       } else {
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));
2183       }
2184
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));
2189
2190       base_offset = start_offset;       /* set base by start offset */
2191       second_count = current_ts + GST_SECOND;   /* 1sec */
2192
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) */
2199
2200       /************************************/
2201       /* STEP 1: MAX_PULL_RANGE_BUF cycle */
2202       /************************************/
2203       while (total_file_size - base_offset >= AAC_MAX_PULL_RANGE_BUF) {
2204         gint64 offset = 0;
2205         GstBuffer *buffer = NULL;
2206         guint8 *buf = NULL;
2207         GstMapInfo map;
2208         GST_INFO ("gst_pad_pull_range %d bytes (from %" G_GINT64_FORMAT
2209             ") use max size", AAC_MAX_PULL_RANGE_BUF, base_offset);
2210         res =
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!");
2215           break;
2216         }
2217
2218         gst_buffer_map (buffer, &map, GST_MAP_READ);
2219         buf = map.data;
2220         if (buf == NULL) {
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;
2225         }
2226
2227         while (offset <= AAC_MAX_PULL_RANGE_BUF) {
2228           gint frame_size = 0;
2229
2230           /* make sure the values in the frame header look sane */
2231           frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2232
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 */
2241             }
2242
2243             current_ts += (aacparse->frame_duration * GST_MSECOND) / 100;       /* each frame is (frame_duration) ms */
2244             offset += frame_size;
2245             buf += frame_size;
2246             frame_count++;
2247           } else if (frame_size >= (AAC_MAX_PULL_RANGE_BUF - offset)) {
2248             GST_DEBUG ("we need refill buffer");
2249             break;
2250           } else {
2251             GST_WARNING ("we lost sync");
2252             buf++;
2253             offset++;
2254           }
2255         }                       /* while */
2256
2257         base_offset = base_offset + offset;
2258
2259         gst_buffer_unmap (buffer, &map);
2260         gst_buffer_unref (buffer);
2261       }                         /* end MAX buffer cycle */
2262
2263       /*******************************/
2264       /* STEP 2: Remain Buffer cycle */
2265       /*******************************/
2266       if (total_file_size - base_offset > 0) {
2267         gint64 offset = 0;
2268         GstBuffer *buffer = NULL;
2269         guint8 *buf = NULL;
2270         GstMapInfo map;
2271
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);
2275         res =
2276             gst_pad_pull_range (parse->sinkpad, base_offset, total_file_size,
2277             &buffer);
2278         if (res != GST_FLOW_OK) {
2279           GST_ERROR ("gst_pad_pull_range failed!");
2280           break;
2281         }
2282
2283         gst_buffer_map (buffer, &map, GST_MAP_READ);
2284         buf = map.data;
2285         if (buf == NULL) {
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;
2290         }
2291
2292         while (base_offset + offset < total_file_size) {
2293           gint frame_size = 0;
2294
2295           /* make sure the values in the frame header look sane */
2296           frame_size = gst_aac_parse_adts_get_fast_frame_len (buf);
2297
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 */
2306             }
2307
2308             current_ts += (aacparse->frame_duration * GST_MSECOND) / 100;       /* each frame is (frame_duration) ms */
2309             offset += frame_size;
2310             buf += frame_size;
2311             frame_count++;
2312           } else if (frame_size == 0) {
2313             GST_DEBUG ("Frame size is 0 so, Decoding end..");
2314             break;
2315           } else {
2316             GST_WARNING ("we lost sync");
2317             buf++;
2318             offset++;
2319           }
2320         }                       /* while */
2321
2322         gst_buffer_unmap (buffer, &map);
2323         gst_buffer_unref (buffer);
2324       }
2325       /* end remain_buf buffer cycle */
2326       GST_DEBUG ("gst_aac_parse_adts_src_eventfunc GST_EVENT_SEEK leave");
2327     }
2328       break;
2329
2330     default:
2331       break;
2332   }
2333
2334 aac_seek_null_exit:
2335
2336   /* call baseparse src_event function to handle event */
2337   handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
2338   return handled;
2339 }
2340
2341 static void
2342 gst_aac_parse_check_byte_seekability (GstBaseParse * parse)
2343 {
2344   GstQuery *query;
2345   gboolean seekable = FALSE;
2346   GstAacParse *aacparse = GST_AAC_PARSE (parse);
2347   GST_LOG_OBJECT (aacparse, "gst_aac_parse_check_byte_seekability enter");
2348
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);
2352   else
2353     GST_DEBUG_OBJECT (aacparse, "seeking query failed");
2354
2355   gst_query_unref (query);
2356
2357   GST_INFO_OBJECT (aacparse, "byte seekable: %d", seekable);
2358
2359   aacparse->byte_seekable = seekable;
2360 }
2361 #endif /* TIZEN_FEATURE_AACPARSE_MODIFICATION */