1 /* GStreamer FAAD (Free AAC Decoder) plugin
2  * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
3  * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 /**
22  * SECTION:element-faad
23  * @title: faad
24  * @seealso: faac
25  *
26  * faad decodes AAC (MPEG-4 part 3) stream.
27  *
28  * ## Example launch lines
29  * |[
30  * gst-launch-1.0 filesrc location=example.mp4 ! qtdemux ! faad ! audioconvert ! audioresample ! autoaudiosink
31  * ]| Play aac from mp4 file.
32  * |[
33  * gst-launch-1.0 filesrc location=example.adts ! faad ! audioconvert ! audioresample ! autoaudiosink
34  * ]| Play standalone aac bitstream.
35  *
36  */
37 
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 
42 #include <string.h>
43 #include <gst/audio/audio.h>
44 
45 #include "gstfaad.h"
46 
47 GST_DEBUG_CATEGORY_STATIC (faad_debug);
48 #define GST_CAT_DEFAULT faad_debug
49 
50 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("audio/mpeg, " "mpegversion = (int) 2; "
54         "audio/mpeg, mpegversion = (int) 4, stream-format = (string) { raw, adts }")
55     );
56 
57 #define STATIC_RAW_CAPS(format) \
58   "audio/x-raw, " \
59     "format = (string) "GST_AUDIO_NE(format)", " \
60     "layout = (string) interleaved, " \
61     "rate = (int) [ 8000, 96000 ], " \
62     "channels = (int) [ 1, 8 ]"
63 
64 /*
65  * All except 16-bit integer are disabled until someone fixes FAAD.
66  * FAAD allocates approximately 8*1024*2 bytes bytes, which is enough
67  * for 1 frame (1024 samples) of 6 channel (5.1) 16-bit integer 16bpp
68  * audio, but not for any other. You'll get random segfaults, crashes
69  * and even valgrind goes crazy.
70  */
71 
72 #define STATIC_CAPS \
73   STATIC_RAW_CAPS (S16)
74 #if 0
75 #define NOTUSED "; " \
76 STATIC_RAW_CAPS (S24) \
77     "; " \
78 STATIC_RAW_CAPS (S32) \
79     "; " \
80 STATIC_RAW_CAPS (F32) \
81     "; " \
82 STATIC_RAW_CAPS (F64)
83 #endif
84 
85 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
86     GST_PAD_SRC,
87     GST_PAD_ALWAYS,
88     GST_STATIC_CAPS (STATIC_CAPS)
89     );
90 
91 static void gst_faad_reset (GstFaad * faad);
92 
93 static gboolean gst_faad_start (GstAudioDecoder * dec);
94 static gboolean gst_faad_stop (GstAudioDecoder * dec);
95 static gboolean gst_faad_set_format (GstAudioDecoder * dec, GstCaps * caps);
96 static GstFlowReturn gst_faad_parse (GstAudioDecoder * dec,
97     GstAdapter * adapter, gint * offset, gint * length);
98 static GstFlowReturn gst_faad_handle_frame (GstAudioDecoder * dec,
99     GstBuffer * buffer);
100 static void gst_faad_flush (GstAudioDecoder * dec, gboolean hard);
101 
102 static gboolean gst_faad_open_decoder (GstFaad * faad);
103 static void gst_faad_close_decoder (GstFaad * faad);
104 
105 #define gst_faad_parent_class parent_class
106 G_DEFINE_TYPE (GstFaad, gst_faad, GST_TYPE_AUDIO_DECODER);
107 
108 static void
gst_faad_class_init(GstFaadClass * klass)109 gst_faad_class_init (GstFaadClass * klass)
110 {
111   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
112   GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
113 
114   gst_element_class_add_static_pad_template (element_class, &src_template);
115   gst_element_class_add_static_pad_template (element_class, &sink_template);
116 
117   gst_element_class_set_static_metadata (element_class, "AAC audio decoder",
118       "Codec/Decoder/Audio",
119       "Free MPEG-2/4 AAC decoder",
120       "Ronald Bultje <rbultje@ronald.bitfreak.net>");
121 
122   base_class->start = GST_DEBUG_FUNCPTR (gst_faad_start);
123   base_class->stop = GST_DEBUG_FUNCPTR (gst_faad_stop);
124   base_class->set_format = GST_DEBUG_FUNCPTR (gst_faad_set_format);
125   base_class->parse = GST_DEBUG_FUNCPTR (gst_faad_parse);
126   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_faad_handle_frame);
127   base_class->flush = GST_DEBUG_FUNCPTR (gst_faad_flush);
128 
129   GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
130 }
131 
132 static void
gst_faad_init(GstFaad * faad)133 gst_faad_init (GstFaad * faad)
134 {
135   gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
136       (faad), TRUE);
137   GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (faad));
138   gst_faad_reset (faad);
139 }
140 
141 static void
gst_faad_reset_stream_state(GstFaad * faad)142 gst_faad_reset_stream_state (GstFaad * faad)
143 {
144   if (faad->handle)
145     faacDecPostSeekReset (faad->handle, 0);
146 }
147 
148 static void
gst_faad_reset(GstFaad * faad)149 gst_faad_reset (GstFaad * faad)
150 {
151   faad->samplerate = -1;
152   faad->channels = -1;
153   faad->init = FALSE;
154   faad->packetised = FALSE;
155   g_free (faad->channel_positions);
156   faad->channel_positions = NULL;
157   faad->last_header = 0;
158 
159   gst_faad_reset_stream_state (faad);
160 }
161 
162 static gboolean
gst_faad_start(GstAudioDecoder * dec)163 gst_faad_start (GstAudioDecoder * dec)
164 {
165   GstFaad *faad = GST_FAAD (dec);
166 
167   GST_DEBUG_OBJECT (dec, "start");
168   gst_faad_reset (faad);
169 
170   /* call upon legacy upstream byte support (e.g. seeking) */
171   gst_audio_decoder_set_estimate_rate (dec, TRUE);
172   /* never mind a few errors */
173   gst_audio_decoder_set_max_errors (dec, 10);
174 
175   return TRUE;
176 }
177 
178 static gboolean
gst_faad_stop(GstAudioDecoder * dec)179 gst_faad_stop (GstAudioDecoder * dec)
180 {
181   GstFaad *faad = GST_FAAD (dec);
182 
183   GST_DEBUG_OBJECT (dec, "stop");
184   gst_faad_reset (faad);
185   gst_faad_close_decoder (faad);
186 
187   return TRUE;
188 }
189 
190 static gint
aac_rate_idx(gint rate)191 aac_rate_idx (gint rate)
192 {
193   if (92017 <= rate)
194     return 0;
195   else if (75132 <= rate)
196     return 1;
197   else if (55426 <= rate)
198     return 2;
199   else if (46009 <= rate)
200     return 3;
201   else if (37566 <= rate)
202     return 4;
203   else if (27713 <= rate)
204     return 5;
205   else if (23004 <= rate)
206     return 6;
207   else if (18783 <= rate)
208     return 7;
209   else if (13856 <= rate)
210     return 8;
211   else if (11502 <= rate)
212     return 9;
213   else if (9391 <= rate)
214     return 10;
215   else
216     return 11;
217 }
218 
219 static gboolean
gst_faad_set_format(GstAudioDecoder * dec,GstCaps * caps)220 gst_faad_set_format (GstAudioDecoder * dec, GstCaps * caps)
221 {
222   GstFaad *faad = GST_FAAD (dec);
223   GstStructure *str = gst_caps_get_structure (caps, 0);
224   GstBuffer *buf;
225   const GValue *value;
226   GstMapInfo map;
227   guint8 *cdata;
228   gsize csize;
229 
230   /* clean up current decoder, rather than trying to reconfigure */
231   gst_faad_close_decoder (faad);
232 
233   /* Assume raw stream */
234   faad->packetised = FALSE;
235 
236   if ((value = gst_structure_get_value (str, "codec_data"))) {
237     unsigned long samplerate;
238     guint8 channels;
239 
240     /* We have codec data, means packetised stream */
241     faad->packetised = TRUE;
242 
243     buf = gst_value_get_buffer (value);
244     g_return_val_if_fail (buf != NULL, FALSE);
245 
246     gst_buffer_map (buf, &map, GST_MAP_READ);
247     cdata = map.data;
248     csize = map.size;
249 
250     if (csize < 2)
251       goto wrong_length;
252 
253     GST_DEBUG_OBJECT (faad,
254         "codec_data: object_type=%d, sample_rate=%d, channels=%d",
255         ((cdata[0] & 0xf8) >> 3),
256         (((cdata[0] & 0x07) << 1) | ((cdata[1] & 0x80) >> 7)),
257         ((cdata[1] & 0x78) >> 3));
258 
259     if (!gst_faad_open_decoder (faad))
260       goto open_failed;
261     /* someone forgot that char can be unsigned when writing the API */
262     if ((gint8) faacDecInit2 (faad->handle, cdata, csize, &samplerate,
263             &channels) < 0)
264       goto init_failed;
265 
266     if (channels != ((cdata[1] & 0x78) >> 3)) {
267       /* https://bugs.launchpad.net/ubuntu/+source/faad2/+bug/290259 */
268       GST_WARNING_OBJECT (faad,
269           "buggy faad version, wrong nr of channels %d instead of %d", channels,
270           ((cdata[1] & 0x78) >> 3));
271     }
272 
273     GST_DEBUG_OBJECT (faad, "codec_data init: channels=%u, rate=%u", channels,
274         (guint32) samplerate);
275 
276     /* not updating these here, so they are updated in the
277      * chain function, and new caps are created etc. */
278     faad->samplerate = 0;
279     faad->channels = 0;
280 
281     faad->init = TRUE;
282     gst_buffer_unmap (buf, &map);
283   } else if ((value = gst_structure_get_value (str, "framed")) &&
284       g_value_get_boolean (value) == TRUE) {
285     faad->packetised = TRUE;
286     faad->init = FALSE;
287     GST_DEBUG_OBJECT (faad, "we have packetized audio");
288   } else {
289     faad->init = FALSE;
290   }
291 
292   faad->fake_codec_data[0] = 0;
293   faad->fake_codec_data[1] = 0;
294 
295   if (faad->packetised && !faad->init) {
296     gint rate, channels;
297 
298     if (gst_structure_get_int (str, "rate", &rate) &&
299         gst_structure_get_int (str, "channels", &channels)) {
300       gint rate_idx, profile;
301 
302       profile = 3;              /* 0=MAIN, 1=LC, 2=SSR, 3=LTP */
303       rate_idx = aac_rate_idx (rate);
304 
305       faad->fake_codec_data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
306       faad->fake_codec_data[1] = ((rate_idx & 0x1) << 7) | (channels << 3);
307       GST_LOG_OBJECT (faad, "created fake codec data (%u,%u): 0x%x 0x%x", rate,
308           channels, (int) faad->fake_codec_data[0],
309           (int) faad->fake_codec_data[1]);
310     }
311   }
312 
313   return TRUE;
314 
315   /* ERRORS */
316 wrong_length:
317   {
318     GST_DEBUG_OBJECT (faad, "codec_data less than 2 bytes long");
319     gst_buffer_unmap (buf, &map);
320     return FALSE;
321   }
322 open_failed:
323   {
324     GST_DEBUG_OBJECT (faad, "failed to create decoder");
325     gst_buffer_unmap (buf, &map);
326     return FALSE;
327   }
328 init_failed:
329   {
330     GST_DEBUG_OBJECT (faad, "faacDecInit2() failed");
331     gst_buffer_unmap (buf, &map);
332     return FALSE;
333   }
334 }
335 
336 static gboolean
gst_faad_chanpos_to_gst(GstFaad * faad,guchar * fpos,GstAudioChannelPosition * pos,guint num)337 gst_faad_chanpos_to_gst (GstFaad * faad, guchar * fpos,
338     GstAudioChannelPosition * pos, guint num)
339 {
340   guint n;
341   gboolean unknown_channel = FALSE;
342 
343   /* special handling for the common cases for mono and stereo */
344   if (num == 1 && fpos[0] == FRONT_CHANNEL_CENTER) {
345     GST_DEBUG_OBJECT (faad, "mono common case; won't set channel positions");
346     pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
347     return TRUE;
348   } else if (num == 2 && fpos[0] == FRONT_CHANNEL_LEFT
349       && fpos[1] == FRONT_CHANNEL_RIGHT) {
350     GST_DEBUG_OBJECT (faad, "stereo common case; won't set channel positions");
351     pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
352     pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
353     return TRUE;
354   }
355 
356   for (n = 0; n < num; n++) {
357     GST_DEBUG_OBJECT (faad, "faad channel %d as %d", n, fpos[n]);
358     switch (fpos[n]) {
359       case FRONT_CHANNEL_LEFT:
360         pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
361         break;
362       case FRONT_CHANNEL_RIGHT:
363         pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
364         break;
365       case FRONT_CHANNEL_CENTER:
366         /* argh, mono = center */
367         if (num == 1)
368           pos[n] = GST_AUDIO_CHANNEL_POSITION_MONO;
369         else
370           pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
371         break;
372       case SIDE_CHANNEL_LEFT:
373         pos[n] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
374         break;
375       case SIDE_CHANNEL_RIGHT:
376         pos[n] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
377         break;
378       case BACK_CHANNEL_LEFT:
379         pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
380         break;
381       case BACK_CHANNEL_RIGHT:
382         pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
383         break;
384       case BACK_CHANNEL_CENTER:
385         pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
386         break;
387       case LFE_CHANNEL:
388         pos[n] = GST_AUDIO_CHANNEL_POSITION_LFE1;
389         break;
390       default:
391         GST_DEBUG_OBJECT (faad, "unknown channel %d at %d", fpos[n], n);
392         unknown_channel = TRUE;
393         break;
394     }
395   }
396   if (unknown_channel) {
397     switch (num) {
398       case 1:{
399         GST_DEBUG_OBJECT (faad,
400             "FAAD reports unknown 1 channel mapping. Forcing to mono");
401         pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
402         break;
403       }
404       case 2:{
405         GST_DEBUG_OBJECT (faad,
406             "FAAD reports unknown 2 channel mapping. Forcing to stereo");
407         pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
408         pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
409         break;
410       }
411       default:{
412         GST_WARNING_OBJECT (faad,
413             "Unsupported FAAD channel position 0x%x encountered", fpos[n]);
414         return FALSE;
415       }
416     }
417   }
418 
419   return TRUE;
420 }
421 
422 static gboolean
gst_faad_update_caps(GstFaad * faad,faacDecFrameInfo * info)423 gst_faad_update_caps (GstFaad * faad, faacDecFrameInfo * info)
424 {
425   gboolean ret;
426   gboolean fmt_change = FALSE;
427   GstAudioInfo ainfo;
428   gint i;
429   GstAudioChannelPosition position[6];
430 
431   /* see if we need to renegotiate */
432   if (info->samplerate != faad->samplerate ||
433       info->channels != faad->channels || !faad->channel_positions) {
434     fmt_change = TRUE;
435   } else {
436     for (i = 0; i < info->channels; i++) {
437       if (info->channel_position[i] != faad->channel_positions[i]) {
438         fmt_change = TRUE;
439         break;
440       }
441     }
442   }
443 
444   if (G_LIKELY (gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (faad))
445           && !fmt_change))
446     return TRUE;
447 
448 
449   /* store new negotiation information */
450   faad->samplerate = info->samplerate;
451   faad->channels = info->channels;
452   g_free (faad->channel_positions);
453   faad->channel_positions = g_memdup (info->channel_position, faad->channels);
454 
455   faad->bps = 16 / 8;
456 
457   if (!gst_faad_chanpos_to_gst (faad, faad->channel_positions,
458           faad->aac_positions, faad->channels)) {
459     GST_DEBUG_OBJECT (faad, "Could not map channel positions");
460     return FALSE;
461   }
462 
463   memcpy (position, faad->aac_positions, sizeof (position));
464   gst_audio_channel_positions_to_valid_order (position, faad->channels);
465   memcpy (faad->gst_positions, position,
466       faad->channels * sizeof (GstAudioChannelPosition));
467 
468   /* get the remap table */
469   memset (faad->reorder_map, 0, sizeof (faad->reorder_map));
470   faad->need_reorder = FALSE;
471   if (gst_audio_get_channel_reorder_map (faad->channels, faad->aac_positions,
472           faad->gst_positions, faad->reorder_map)) {
473     for (i = 0; i < faad->channels; i++) {
474       GST_DEBUG_OBJECT (faad, "remap %d -> %d", i, faad->reorder_map[i]);
475       if (faad->reorder_map[i] != i) {
476         faad->need_reorder = TRUE;
477       }
478     }
479   }
480 
481   /* FIXME: Use the GstAudioInfo of GstAudioDecoder for all of this */
482   gst_audio_info_init (&ainfo);
483   gst_audio_info_set_format (&ainfo, GST_AUDIO_FORMAT_S16, faad->samplerate,
484       faad->channels, position);
485 
486   ret = gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (faad), &ainfo);
487 
488   return ret;
489 }
490 
491 /*
492  * Find syncpoint in ADTS/ADIF stream. Doesn't work for raw,
493  * packetized streams. Be careful when calling.
494  * Returns FALSE on no-sync, fills offset/length if one/two
495  * syncpoints are found, only returns TRUE when it finds two
496  * subsequent syncpoints (similar to mp3 typefinding in
497  * gst/typefind/) for ADTS because 12 bits isn't very reliable.
498  */
499 static gboolean
gst_faad_sync(GstFaad * faad,const guint8 * data,guint size,gboolean next,gint * off,gint * length)500 gst_faad_sync (GstFaad * faad, const guint8 * data, guint size, gboolean next,
501     gint * off, gint * length)
502 {
503   guint n = 0;
504   gint snc;
505   gboolean ret = FALSE;
506   guint len = 0;
507 
508   GST_LOG_OBJECT (faad, "Finding syncpoint");
509 
510   /* check for too small a buffer */
511   if (size < 3)
512     goto exit;
513 
514   for (n = 0; n < size - 3; n++) {
515     snc = GST_READ_UINT16_BE (&data[n]);
516     if ((snc & 0xfff6) == 0xfff0) {
517       /* we have an ADTS syncpoint. Parse length and find
518        * next syncpoint. */
519       GST_LOG_OBJECT (faad,
520           "Found one ADTS syncpoint at offset 0x%x, tracing next...", n);
521 
522       if (size - n < 5) {
523         GST_LOG_OBJECT (faad, "Not enough data to parse ADTS header");
524         break;
525       }
526 
527       len = ((data[n + 3] & 0x03) << 11) |
528           (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5);
529       if (n + len + 2 >= size) {
530         GST_LOG_OBJECT (faad, "Frame size %d, next frame is not within reach",
531             len);
532         if (next) {
533           break;
534         } else if (n + len <= size) {
535           GST_LOG_OBJECT (faad, "but have complete frame and no next frame; "
536               "accept ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
537           ret = TRUE;
538           break;
539         }
540       }
541 
542       snc = GST_READ_UINT16_BE (&data[n + len]);
543       if ((snc & 0xfff6) == 0xfff0) {
544         GST_LOG_OBJECT (faad,
545             "Found ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
546         ret = TRUE;
547         break;
548       }
549 
550       GST_LOG_OBJECT (faad, "No next frame found... (should be at 0x%x)",
551           n + len);
552     } else if (!memcmp (&data[n], "ADIF", 4)) {
553       /* we have an ADIF syncpoint. 4 bytes is enough. */
554       GST_LOG_OBJECT (faad, "Found ADIF syncpoint at offset 0x%x", n);
555       ret = TRUE;
556       break;
557     }
558   }
559 
560 exit:
561 
562   *off = n;
563 
564   if (ret) {
565     *length = len;
566   } else {
567     GST_LOG_OBJECT (faad, "Found no syncpoint");
568   }
569 
570   return ret;
571 }
572 
573 static gboolean
looks_like_valid_header(guint8 * input_data,guint input_size)574 looks_like_valid_header (guint8 * input_data, guint input_size)
575 {
576   if (input_size < 4)
577     return FALSE;
578 
579   if (input_data[0] == 'A'
580       && input_data[1] == 'D' && input_data[2] == 'I' && input_data[3] == 'F')
581     /* ADIF type header */
582     return TRUE;
583 
584   if (input_data[0] == 0xff && (input_data[1] >> 4) == 0xf)
585     /* ADTS type header */
586     return TRUE;
587 
588   return FALSE;
589 }
590 
591 static GstFlowReturn
gst_faad_parse(GstAudioDecoder * dec,GstAdapter * adapter,gint * offset,gint * length)592 gst_faad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
593     gint * offset, gint * length)
594 {
595   GstFaad *faad;
596   const guint8 *data;
597   guint size;
598   gboolean sync, eos;
599 
600   faad = GST_FAAD (dec);
601 
602   size = gst_adapter_available (adapter);
603   g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
604 
605   gst_audio_decoder_get_parse_state (dec, &sync, &eos);
606 
607   if (faad->packetised) {
608     *offset = 0;
609     *length = size;
610     return GST_FLOW_OK;
611   } else {
612     gboolean ret;
613 
614     data = gst_adapter_map (adapter, size);
615     ret = gst_faad_sync (faad, data, size, !eos, offset, length);
616     gst_adapter_unmap (adapter);
617 
618     return (ret ? GST_FLOW_OK : GST_FLOW_EOS);
619   }
620 }
621 
622 static GstFlowReturn
gst_faad_handle_frame(GstAudioDecoder * dec,GstBuffer * buffer)623 gst_faad_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
624 {
625   GstFaad *faad;
626   GstFlowReturn ret = GST_FLOW_OK;
627   GstMapInfo map;
628   gsize input_size;
629   guchar *input_data;
630   GstBuffer *outbuf;
631   faacDecFrameInfo info;
632   void *out;
633 
634   faad = GST_FAAD (dec);
635 
636   /* no fancy draining */
637   if (G_UNLIKELY (!buffer))
638     return GST_FLOW_OK;
639 
640   gst_buffer_map (buffer, &map, GST_MAP_READ);
641   input_data = map.data;
642   input_size = map.size;
643 
644 init:
645   /* init if not already done during capsnego */
646   if (!faad->init) {
647     unsigned long rate;
648     guint8 ch;
649 
650     GST_DEBUG_OBJECT (faad, "initialising ...");
651     if (!gst_faad_open_decoder (faad))
652       goto open_failed;
653     /* We check if the first data looks like it might plausibly contain
654      * appropriate initialisation info... if not, we use our fake_codec_data
655      */
656     if (looks_like_valid_header (input_data, input_size) || !faad->packetised) {
657       if (faacDecInit (faad->handle, input_data, input_size, &rate, &ch) < 0)
658         goto init_failed;
659 
660       GST_DEBUG_OBJECT (faad, "faacDecInit() ok: rate=%u,channels=%u",
661           (guint32) rate, ch);
662     } else {
663       if ((gint8) faacDecInit2 (faad->handle, faad->fake_codec_data, 2,
664               &rate, &ch) < 0) {
665         goto init2_failed;
666       }
667       GST_DEBUG_OBJECT (faad, "faacDecInit2() ok: rate=%u,channels=%u",
668           (guint32) rate, ch);
669     }
670 
671     faad->init = TRUE;
672 
673     /* make sure we create new caps below */
674     faad->samplerate = 0;
675     faad->channels = 0;
676   }
677 
678   /* decode cycle */
679   info.error = 0;
680 
681   do {
682     GstMapInfo omap;
683 
684     if (!faad->packetised) {
685       /* faad only really parses ADTS header at Init time, not when decoding,
686        * so monitor for changes and kick faad when needed */
687       if (GST_READ_UINT32_BE (input_data) >> 4 != faad->last_header >> 4) {
688         GST_DEBUG_OBJECT (faad, "ADTS header changed, forcing Init");
689         faad->last_header = GST_READ_UINT32_BE (input_data);
690         /* kick hard */
691         gst_faad_close_decoder (faad);
692         faad->init = FALSE;
693         goto init;
694       }
695     }
696 
697     out = faacDecDecode (faad->handle, &info, input_data, input_size);
698 
699     gst_buffer_unmap (buffer, &map);
700     buffer = NULL;
701 
702     if (info.error > 0) {
703       /* give up on frame and bail out */
704       gst_audio_decoder_finish_frame (dec, NULL, 1);
705       goto decode_failed;
706     }
707 
708     GST_LOG_OBJECT (faad, "%d bytes consumed, %d samples decoded",
709         (guint) info.bytesconsumed, (guint) info.samples);
710 
711     if (out && info.samples > 0) {
712       guint channels, samples;
713 
714       if (!gst_faad_update_caps (faad, &info))
715         goto negotiation_failed;
716 
717       /* C's lovely propensity for int overflow.. */
718       if (info.samples > G_MAXUINT / faad->bps)
719         goto sample_overflow;
720 
721       channels = faad->channels;
722       /* note: info.samples is total samples, not per channel */
723       samples = info.samples / channels;
724 
725       /* FIXME, add bufferpool and allocator support to the base class */
726       outbuf = gst_buffer_new_allocate (NULL, info.samples * faad->bps, NULL);
727 
728       gst_buffer_map (outbuf, &omap, GST_MAP_READWRITE);
729       if (faad->need_reorder) {
730         gint16 *dest, *src, i, j;
731 
732         dest = (gint16 *) omap.data;
733         src = (gint16 *) out;
734 
735         for (i = 0; i < samples; i++) {
736           for (j = 0; j < channels; j++) {
737             dest[faad->reorder_map[j]] = *src++;
738           }
739           dest += channels;
740         }
741       } else {
742         memcpy (omap.data, out, omap.size);
743       }
744       gst_buffer_unmap (outbuf, &omap);
745 
746       ret = gst_audio_decoder_finish_frame (dec, outbuf, 1);
747     }
748   } while (FALSE);
749 
750 out:
751   if (buffer)
752     gst_buffer_unmap (buffer, &map);
753 
754   return ret;
755 
756 /* ERRORS */
757 open_failed:
758   {
759     GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
760         ("Failed to open decoder"));
761     ret = GST_FLOW_ERROR;
762     goto out;
763   }
764 init_failed:
765   {
766     GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
767         ("Failed to init decoder from stream"));
768     ret = GST_FLOW_ERROR;
769     goto out;
770   }
771 init2_failed:
772   {
773     GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
774         ("%s() failed", (faad->handle) ? "faacDecInit2" : "faacDecOpen"));
775     ret = GST_FLOW_ERROR;
776     goto out;
777   }
778 decode_failed:
779   {
780     GST_AUDIO_DECODER_ERROR (faad, 1, STREAM, DECODE, (NULL),
781         ("decoding error: %s", faacDecGetErrorMessage (info.error)), ret);
782     goto out;
783   }
784 negotiation_failed:
785   {
786     GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL),
787         ("Setting caps on source pad failed"));
788     ret = GST_FLOW_ERROR;
789     goto out;
790   }
791 sample_overflow:
792   {
793     GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
794         ("Output buffer too large"));
795     ret = GST_FLOW_ERROR;
796     goto out;
797   }
798 }
799 
800 static void
gst_faad_flush(GstAudioDecoder * dec,gboolean hard)801 gst_faad_flush (GstAudioDecoder * dec, gboolean hard)
802 {
803   gst_faad_reset_stream_state (GST_FAAD (dec));
804 }
805 
806 static gboolean
gst_faad_open_decoder(GstFaad * faad)807 gst_faad_open_decoder (GstFaad * faad)
808 {
809   faacDecConfiguration *conf;
810 
811   faad->handle = faacDecOpen ();
812 
813   if (faad->handle == NULL) {
814     GST_WARNING_OBJECT (faad, "faacDecOpen() failed");
815     return FALSE;
816   }
817 
818   conf = faacDecGetCurrentConfiguration (faad->handle);
819   conf->defObjectType = LC;
820   conf->dontUpSampleImplicitSBR = 1;
821   conf->outputFormat = FAAD_FMT_16BIT;
822 
823   if (faacDecSetConfiguration (faad->handle, conf) == 0) {
824     GST_WARNING_OBJECT (faad, "faacDecSetConfiguration() failed");
825     return FALSE;
826   }
827 
828   return TRUE;
829 }
830 
831 static void
gst_faad_close_decoder(GstFaad * faad)832 gst_faad_close_decoder (GstFaad * faad)
833 {
834   if (faad->handle) {
835     faacDecClose (faad->handle);
836     faad->handle = NULL;
837   }
838 }
839 
840 static gboolean
plugin_init(GstPlugin * plugin)841 plugin_init (GstPlugin * plugin)
842 {
843   return gst_element_register (plugin, "faad", GST_RANK_SECONDARY,
844       GST_TYPE_FAAD);
845 }
846 
847 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
848     GST_VERSION_MINOR,
849     faad,
850     "Free AAC Decoder (FAAD)",
851     plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
852