summaryrefslogtreecommitdiff
path: root/audio_codec/libfaad/helixaac/aacdec.c (plain)
blob: e8297a4b1f0f8f514c6831f99f1a86cc39842b1d
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: aacdec.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $
3 *
4 * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file,
7 * are subject to the current version of the RealNetworks Public
8 * Source License (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the current version of the RealNetworks Community
11 * Source License (the "RCSL") available at
12 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
13 * will apply. You may also obtain the license terms directly from
14 * RealNetworks. You may not use this file except in compliance with
15 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
16 * to this file, the RCSL. Please see the applicable RPSL or RCSL for
17 * the rights, obligations and limitations governing use of the
18 * contents of the file.
19 *
20 * This file is part of the Helix DNA Technology. RealNetworks is the
21 * developer of the Original Code and owns the copyrights in the
22 * portions it created.
23 *
24 * This file, and the files included with this file, is distributed
25 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
26 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
27 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
28 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
29 * ENJOYMENT OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * http://www.helixcommunity.org/content/tck
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**************************************************************************************
39 * Fixed-point HE-AAC decoder
40 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
41 * February 2005
42 *
43 * aacdec.c - platform-independent top level decoder API
44 **************************************************************************************/
45#include "aaccommon.h"
46#include "bitstream.h"
47#include <stdio.h>
48#include "aacdec.h"
49
50#define HELIX_MAX_DECODE_CH_NUM (6)
51
52/**************************************************************************************
53 * Function: AACInitDecoder
54 *
55 * Description: allocate memory for platform-specific data
56 * clear all the user-accessible fields
57 * initialize SBR decoder if enabled
58 *
59 * Inputs: none
60 *
61 * Outputs: none
62 *
63 * Return: handle to AAC decoder instance, 0 if malloc fails
64 **************************************************************************************/
65HAACDecoder AACInitDecoder(void)
66{
67 AACDecInfo *aacDecInfo;
68
69 aacDecInfo = AllocateBuffers();
70 if (!aacDecInfo) {
71 return 0;
72 }
73
74#ifdef AAC_ENABLE_SBR
75 if (InitSBR(aacDecInfo)) {
76 AACFreeDecoder(aacDecInfo);
77 return 0;
78 }
79#endif
80
81 return (HAACDecoder)aacDecInfo;
82}
83
84/**************************************************************************************
85 * Function: AACFreeDecoder
86 *
87 * Description: free platform-specific data allocated by AACInitDecoder
88 * free SBR decoder if enabled
89 *
90 * Inputs: valid AAC decoder instance pointer (HAACDecoder)
91 *
92 * Outputs: none
93 *
94 * Return: none
95 **************************************************************************************/
96void AACFreeDecoder(HAACDecoder hAACDecoder)
97{
98 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
99
100 if (!aacDecInfo) {
101 return;
102 }
103
104#ifdef AAC_ENABLE_SBR
105 FreeSBR(aacDecInfo);
106#endif
107 FreeBuffers(aacDecInfo);
108}
109
110/**************************************************************************************
111 * Function: AACFindSyncWord
112 *
113 * Description: locate the next byte-alinged sync word in the raw AAC stream
114 *
115 * Inputs: buffer to search for sync word
116 * max number of bytes to search in buffer
117 *
118 * Outputs: none
119 *
120 * Return: offset to first sync word (bytes from start of buf)
121 * -1 if sync not found after searching nBytes
122 **************************************************************************************/
123int AACFindSyncWord(unsigned char *buf, int nBytes)
124{
125 int i;
126
127 /* find byte-aligned syncword (12 bits = 0xFFF) */
128 for (i = 0; i < nBytes - 1; i++) {
129 if ((buf[i + 0] & SYNCWORDH) == SYNCWORDH && (buf[i + 1] & SYNCWORDL) == SYNCWORDL) {
130 return i;
131 }
132 }
133
134 return -1;
135}
136
137/**************************************************************************************
138 * Function: AACGetLastFrameInfo
139 *
140 * Description: get info about last AAC frame decoded (number of samples decoded,
141 * sample rate, bit rate, etc.)
142 *
143 * Inputs: valid AAC decoder instance pointer (HAACDecoder)
144 * pointer to AACFrameInfo struct
145 *
146 * Outputs: filled-in AACFrameInfo struct
147 *
148 * Return: none
149 *
150 * Notes: call this right after calling AACDecode()
151 **************************************************************************************/
152void AACGetLastFrameInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo)
153{
154 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
155
156 if (!aacDecInfo) {
157 aacFrameInfo->format = 0;
158 aacFrameInfo->bitRate = 0;
159 aacFrameInfo->nChans = 0;
160 aacFrameInfo->sampRateCore = 0;
161 aacFrameInfo->sampRateOut = 0;
162 aacFrameInfo->bitsPerSample = 0;
163 aacFrameInfo->outputSamps = 0;
164 aacFrameInfo->profile = 0;
165 aacFrameInfo->tnsUsed = 0;
166 aacFrameInfo->pnsUsed = 0;
167 } else {
168 aacFrameInfo->format = aacDecInfo->format;
169 aacFrameInfo->nChans = aacDecInfo->nChans;
170 aacFrameInfo->sampRateCore = aacDecInfo->sampRate;
171 aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1);
172 aacFrameInfo->bitsPerSample = 16;
173 aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1);
174 aacFrameInfo->profile = aacDecInfo->profile;
175 aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed;
176 aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed;
177 }
178}
179
180void AACGetDecoderInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo)
181{
182 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
183
184 if (aacDecInfo) {
185 aacFrameInfo->format = aacDecInfo->format;
186 aacFrameInfo->nChans = aacDecInfo->nChans;
187 aacFrameInfo->sampRateCore = aacDecInfo->sampRate;
188 aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1);
189 aacFrameInfo->bitsPerSample = 16;
190 aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1);
191 aacFrameInfo->profile = aacDecInfo->profile;
192 aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed;
193 aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed;
194 aacFrameInfo->total_byte_parsed = aacDecInfo->byteParsed;
195 aacFrameInfo->total_sample_decoded = aacDecInfo->sampleDecoded;
196
197 if (aacDecInfo->bitRate) {
198 aacFrameInfo->bitRate = aacDecInfo->bitRate;
199 } else if (aacDecInfo->sampleDecoded > 0) {
200 aacFrameInfo->bitRate = (int)(((float)(aacDecInfo->byteParsed)) / ((float)aacDecInfo->sampleDecoded / (float)aacFrameInfo->sampRateOut)) << 3;
201 }
202 }
203}
204
205/**************************************************************************************
206 * Function: AACSetRawBlockParams
207 *
208 * Description: set internal state variables for decoding a stream of raw data blocks
209 *
210 * Inputs: valid AAC decoder instance pointer (HAACDecoder)
211 * flag indicating source of parameters
212 * AACFrameInfo struct, with the members nChans, sampRate, and profile
213 * optionally filled-in
214 *
215 * Outputs: updated codec state
216 *
217 * Return: 0 if successful, error code (< 0) if error
218 *
219 * Notes: if copyLast == 1, then the codec sets up its internal state (for
220 * decoding raw blocks) based on previously-decoded ADTS header info
221 * if copyLast == 0, then the codec uses the values passed in
222 * aacFrameInfo to configure its internal state (useful when the
223 * source is MP4 format, for example)
224 **************************************************************************************/
225int AACSetRawBlockParams(HAACDecoder hAACDecoder, int copyLast, AACFrameInfo *aacFrameInfo)
226{
227 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
228
229 if (!aacDecInfo) {
230 return ERR_AAC_NULL_POINTER;
231 }
232
233 aacDecInfo->format = AAC_FF_RAW;
234 aacDecInfo->audio_send_by_frame = aacFrameInfo->audio_send_by_frame;
235 if (copyLast) {
236 return SetRawBlockParams(aacDecInfo, 1, 0, 0, 0);
237 } else {
238 return SetRawBlockParams(aacDecInfo, 0, aacFrameInfo->nChans, aacFrameInfo->sampRateCore, aacFrameInfo->profile);
239 }
240}
241
242/**************************************************************************************
243 * Function: AACFlushCodec
244 *
245 * Description: flush internal codec state (after seeking, for example)
246 *
247 * Inputs: valid AAC decoder instance pointer (HAACDecoder)
248 *
249 * Outputs: updated state variables in aacDecInfo
250 *
251 * Return: 0 if successful, error code (< 0) if error
252 **************************************************************************************/
253int AACFlushCodec(HAACDecoder hAACDecoder)
254{
255 int ch;
256 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
257
258 if (!aacDecInfo) {
259 return ERR_AAC_NULL_POINTER;
260 }
261 /* reset common state variables which change per-frame
262 * don't touch state variables which are (usually) constant for entire clip
263 * (nChans, sampRate, profile, format, sbrEnabled)
264 */
265 aacDecInfo->prevBlockID = AAC_ID_INVALID;
266 aacDecInfo->currBlockID = AAC_ID_INVALID;
267 aacDecInfo->currInstTag = -1;
268 for (ch = 0; ch < MAX_NCHANS_ELEM; ch++) {
269 aacDecInfo->sbDeinterleaveReqd[ch] = 0;
270 }
271 aacDecInfo->adtsBlocksLeft = 0;
272 aacDecInfo->tnsUsed = 0;
273 aacDecInfo->pnsUsed = 0;
274
275 /* reset internal codec state (flush overlap buffers, etc.) */
276 FlushCodec(aacDecInfo);
277#ifdef AAC_ENABLE_SBR
278 FlushCodecSBR(aacDecInfo);
279#endif
280
281 return ERR_AAC_NONE;
282}
283
284/**************************************************************************************
285 * Function: AACDecode
286 *
287 * Description: decode AAC frame
288 *
289 * Inputs: valid AAC decoder instance pointer (HAACDecoder)
290 * double pointer to buffer of AAC data
291 * pointer to number of valid bytes remaining in inbuf
292 * pointer to outbuf, big enough to hold one frame of decoded PCM samples
293 * (outbuf must be double-sized if SBR enabled)
294 *
295 * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo
296 * number of output samples = 1024 per channel (2048 if SBR enabled)
297 * updated inbuf pointer
298 * updated bytesLeft
299 *
300 * Return: 0 if successful, error code (< 0) if error
301 *
302 * Notes: inbuf pointer and bytesLeft are not updated until whole frame is
303 * successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned
304 * just call AACDecode again with more data in inbuf
305 **************************************************************************************/
306int AACDecode(HAACDecoder hAACDecoder, unsigned char **inbuf, int *bytesLeft, short *outbuf)
307{
308 int err, offset, bitOffset, bitsAvail;
309 int ch, baseChan, baseChanSBR, elementChans;
310 unsigned char *inptr;
311 AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
312#ifdef AAC_ENABLE_SBR
313 int elementChansSBR;
314#endif
315
316 if (!aacDecInfo) {
317 return ERR_AAC_NULL_POINTER;
318 }
319
320 /* make local copies (see "Notes" above) */
321 inptr = *inbuf;
322 bitOffset = 0;
323 bitsAvail = (*bytesLeft) << 3;
324
325 /* first time through figure out what the file format is */
326 if (aacDecInfo->format == AAC_FF_Unknown) {
327 if (bitsAvail < 32) {
328 return ERR_AAC_INDATA_UNDERFLOW;
329 }
330
331 if (IS_ADIF(inptr)) {
332 /* unpack ADIF header */
333 aacDecInfo->format = AAC_FF_ADIF;
334 //printk("ADIF_DBG:ready step into UnpackADIFHeader()!\n");
335 err = UnpackADIFHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail);
336 if (err) {
337 return err;
338 }
339 } else {
340 /* assume ADTS by default */
341 aacDecInfo->format = AAC_FF_ADTS;
342 }
343 }
344 //printk("ADIF_DBG:aacDecInfo->format1=%d\n",aacDecInfo->format);
345
346 /* if ADTS, search for start of next frame */
347 if (aacDecInfo->format == AAC_FF_ADTS) {
348 /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */
349 if (/*aacDecInfo->adtsBlocksLeft == 0*/1) {
350 offset = AACFindSyncWord(inptr, bitsAvail >> 3);
351 if (AACDataSource == 1) {
352 if (offset < 0) { //not find sync word in current buffer
353 return ERR_AAC_INVALID_ADTS_SYNCWORD; //ERR_AAC_INDATA_UNDERFLOW;
354 }
355 inptr += offset;
356 bitsAvail -= (offset << 3);
357 }
358 err = UnpackADTSHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail);
359 if (err) {
360 return err;
361 }
362
363 if (aacDecInfo->nChans == -1) {
364 /* figure out implicit channel mapping if necessary */
365 err = GetADTSChannelMapping(aacDecInfo, inptr, bitOffset, bitsAvail);
366 if (err) {
367 return err;
368 }
369 }
370 }
371 aacDecInfo->adtsBlocksLeft--;
372 } else if (aacDecInfo->format == AAC_FF_RAW) {
373 err = PrepareRawBlock(aacDecInfo);
374 if (err) {
375 return err;
376 }
377 }
378
379 //printk("ADIF_DBG:aacDecInfo->nChans=%d aacDecInfo->sampRate=%d\n",aacDecInfo->nChans,aacDecInfo->sampRate);
380 /* check for valid number of channels */
381 if (aacDecInfo->nChans > AAC_MAX_NCHANS || aacDecInfo->nChans <= 0) {
382 printk("AAC ERR: ERR_AAC_NCHANS_TOO_HIGH\n");
383 return ERR_AAC_NCHANS_TOO_HIGH;
384 }
385
386 /* will be set later if active in this frame */
387 aacDecInfo->tnsUsed = 0;
388 aacDecInfo->pnsUsed = 0;
389
390 bitOffset = 0;
391 baseChan = 0;
392 baseChanSBR = 0;
393 do {
394 /* parse next syntactic element */
395 err = DecodeNextElement(aacDecInfo, &inptr, &bitOffset, &bitsAvail);
396 if (err) {
397 return err;
398 }
399
400 elementChans = elementNumChans[aacDecInfo->currBlockID];
401 if (baseChan + elementChans > AAC_MAX_NCHANS) {
402 return ERR_AAC_NCHANS_TOO_HIGH;
403 }
404
405 /* noiseless decoder and dequantizer */
406 for (ch = 0; ch < elementChans; ch++) {
407 err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch);
408 if (err) {
409 return err;
410 }
411
412 if (Dequantize(aacDecInfo, ch)) {
413 return ERR_AAC_DEQUANT;
414 }
415 }
416
417 /* mid-side and intensity stereo */
418 if (aacDecInfo->currBlockID == AAC_ID_CPE) {
419 if (StereoProcess(aacDecInfo)) {
420 return ERR_AAC_STEREO_PROCESS;
421 }
422 }
423
424 /* PNS, TNS, inverse transform */
425 for (ch = 0; ch < elementChans; ch++) {
426 if (PNS(aacDecInfo, ch)) {
427 return ERR_AAC_PNS;
428 }
429
430 if (aacDecInfo->sbDeinterleaveReqd[ch]) {
431 /* deinterleave short blocks, if required */
432 if (DeinterleaveShortBlocks(aacDecInfo, ch)) {
433 return ERR_AAC_SHORT_BLOCK_DEINT;
434 }
435 aacDecInfo->sbDeinterleaveReqd[ch] = 0;
436 }
437
438 if (TNSFilter(aacDecInfo, ch)) {
439 return ERR_AAC_TNS;
440 }
441
442 if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf)) {
443 return ERR_AAC_IMDCT;
444 }
445 }
446
447#ifdef AAC_ENABLE_SBR
448 if (aacDecInfo->sbrEnabled && (aacDecInfo->currBlockID == AAC_ID_FIL || aacDecInfo->currBlockID == AAC_ID_LFE)) {
449 if (aacDecInfo->currBlockID == AAC_ID_LFE) {
450 elementChansSBR = elementNumChans[AAC_ID_LFE];
451 } else if (aacDecInfo->currBlockID == AAC_ID_FIL && (aacDecInfo->prevBlockID == AAC_ID_SCE || aacDecInfo->prevBlockID == AAC_ID_CPE)) {
452 elementChansSBR = elementNumChans[aacDecInfo->prevBlockID];
453 } else {
454 elementChansSBR = 0;
455 }
456
457 if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS) {
458 return ERR_AAC_SBR_NCHANS_TOO_HIGH;
459 }
460
461 /* parse SBR extension data if present (contained in a fill element) */
462 if (DecodeSBRBitstream(aacDecInfo, baseChanSBR)) {
463 return ERR_AAC_SBR_BITSTREAM;
464 }
465
466 /* apply SBR */
467 if (DecodeSBRData(aacDecInfo, baseChanSBR, outbuf)) {
468 return ERR_AAC_SBR_DATA;
469 }
470
471 baseChanSBR += elementChansSBR;
472 }
473#endif
474
475 baseChan += elementChans;
476 } while (aacDecInfo->currBlockID != AAC_ID_END);
477
478 /* byte align after each raw_data_block */
479 if (bitOffset) {
480 inptr++;
481 bitsAvail -= (8 - bitOffset);
482 bitOffset = 0;
483 if (bitsAvail < 0) {
484 return ERR_AAC_INDATA_UNDERFLOW;
485 }
486 }
487
488 /* update pointers */
489 if (AACDataSource == 1) {
490 aacDecInfo->frameCount++;
491 aacDecInfo->byteParsed += inptr - *inbuf;
492 //printk(" decode one frame cost byte %d \n",inptr - *inbuf);
493 aacDecInfo->sampleDecoded += AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1);
494 *bytesLeft -= (inptr - *inbuf);
495 *inbuf = inptr;
496 } else {
497 aacDecInfo->frameCount++;
498 aacDecInfo->byteParsed = CalcBitsUsed(0, 0, 0) >> 3;
499 aacDecInfo->sampleDecoded += AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1);
500 *bytesLeft -= (CalcBitsUsed(0, 0, 0) >> 3);
501 // *inbuf = *inbuf+;
502 }
503
504
505
506 return ERR_AAC_NONE;
507}
508
509