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