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 | **************************************************************************************/ |
65 | HAACDecoder 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 | **************************************************************************************/ |
96 | void 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 | **************************************************************************************/ |
123 | int 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 | **************************************************************************************/ |
152 | void 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 | |
180 | void 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 | **************************************************************************************/ |
225 | int 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 | **************************************************************************************/ |
253 | int 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 | **************************************************************************************/ |
306 | int 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 |