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