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