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