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