upload tizen1.0 source
[framework/multimedia/gst-plugins-good0.10.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., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:element-aacparse
24  * @short_description: AAC parser
25  * @see_also: #GstAmrParse
26  *
27  * This is an AAC parser which handles both ADIF and ADTS stream formats.
28  *
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.
32  *
33  * <refsect2>
34  * <title>Example launch line</title>
35  * |[
36  * gst-launch filesrc location=abc.aac ! aacparse ! faad ! audioresample ! audioconvert ! alsasink
37  * ]|
38  * </refsect2>
39  */
40
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
44
45 #include <string.h>
46
47 #include "gstaacparse.h"
48
49
50 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
51     GST_PAD_SRC,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("audio/mpeg, "
54         "framed = (boolean) true, " "mpegversion = (int) { 2, 4 }, "
55         "stream-format = (string) { raw, adts, adif };"));
56
57 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
58     GST_PAD_SINK,
59     GST_PAD_ALWAYS,
60     GST_STATIC_CAPS ("audio/mpeg, "
61         "framed = (boolean) false, " "mpegversion = (int) { 2, 4 };"));
62
63 GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
64 #define GST_CAT_DEFAULT aacparse_debug
65
66
67 #define ADIF_MAX_SIZE 40        /* Should be enough */
68 #define ADTS_MAX_SIZE 10        /* Should be enough */
69
70
71 #define AAC_FRAME_DURATION(parse) (GST_SECOND/parse->frames_per_sec)
72
73 gboolean gst_aac_parse_start (GstBaseParse * parse);
74 gboolean gst_aac_parse_stop (GstBaseParse * parse);
75
76 static gboolean gst_aac_parse_sink_setcaps (GstBaseParse * parse,
77     GstCaps * caps);
78
79 gboolean gst_aac_parse_check_valid_frame (GstBaseParse * parse,
80     GstBaseParseFrame * frame, guint * size, gint * skipsize);
81
82 GstFlowReturn gst_aac_parse_parse_frame (GstBaseParse * parse,
83     GstBaseParseFrame * frame);
84
85 gboolean gst_aac_parse_convert (GstBaseParse * parse,
86     GstFormat src_format,
87     gint64 src_value, GstFormat dest_format, gint64 * dest_value);
88
89 gint gst_aac_parse_get_frame_overhead (GstBaseParse * parse,
90     GstBuffer * buffer);
91
92 gboolean gst_aac_parse_event (GstBaseParse * parse, GstEvent * event);
93
94 #define _do_init(bla) \
95     GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0, \
96     "AAC audio stream parser");
97
98 GST_BOILERPLATE_FULL (GstAacParse, gst_aac_parse, GstBaseParse,
99     GST_TYPE_BASE_PARSE, _do_init);
100
101 static inline gint
102 gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
103 {
104   static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
105     32000, 24000, 22050, 16000, 12000, 11025, 8000
106   };
107
108   if (sr_idx < G_N_ELEMENTS (aac_sample_rates))
109     return aac_sample_rates[sr_idx];
110   GST_WARNING ("Invalid sample rate index %u", sr_idx);
111   return 0;
112 }
113
114 /**
115  * gst_aac_parse_base_init:
116  * @klass: #GstElementClass.
117  *
118  */
119 static void
120 gst_aac_parse_base_init (gpointer klass)
121 {
122   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
123
124   gst_element_class_add_pad_template (element_class,
125       gst_static_pad_template_get (&sink_template));
126   gst_element_class_add_pad_template (element_class,
127       gst_static_pad_template_get (&src_template));
128
129   gst_element_class_set_details_simple (element_class,
130       "AAC audio stream parser", "Codec/Parser/Audio",
131       "Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
132 }
133
134
135 /**
136  * gst_aac_parse_class_init:
137  * @klass: #GstAacParseClass.
138  *
139  */
140 static void
141 gst_aac_parse_class_init (GstAacParseClass * klass)
142 {
143   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
144
145   parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
146   parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
147   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aac_parse_sink_setcaps);
148   parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aac_parse_parse_frame);
149   parse_class->check_valid_frame =
150       GST_DEBUG_FUNCPTR (gst_aac_parse_check_valid_frame);
151 }
152
153
154 /**
155  * gst_aac_parse_init:
156  * @aacparse: #GstAacParse.
157  * @klass: #GstAacParseClass.
158  *
159  */
160 static void
161 gst_aac_parse_init (GstAacParse * aacparse, GstAacParseClass * klass)
162 {
163   GST_DEBUG ("initialized");
164 }
165
166
167 /**
168  * gst_aac_parse_set_src_caps:
169  * @aacparse: #GstAacParse.
170  * @sink_caps: (proposed) caps of sink pad
171  *
172  * Set source pad caps according to current knowledge about the
173  * audio stream.
174  *
175  * Returns: TRUE if caps were successfully set.
176  */
177 static gboolean
178 gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
179 {
180   GstStructure *s;
181   GstCaps *src_caps = NULL;
182   gboolean res = FALSE;
183   const gchar *stream_format;
184
185   GST_DEBUG_OBJECT (aacparse, "sink caps: %" GST_PTR_FORMAT, sink_caps);
186   if (sink_caps)
187     src_caps = gst_caps_copy (sink_caps);
188   else
189     src_caps = gst_caps_new_simple ("audio/mpeg", NULL);
190
191   gst_caps_set_simple (src_caps, "framed", G_TYPE_BOOLEAN, TRUE,
192       "mpegversion", G_TYPE_INT, aacparse->mpegversion, NULL);
193
194   switch (aacparse->header_type) {
195     case DSPAAC_HEADER_NONE:
196       stream_format = "raw";
197       break;
198     case DSPAAC_HEADER_ADTS:
199       stream_format = "adts";
200       break;
201     case DSPAAC_HEADER_ADIF:
202       stream_format = "adif";
203       break;
204     default:
205       stream_format = NULL;
206   }
207
208   s = gst_caps_get_structure (src_caps, 0);
209   if (aacparse->sample_rate > 0)
210     gst_structure_set (s, "rate", G_TYPE_INT, aacparse->sample_rate, NULL);
211   if (aacparse->channels > 0)
212     gst_structure_set (s, "channels", G_TYPE_INT, aacparse->channels, NULL);
213   if (stream_format)
214     gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
215
216   GST_DEBUG_OBJECT (aacparse, "setting src caps: %" GST_PTR_FORMAT, src_caps);
217
218   res = gst_pad_set_caps (GST_BASE_PARSE (aacparse)->srcpad, src_caps);
219   gst_caps_unref (src_caps);
220   return res;
221 }
222
223
224 /**
225  * gst_aac_parse_sink_setcaps:
226  * @sinkpad: GstPad
227  * @caps: GstCaps
228  *
229  * Implementation of "set_sink_caps" vmethod in #GstBaseParse class.
230  *
231  * Returns: TRUE on success.
232  */
233 static gboolean
234 gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
235 {
236   GstAacParse *aacparse;
237   GstStructure *structure;
238   gchar *caps_str;
239   const GValue *value;
240
241   aacparse = GST_AAC_PARSE (parse);
242   structure = gst_caps_get_structure (caps, 0);
243   caps_str = gst_caps_to_string (caps);
244
245   GST_DEBUG_OBJECT (aacparse, "setcaps: %s", caps_str);
246   g_free (caps_str);
247
248   /* This is needed at least in case of RTP
249    * Parses the codec_data information to get ObjectType,
250    * number of channels and samplerate */
251   value = gst_structure_get_value (structure, "codec_data");
252   if (value) {
253     GstBuffer *buf = gst_value_get_buffer (value);
254
255     if (buf) {
256       const guint8 *buffer = GST_BUFFER_DATA (buf);
257       guint sr_idx;
258
259       sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7);
260       aacparse->object_type = (buffer[0] & 0xf8) >> 3;
261       aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
262       aacparse->channels = (buffer[1] & 0x78) >> 3;
263       aacparse->header_type = DSPAAC_HEADER_NONE;
264       aacparse->mpegversion = 4;
265
266       GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d",
267           aacparse->object_type, aacparse->sample_rate, aacparse->channels);
268
269       /* arrange for metadata and get out of the way */
270       gst_aac_parse_set_src_caps (aacparse, caps);
271       gst_base_parse_set_passthrough (parse, TRUE);
272     } else
273       return FALSE;
274
275     /* caps info overrides */
276     gst_structure_get_int (structure, "rate", &aacparse->sample_rate);
277     gst_structure_get_int (structure, "channels", &aacparse->channels);
278   } else {
279     gst_base_parse_set_passthrough (parse, FALSE);
280   }
281
282   return TRUE;
283 }
284
285
286 /**
287  * gst_aac_parse_adts_get_frame_len:
288  * @data: block of data containing an ADTS header.
289  *
290  * This function calculates ADTS frame length from the given header.
291  *
292  * Returns: size of the ADTS frame.
293  */
294 static inline guint
295 gst_aac_parse_adts_get_frame_len (const guint8 * data)
296 {
297   return ((data[3] & 0x03) << 11) | (data[4] << 3) | ((data[5] & 0xe0) >> 5);
298 }
299
300
301 /**
302  * gst_aac_parse_check_adts_frame:
303  * @aacparse: #GstAacParse.
304  * @data: Data to be checked.
305  * @avail: Amount of data passed.
306  * @framesize: If valid ADTS frame was found, this will be set to tell the
307  *             found frame size in bytes.
308  * @needed_data: If frame was not found, this may be set to tell how much
309  *               more data is needed in the next round to detect the frame
310  *               reliably. This may happen when a frame header candidate
311  *               is found but it cannot be guaranteed to be the header without
312  *               peeking the following data.
313  *
314  * Check if the given data contains contains ADTS frame. The algorithm
315  * will examine ADTS frame header and calculate the frame size. Also, another
316  * consecutive ADTS frame header need to be present after the found frame.
317  * Otherwise the data is not considered as a valid ADTS frame. However, this
318  * "extra check" is omitted when EOS has been received. In this case it is
319  * enough when data[0] contains a valid ADTS header.
320  *
321  * This function may set the #needed_data to indicate that a possible frame
322  * candidate has been found, but more data (#needed_data bytes) is needed to
323  * be absolutely sure. When this situation occurs, FALSE will be returned.
324  *
325  * When a valid frame is detected, this function will use
326  * gst_base_parse_set_min_frame_size() function from #GstBaseParse class
327  * to set the needed bytes for next frame.This way next data chunk is already
328  * of correct size.
329  *
330  * Returns: TRUE if the given data contains a valid ADTS header.
331  */
332 static gboolean
333 gst_aac_parse_check_adts_frame (GstAacParse * aacparse,
334     const guint8 * data, const guint avail, gboolean drain,
335     guint * framesize, guint * needed_data)
336 {
337   if (G_UNLIKELY (avail < 2))
338     return FALSE;
339
340   if ((data[0] == 0xff) && ((data[1] & 0xf6) == 0xf0)) {
341     *framesize = gst_aac_parse_adts_get_frame_len (data);
342
343     /* In EOS mode this is enough. No need to examine the data further */
344     if (drain) {
345       return TRUE;
346     }
347
348     if (*framesize + ADTS_MAX_SIZE > avail) {
349       /* We have found a possible frame header candidate, but can't be
350          sure since we don't have enough data to check the next frame */
351       GST_DEBUG ("NEED MORE DATA: we need %d, available %d",
352           *framesize + ADTS_MAX_SIZE, avail);
353       *needed_data = *framesize + ADTS_MAX_SIZE;
354       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
355           *framesize + ADTS_MAX_SIZE);
356       return FALSE;
357     }
358
359     if ((data[*framesize] == 0xff) && ((data[*framesize + 1] & 0xf6) == 0xf0)) {
360       guint nextlen = gst_aac_parse_adts_get_frame_len (data + (*framesize));
361
362       GST_LOG ("ADTS frame found, len: %d bytes", *framesize);
363       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
364           nextlen + ADTS_MAX_SIZE);
365       return TRUE;
366     }
367   }
368   return FALSE;
369 }
370
371 /* caller ensure sufficient data */
372 static inline void
373 gst_aac_parse_parse_adts_header (GstAacParse * aacparse, const guint8 * data,
374     gint * rate, gint * channels, gint * object, gint * version)
375 {
376
377   if (rate) {
378     gint sr_idx = (data[2] & 0x3c) >> 2;
379
380     *rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
381   }
382   if (channels)
383     *channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
384
385   if (version)
386     *version = (data[1] & 0x08) ? 2 : 4;
387   if (object)
388     *object = (data[2] & 0xc0) >> 6;
389 }
390
391 /**
392  * gst_aac_parse_detect_stream:
393  * @aacparse: #GstAacParse.
394  * @data: A block of data that needs to be examined for stream characteristics.
395  * @avail: Size of the given datablock.
396  * @framesize: If valid stream was found, this will be set to tell the
397  *             first frame size in bytes.
398  * @skipsize: If valid stream was found, this will be set to tell the first
399  *            audio frame position within the given data.
400  *
401  * Examines the given piece of data and try to detect the format of it. It
402  * checks for "ADIF" header (in the beginning of the clip) and ADTS frame
403  * header. If the stream is detected, TRUE will be returned and #framesize
404  * is set to indicate the found frame size. Additionally, #skipsize might
405  * be set to indicate the number of bytes that need to be skipped, a.k.a. the
406  * position of the frame inside given data chunk.
407  *
408  * Returns: TRUE on success.
409  */
410 static gboolean
411 gst_aac_parse_detect_stream (GstAacParse * aacparse,
412     const guint8 * data, const guint avail, gboolean drain,
413     guint * framesize, gint * skipsize)
414 {
415   gboolean found = FALSE;
416   guint need_data = 0;
417   guint i = 0;
418
419   GST_DEBUG_OBJECT (aacparse, "Parsing header data");
420
421   /* FIXME: No need to check for ADIF if we are not in the beginning of the
422      stream */
423
424   /* Can we even parse the header? */
425   if (avail < ADTS_MAX_SIZE)
426     return FALSE;
427
428   for (i = 0; i < avail - 4; i++) {
429     if (((data[i] == 0xff) && ((data[i + 1] & 0xf6) == 0xf0)) ||
430         strncmp ((char *) data + i, "ADIF", 4) == 0) {
431       found = TRUE;
432
433       if (i) {
434         /* Trick: tell the parent class that we didn't find the frame yet,
435            but make it skip 'i' amount of bytes. Next time we arrive
436            here we have full frame in the beginning of the data. */
437         *skipsize = i;
438         return FALSE;
439       }
440       break;
441     }
442   }
443   if (!found) {
444     if (i)
445       *skipsize = i;
446     return FALSE;
447   }
448
449   if (gst_aac_parse_check_adts_frame (aacparse, data, avail, drain,
450           framesize, &need_data)) {
451     gint rate, channels;
452
453     GST_INFO ("ADTS ID: %d, framesize: %d", (data[1] & 0x08) >> 3, *framesize);
454
455     aacparse->header_type = DSPAAC_HEADER_ADTS;
456     gst_aac_parse_parse_adts_header (aacparse, data, &rate, &channels,
457         &aacparse->object_type, &aacparse->mpegversion);
458
459     gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse), rate, 1024, 2, 2);
460
461     GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d, version %d",
462         rate, channels, aacparse->object_type, aacparse->mpegversion);
463
464     gst_base_parse_set_syncable (GST_BASE_PARSE (aacparse), TRUE);
465
466     return TRUE;
467   } else if (need_data) {
468     /* This tells the parent class not to skip any data */
469     *skipsize = 0;
470     return FALSE;
471   }
472
473   if (avail < ADIF_MAX_SIZE)
474     return FALSE;
475
476   if (memcmp (data + i, "ADIF", 4) == 0) {
477     const guint8 *adif;
478     int skip_size = 0;
479     int bitstream_type;
480     int sr_idx;
481
482     aacparse->header_type = DSPAAC_HEADER_ADIF;
483     aacparse->mpegversion = 4;
484
485     /* Skip the "ADIF" bytes */
486     adif = data + i + 4;
487
488     /* copyright string */
489     if (adif[0] & 0x80)
490       skip_size += 9;           /* skip 9 bytes */
491
492     bitstream_type = adif[0 + skip_size] & 0x10;
493     aacparse->bitrate =
494         ((unsigned int) (adif[0 + skip_size] & 0x0f) << 19) |
495         ((unsigned int) adif[1 + skip_size] << 11) |
496         ((unsigned int) adif[2 + skip_size] << 3) |
497         ((unsigned int) adif[3 + skip_size] & 0xe0);
498
499     /* CBR */
500     if (bitstream_type == 0) {
501 #if 0
502       /* Buffer fullness parsing. Currently not needed... */
503       guint num_elems = 0;
504       guint fullness = 0;
505
506       num_elems = (adif[3 + skip_size] & 0x1e);
507       GST_INFO ("ADIF num_config_elems: %d", num_elems);
508
509       fullness = ((unsigned int) (adif[3 + skip_size] & 0x01) << 19) |
510           ((unsigned int) adif[4 + skip_size] << 11) |
511           ((unsigned int) adif[5 + skip_size] << 3) |
512           ((unsigned int) (adif[6 + skip_size] & 0xe0) >> 5);
513
514       GST_INFO ("ADIF buffer fullness: %d", fullness);
515 #endif
516       aacparse->object_type = ((adif[6 + skip_size] & 0x01) << 1) |
517           ((adif[7 + skip_size] & 0x80) >> 7);
518       sr_idx = (adif[7 + skip_size] & 0x78) >> 3;
519     }
520     /* VBR */
521     else {
522       aacparse->object_type = (adif[4 + skip_size] & 0x18) >> 3;
523       sr_idx = ((adif[4 + skip_size] & 0x07) << 1) |
524           ((adif[5 + skip_size] & 0x80) >> 7);
525     }
526
527     /* FIXME: This gives totally wrong results. Duration calculation cannot
528        be based on this */
529     aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
530
531     /* baseparse is not given any fps,
532      * so it will give up on timestamps, seeking, etc */
533
534     /* FIXME: Can we assume this? */
535     aacparse->channels = 2;
536
537     GST_INFO ("ADIF: br=%d, samplerate=%d, objtype=%d",
538         aacparse->bitrate, aacparse->sample_rate, aacparse->object_type);
539
540     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 512);
541
542     /* arrange for metadata and get out of the way */
543     gst_aac_parse_set_src_caps (aacparse,
544         GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse)));
545
546     /* not syncable, not easily seekable (unless we push data from start */
547     gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (aacparse), FALSE);
548     gst_base_parse_set_passthrough (GST_BASE_PARSE_CAST (aacparse), TRUE);
549     gst_base_parse_set_average_bitrate (GST_BASE_PARSE_CAST (aacparse), 0);
550
551     *framesize = avail;
552     return TRUE;
553   }
554
555   /* This should never happen */
556   return FALSE;
557 }
558
559
560 /**
561  * gst_aac_parse_check_valid_frame:
562  * @parse: #GstBaseParse.
563  * @buffer: #GstBuffer.
564  * @framesize: If the buffer contains a valid frame, its size will be put here
565  * @skipsize: How much data parent class should skip in order to find the
566  *            frame header.
567  *
568  * Implementation of "check_valid_frame" vmethod in #GstBaseParse class.
569  *
570  * Returns: TRUE if buffer contains a valid frame.
571  */
572 gboolean
573 gst_aac_parse_check_valid_frame (GstBaseParse * parse,
574     GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
575 {
576   const guint8 *data;
577   GstAacParse *aacparse;
578   gboolean ret = FALSE;
579   gboolean lost_sync;
580   GstBuffer *buffer;
581
582   aacparse = GST_AAC_PARSE (parse);
583   buffer = frame->buffer;
584   data = GST_BUFFER_DATA (buffer);
585
586   lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
587
588   if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
589       aacparse->header_type == DSPAAC_HEADER_NONE) {
590     /* There is nothing to parse */
591     *framesize = GST_BUFFER_SIZE (buffer);
592     ret = TRUE;
593
594   } else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
595
596     ret = gst_aac_parse_detect_stream (aacparse, data, GST_BUFFER_SIZE (buffer),
597         GST_BASE_PARSE_DRAINING (parse), framesize, skipsize);
598
599   } else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
600     guint needed_data = 1024;
601
602     ret = gst_aac_parse_check_adts_frame (aacparse, data,
603         GST_BUFFER_SIZE (buffer), GST_BASE_PARSE_DRAINING (parse),
604         framesize, &needed_data);
605
606     if (!ret) {
607       GST_DEBUG ("buffer didn't contain valid frame");
608       gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse),
609           needed_data);
610     }
611
612   } else {
613     GST_DEBUG ("buffer didn't contain valid frame");
614     gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
615   }
616
617   return ret;
618 }
619
620
621 /**
622  * gst_aac_parse_parse_frame:
623  * @parse: #GstBaseParse.
624  * @buffer: #GstBuffer.
625  *
626  * Implementation of "parse_frame" vmethod in #GstBaseParse class.
627  *
628  * Also determines frame overhead.
629  * ADTS streams have a 7 byte header in each frame. MP4 and ADIF streams don't have
630  * a per-frame header.
631  *
632  * We're making a couple of simplifying assumptions:
633  *
634  * 1. We count Program Configuration Elements rather than searching for them
635  *    in the streams to discount them - the overhead is negligible.
636  *
637  * 2. We ignore CRC. This has a worst-case impact of (num_raw_blocks + 1)*16
638  *    bits, which should still not be significant enough to warrant the
639  *    additional parsing through the headers
640  *
641  * Returns: GST_FLOW_OK if frame was successfully parsed and can be pushed
642  *          forward. Otherwise appropriate error is returned.
643  */
644 GstFlowReturn
645 gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
646 {
647   GstAacParse *aacparse;
648   GstBuffer *buffer;
649   GstFlowReturn ret = GST_FLOW_OK;
650   gint rate, channels;
651
652   aacparse = GST_AAC_PARSE (parse);
653   buffer = frame->buffer;
654
655   if (G_UNLIKELY (aacparse->header_type != DSPAAC_HEADER_ADTS))
656     return ret;
657
658   /* see above */
659   frame->overhead = 7;
660
661   gst_aac_parse_parse_adts_header (aacparse, GST_BUFFER_DATA (buffer),
662       &rate, &channels, NULL, NULL);
663   GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
664
665   if (G_UNLIKELY (rate != aacparse->sample_rate
666           || channels != aacparse->channels)) {
667     aacparse->sample_rate = rate;
668     aacparse->channels = channels;
669
670     if (!gst_aac_parse_set_src_caps (aacparse,
671             GST_PAD_CAPS (GST_BASE_PARSE (aacparse)->sinkpad))) {
672       /* If linking fails, we need to return appropriate error */
673       ret = GST_FLOW_NOT_LINKED;
674     }
675
676     gst_base_parse_set_frame_rate (GST_BASE_PARSE (aacparse),
677         aacparse->sample_rate, 1024, 2, 2);
678   }
679
680   return ret;
681 }
682
683
684 /**
685  * gst_aac_parse_start:
686  * @parse: #GstBaseParse.
687  *
688  * Implementation of "start" vmethod in #GstBaseParse class.
689  *
690  * Returns: TRUE if startup succeeded.
691  */
692 gboolean
693 gst_aac_parse_start (GstBaseParse * parse)
694 {
695   GstAacParse *aacparse;
696
697   aacparse = GST_AAC_PARSE (parse);
698   GST_DEBUG ("start");
699   gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
700   return TRUE;
701 }
702
703
704 /**
705  * gst_aac_parse_stop:
706  * @parse: #GstBaseParse.
707  *
708  * Implementation of "stop" vmethod in #GstBaseParse class.
709  *
710  * Returns: TRUE is stopping succeeded.
711  */
712 gboolean
713 gst_aac_parse_stop (GstBaseParse * parse)
714 {
715   GST_DEBUG ("stop");
716   return TRUE;
717 }