blob: aa553a108405a48bc78bbd5570eb7378f2ee9a1d
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 <core/dsp.h> |
48 | #include <stdio.h> |
49 | #include "aacdec.h" |
50 | |
51 | extern FILE*fpdbg; |
52 | extern void RefillBitStream(); |
53 | extern void set_timestamp_len(unsigned val); |
54 | extern void set_timestamp(unsigned val); |
55 | |
56 | int aac_need_align_bitstream = 0; |
57 | int AACDataSource = 1; |
58 | |
59 | /************************************************************************************** |
60 | * Function: AACInitDecoder |
61 | * |
62 | * Description: allocate memory for platform-specific data |
63 | * clear all the user-accessible fields |
64 | * initialize SBR decoder if enabled |
65 | * |
66 | * Inputs: none |
67 | * |
68 | * Outputs: none |
69 | * |
70 | * Return: handle to AAC decoder instance, 0 if malloc fails |
71 | **************************************************************************************/ |
72 | HAACDecoder AACInitDecoder(int DataSource) |
73 | { |
74 | AACDecInfo *aacDecInfo; |
75 | |
76 | AACDataSource = DataSource; |
77 | aacDecInfo = AllocateBuffers(); |
78 | if (!aacDecInfo) { |
79 | return 0; |
80 | } |
81 | |
82 | #ifdef AAC_ENABLE_SBR |
83 | if (InitSBR(aacDecInfo)) { |
84 | AACFreeDecoder(aacDecInfo); |
85 | return 0; |
86 | } |
87 | #endif |
88 | |
89 | if (AACDataSource == 0) { |
90 | InitBitStream(); |
91 | } |
92 | return (HAACDecoder)aacDecInfo; |
93 | } |
94 | |
95 | /************************************************************************************** |
96 | * Function: AACFreeDecoder |
97 | * |
98 | * Description: free platform-specific data allocated by AACInitDecoder |
99 | * free SBR decoder if enabled |
100 | * |
101 | * Inputs: valid AAC decoder instance pointer (HAACDecoder) |
102 | * |
103 | * Outputs: none |
104 | * |
105 | * Return: none |
106 | **************************************************************************************/ |
107 | void AACFreeDecoder(HAACDecoder hAACDecoder) |
108 | { |
109 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
110 | |
111 | if (!aacDecInfo) { |
112 | return; |
113 | } |
114 | |
115 | #ifdef AAC_ENABLE_SBR |
116 | FreeSBR(aacDecInfo); |
117 | #endif |
118 | FreeBuffers(aacDecInfo); |
119 | } |
120 | |
121 | /************************************************************************************** |
122 | * Function: AACFindSyncWord |
123 | * |
124 | * Description: locate the next byte-alinged sync word in the raw AAC stream |
125 | * |
126 | * Inputs: buffer to search for sync word |
127 | * max number of bytes to search in buffer |
128 | * |
129 | * Outputs: none |
130 | * |
131 | * Return: offset to first sync word (bytes from start of buf) |
132 | * -1 if sync not found after searching nBytes |
133 | **************************************************************************************/ |
134 | int AACFindSyncWord(unsigned char *buf, int nBytes) |
135 | { |
136 | int sync0 = 0; |
137 | int sync1 = 0; |
138 | int i; |
139 | |
140 | if (AACDataSource == 0) { |
141 | while (1) { |
142 | sync0 = GetBits(0, 8); |
143 | if (sync0 != 0xff) { |
144 | continue; |
145 | } |
146 | sync1 = GetBits(0, 4); |
147 | if (sync1 != 0xf) { |
148 | GetBits(0, 4); |
149 | continue; |
150 | } |
151 | return 0; |
152 | } |
153 | return -1; |
154 | } else { |
155 | /* find byte-aligned syncword (12 bits = 0xFFF) */ |
156 | for (i = 0; i < nBytes - 1; i++) { |
157 | if ((buf[i + 0] & SYNCWORDH) == SYNCWORDH && (buf[i + 1] & SYNCWORDL) == SYNCWORDL) { |
158 | return i; |
159 | } |
160 | } |
161 | |
162 | return -1; |
163 | } |
164 | } |
165 | |
166 | int AACFindSyncWordRaw(unsigned char *buf, int nBytes) |
167 | { |
168 | int sync0 = 0; |
169 | int sync1 = 0; |
170 | |
171 | if (AACDataSource == 0) { |
172 | while (1) { |
173 | sync0 = GetBits(0, 8); |
174 | if (sync0 != SYNCWORD0) { |
175 | continue; |
176 | } |
177 | sync1 = GetBits(0, 8); |
178 | if (sync1 != SYNCWORD1) { |
179 | continue; |
180 | } |
181 | RefillBitStream(); |
182 | return 0; |
183 | } |
184 | } |
185 | return 0; |
186 | } |
187 | |
188 | /************************************************************************************** |
189 | * Function: AACGetLastFrameInfo |
190 | * |
191 | * Description: get info about last AAC frame decoded (number of samples decoded, |
192 | * sample rate, bit rate, etc.) |
193 | * |
194 | * Inputs: valid AAC decoder instance pointer (HAACDecoder) |
195 | * pointer to AACFrameInfo struct |
196 | * |
197 | * Outputs: filled-in AACFrameInfo struct |
198 | * |
199 | * Return: none |
200 | * |
201 | * Notes: call this right after calling AACDecode() |
202 | **************************************************************************************/ |
203 | void AACGetLastFrameInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo) |
204 | { |
205 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
206 | |
207 | if (!aacDecInfo) { |
208 | aacFrameInfo->format = 0; |
209 | aacFrameInfo->bitRate = 0; |
210 | aacFrameInfo->nChans = 0; |
211 | aacFrameInfo->sampRateCore = 0; |
212 | aacFrameInfo->sampRateOut = 0; |
213 | aacFrameInfo->bitsPerSample = 0; |
214 | aacFrameInfo->outputSamps = 0; |
215 | aacFrameInfo->profile = 0; |
216 | aacFrameInfo->tnsUsed = 0; |
217 | aacFrameInfo->pnsUsed = 0; |
218 | } else { |
219 | aacFrameInfo->format = aacDecInfo->format; |
220 | aacFrameInfo->nChans = aacDecInfo->nChans; |
221 | aacFrameInfo->sampRateCore = aacDecInfo->sampRate; |
222 | aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1); |
223 | aacFrameInfo->bitsPerSample = 16; |
224 | aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); |
225 | aacFrameInfo->profile = aacDecInfo->profile; |
226 | aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed; |
227 | aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed; |
228 | } |
229 | } |
230 | |
231 | void AACGetDecoderInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo) |
232 | { |
233 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
234 | |
235 | if (aacDecInfo) { |
236 | aacFrameInfo->format = aacDecInfo->format; |
237 | aacFrameInfo->nChans = aacDecInfo->nChans; |
238 | aacFrameInfo->sampRateCore = aacDecInfo->sampRate; |
239 | aacFrameInfo->sampRateOut = aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1); |
240 | aacFrameInfo->bitsPerSample = 16; |
241 | aacFrameInfo->outputSamps = aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); |
242 | aacFrameInfo->profile = aacDecInfo->profile; |
243 | aacFrameInfo->tnsUsed = aacDecInfo->tnsUsed; |
244 | aacFrameInfo->pnsUsed = aacDecInfo->pnsUsed; |
245 | aacFrameInfo->total_byte_parsed = aacDecInfo->byteParsed; |
246 | aacFrameInfo->total_sample_decoded = aacDecInfo->sampleDecoded; |
247 | |
248 | if (aacDecInfo->bitRate) { |
249 | aacFrameInfo->bitRate = aacDecInfo->bitRate; |
250 | } else if (aacDecInfo->sampleDecoded > 0) { |
251 | aacFrameInfo->bitRate = (int)(((float)(aacDecInfo->byteParsed)) / ((float)aacDecInfo->sampleDecoded / (float)aacFrameInfo->sampRateOut)) << 3; |
252 | } |
253 | } |
254 | } |
255 | |
256 | /************************************************************************************** |
257 | * Function: AACSetRawBlockParams |
258 | * |
259 | * Description: set internal state variables for decoding a stream of raw data blocks |
260 | * |
261 | * Inputs: valid AAC decoder instance pointer (HAACDecoder) |
262 | * flag indicating source of parameters |
263 | * AACFrameInfo struct, with the members nChans, sampRate, and profile |
264 | * optionally filled-in |
265 | * |
266 | * Outputs: updated codec state |
267 | * |
268 | * Return: 0 if successful, error code (< 0) if error |
269 | * |
270 | * Notes: if copyLast == 1, then the codec sets up its internal state (for |
271 | * decoding raw blocks) based on previously-decoded ADTS header info |
272 | * if copyLast == 0, then the codec uses the values passed in |
273 | * aacFrameInfo to configure its internal state (useful when the |
274 | * source is MP4 format, for example) |
275 | **************************************************************************************/ |
276 | int AACSetRawBlockParams(HAACDecoder hAACDecoder, int copyLast, AACFrameInfo *aacFrameInfo) |
277 | { |
278 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
279 | |
280 | if (!aacDecInfo) { |
281 | return ERR_AAC_NULL_POINTER; |
282 | } |
283 | |
284 | aacDecInfo->format = AAC_FF_RAW; |
285 | aacDecInfo->audio_send_by_frame = aacFrameInfo->audio_send_by_frame; |
286 | if (copyLast) { |
287 | return SetRawBlockParams(aacDecInfo, 1, 0, 0, 0); |
288 | } else { |
289 | return SetRawBlockParams(aacDecInfo, 0, aacFrameInfo->nChans, aacFrameInfo->sampRateCore, aacFrameInfo->profile); |
290 | } |
291 | } |
292 | |
293 | /************************************************************************************** |
294 | * Function: AACFlushCodec |
295 | * |
296 | * Description: flush internal codec state (after seeking, for example) |
297 | * |
298 | * Inputs: valid AAC decoder instance pointer (HAACDecoder) |
299 | * |
300 | * Outputs: updated state variables in aacDecInfo |
301 | * |
302 | * Return: 0 if successful, error code (< 0) if error |
303 | **************************************************************************************/ |
304 | int AACFlushCodec(HAACDecoder hAACDecoder) |
305 | { |
306 | int ch; |
307 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
308 | |
309 | if (!aacDecInfo) { |
310 | return ERR_AAC_NULL_POINTER; |
311 | } |
312 | /* reset common state variables which change per-frame |
313 | * don't touch state variables which are (usually) constant for entire clip |
314 | * (nChans, sampRate, profile, format, sbrEnabled) |
315 | */ |
316 | aacDecInfo->prevBlockID = AAC_ID_INVALID; |
317 | aacDecInfo->currBlockID = AAC_ID_INVALID; |
318 | aacDecInfo->currInstTag = -1; |
319 | for (ch = 0; ch < MAX_NCHANS_ELEM; ch++) { |
320 | aacDecInfo->sbDeinterleaveReqd[ch] = 0; |
321 | } |
322 | aacDecInfo->adtsBlocksLeft = 0; |
323 | aacDecInfo->tnsUsed = 0; |
324 | aacDecInfo->pnsUsed = 0; |
325 | |
326 | /* reset internal codec state (flush overlap buffers, etc.) */ |
327 | FlushCodec(aacDecInfo); |
328 | #ifdef AAC_ENABLE_SBR |
329 | FlushCodecSBR(aacDecInfo); |
330 | #endif |
331 | |
332 | return ERR_AAC_NONE; |
333 | } |
334 | |
335 | /************************************************************************************** |
336 | * Function: AACDecode |
337 | * |
338 | * Description: decode AAC frame |
339 | * |
340 | * Inputs: valid AAC decoder instance pointer (HAACDecoder) |
341 | * double pointer to buffer of AAC data |
342 | * pointer to number of valid bytes remaining in inbuf |
343 | * pointer to outbuf, big enough to hold one frame of decoded PCM samples |
344 | * (outbuf must be double-sized if SBR enabled) |
345 | * |
346 | * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo |
347 | * number of output samples = 1024 per channel (2048 if SBR enabled) |
348 | * updated inbuf pointer |
349 | * updated bytesLeft |
350 | * |
351 | * Return: 0 if successful, error code (< 0) if error |
352 | * |
353 | * Notes: inbuf pointer and bytesLeft are not updated until whole frame is |
354 | * successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned |
355 | * just call AACDecode again with more data in inbuf |
356 | **************************************************************************************/ |
357 | int AACDecode(HAACDecoder hAACDecoder, unsigned char **inbuf, int *bytesLeft, short *outbuf) |
358 | { |
359 | int err, offset, bitOffset, bitsAvail; |
360 | int ch, baseChan, baseChanSBR, elementChans; |
361 | unsigned char *inptr; |
362 | AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder; |
363 | #ifdef AAC_ENABLE_SBR |
364 | int elementChansSBR; |
365 | #endif |
366 | int data; |
367 | unsigned char buf[4]; |
368 | |
369 | if (AACDataSource == 0) { |
370 | if (aac_need_align_bitstream) { |
371 | ByteAlignBitstream(0); |
372 | aac_need_align_bitstream = 0; |
373 | } |
374 | } |
375 | if (!aacDecInfo) { |
376 | return ERR_AAC_NULL_POINTER; |
377 | } |
378 | /* make local copies (see "Notes" above) */ |
379 | if (AACDataSource == 1) { |
380 | inptr = *inbuf; |
381 | bitOffset = 0; |
382 | bitsAvail = (*bytesLeft) << 3; |
383 | } else { |
384 | data = GetBitsNoAdvance(NULL, 32); |
385 | buf[0] = data >> 24; |
386 | buf[1] = data >> 16; |
387 | buf[2] = data >> 8; |
388 | buf[3] = data; |
389 | if (buf[0] == 'A' && buf[1] == 'P' && buf[2] == 'T' && buf[3] == 'S') { |
390 | register unsigned char tmp0, tmp1, tmp2, tmp3; |
391 | AdvanceBitstream(NULL, 16); // skip "APTS" |
392 | AdvanceBitstream(NULL, 16); |
393 | |
394 | // timestamp |
395 | tmp0 = GetBits(NULL, 8); |
396 | tmp1 = GetBits(NULL, 8); |
397 | tmp2 = GetBits(NULL, 8); |
398 | tmp3 = GetBits(NULL, 8); |
399 | set_timestamp((tmp0 << 24) | (tmp1 << 16) | (tmp2 << 8) | (tmp3)); |
400 | |
401 | // length |
402 | tmp0 = GetBits(NULL, 8); |
403 | tmp1 = GetBits(NULL, 8); |
404 | tmp2 = GetBits(NULL, 8); |
405 | tmp3 = GetBits(NULL, 8); |
406 | set_timestamp_len((tmp0 << 24) | (tmp1 << 16) | (tmp2 << 8) | (tmp3)); |
407 | |
408 | data = GetBitsNoAdvance(NULL, 32); |
409 | buf[0] = data >> 24; |
410 | buf[1] = data >> 16; |
411 | buf[2] = data >> 8; |
412 | buf[3] = data; |
413 | } |
414 | inptr = buf; |
415 | bitOffset = 0; |
416 | bitsAvail = 32; |
417 | } |
418 | /* first time through figure out what the file format is */ |
419 | if (aacDecInfo->format == AAC_FF_Unknown) { |
420 | if (AACDataSource == 1) { |
421 | if (bitsAvail < 32) { |
422 | return ERR_AAC_INDATA_UNDERFLOW; |
423 | } |
424 | } |
425 | if (IS_ADIF(inptr)) { |
426 | /* unpack ADIF header */ |
427 | aacDecInfo->format = AAC_FF_ADIF; |
428 | err = UnpackADIFHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); |
429 | if (err) { |
430 | return err; |
431 | } |
432 | } else { |
433 | /* assume ADTS by default */ |
434 | aacDecInfo->format = AAC_FF_ADTS; |
435 | } |
436 | } |
437 | /* if ADTS, search for start of next frame */ |
438 | if (aacDecInfo->format == AAC_FF_ADTS) { |
439 | /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */ |
440 | if (aacDecInfo->adtsBlocksLeft == 0) { |
441 | offset = AACFindSyncWord(inptr, bitsAvail >> 3); |
442 | if (AACDataSource == 1) { |
443 | if (offset < 0) { |
444 | return ERR_AAC_INDATA_UNDERFLOW; |
445 | } |
446 | inptr += offset; |
447 | bitsAvail -= (offset << 3); |
448 | } |
449 | err = UnpackADTSHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); |
450 | if (err) { |
451 | return err; |
452 | } |
453 | |
454 | if (aacDecInfo->nChans == -1) { |
455 | /* figure out implicit channel mapping if necessary */ |
456 | err = GetADTSChannelMapping(aacDecInfo, inptr, bitOffset, bitsAvail); |
457 | if (err) { |
458 | return err; |
459 | } |
460 | } |
461 | } |
462 | aacDecInfo->adtsBlocksLeft--; |
463 | } else if (aacDecInfo->format == AAC_FF_RAW) { |
464 | if (AACDataSource == 0) { |
465 | /* skip raw header*/ |
466 | if (aacDecInfo->audio_send_by_frame) { |
467 | offset = AACFindSyncWordRaw(inptr, bitsAvail >> 3); |
468 | } |
469 | } |
470 | err = PrepareRawBlock(aacDecInfo); |
471 | if (err) { |
472 | return err; |
473 | } |
474 | } |
475 | |
476 | /* check for valid number of channels */ |
477 | if (aacDecInfo->nChans > AAC_MAX_NCHANS || aacDecInfo->nChans <= 0) { |
478 | //printk("AAC ERR: ERR_AAC_NCHANS_TOO_HIGH\n"); |
479 | return ERR_AAC_NCHANS_TOO_HIGH; |
480 | } |
481 | |
482 | /* will be set later if active in this frame */ |
483 | aacDecInfo->tnsUsed = 0; |
484 | aacDecInfo->pnsUsed = 0; |
485 | |
486 | bitOffset = 0; |
487 | baseChan = 0; |
488 | baseChanSBR = 0; |
489 | do { |
490 | /* parse next syntactic element */ |
491 | err = DecodeNextElement(aacDecInfo, &inptr, &bitOffset, &bitsAvail); |
492 | if (err) { |
493 | return err; |
494 | } |
495 | |
496 | elementChans = elementNumChans[aacDecInfo->currBlockID]; |
497 | if (baseChan + elementChans > AAC_MAX_NCHANS) { |
498 | return ERR_AAC_NCHANS_TOO_HIGH; |
499 | } |
500 | |
501 | /* noiseless decoder and dequantizer */ |
502 | for (ch = 0; ch < elementChans; ch++) { |
503 | err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch); |
504 | if (err) { |
505 | return err; |
506 | } |
507 | |
508 | if (Dequantize(aacDecInfo, ch)) { |
509 | return ERR_AAC_DEQUANT; |
510 | } |
511 | } |
512 | |
513 | /* mid-side and intensity stereo */ |
514 | if (aacDecInfo->currBlockID == AAC_ID_CPE) { |
515 | if (StereoProcess(aacDecInfo)) { |
516 | return ERR_AAC_STEREO_PROCESS; |
517 | } |
518 | } |
519 | |
520 | /* PNS, TNS, inverse transform */ |
521 | for (ch = 0; ch < elementChans; ch++) { |
522 | if (PNS(aacDecInfo, ch)) { |
523 | return ERR_AAC_PNS; |
524 | } |
525 | |
526 | if (aacDecInfo->sbDeinterleaveReqd[ch]) { |
527 | /* deinterleave short blocks, if required */ |
528 | if (DeinterleaveShortBlocks(aacDecInfo, ch)) { |
529 | return ERR_AAC_SHORT_BLOCK_DEINT; |
530 | } |
531 | aacDecInfo->sbDeinterleaveReqd[ch] = 0; |
532 | } |
533 | |
534 | if (TNSFilter(aacDecInfo, ch)) { |
535 | return ERR_AAC_TNS; |
536 | } |
537 | |
538 | if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf)) { |
539 | return ERR_AAC_IMDCT; |
540 | } |
541 | } |
542 | |
543 | #ifdef AAC_ENABLE_SBR |
544 | if (aacDecInfo->sbrEnabled && (aacDecInfo->currBlockID == AAC_ID_FIL || aacDecInfo->currBlockID == AAC_ID_LFE)) { |
545 | if (aacDecInfo->currBlockID == AAC_ID_LFE) { |
546 | elementChansSBR = elementNumChans[AAC_ID_LFE]; |
547 | } else if (aacDecInfo->currBlockID == AAC_ID_FIL && (aacDecInfo->prevBlockID == AAC_ID_SCE || aacDecInfo->prevBlockID == AAC_ID_CPE)) { |
548 | elementChansSBR = elementNumChans[aacDecInfo->prevBlockID]; |
549 | } else { |
550 | elementChansSBR = 0; |
551 | } |
552 | |
553 | if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS) { |
554 | return ERR_AAC_SBR_NCHANS_TOO_HIGH; |
555 | } |
556 | |
557 | /* parse SBR extension data if present (contained in a fill element) */ |
558 | if (DecodeSBRBitstream(aacDecInfo, baseChanSBR)) { |
559 | return ERR_AAC_SBR_BITSTREAM; |
560 | } |
561 | |
562 | /* apply SBR */ |
563 | if (DecodeSBRData(aacDecInfo, baseChanSBR, outbuf)) { |
564 | return ERR_AAC_SBR_DATA; |
565 | } |
566 | |
567 | baseChanSBR += elementChansSBR; |
568 | } |
569 | #endif |
570 | |
571 | baseChan += elementChans; |
572 | } while (aacDecInfo->currBlockID != AAC_ID_END); |
573 | if (AACDataSource == 1) { |
574 | /* byte align after each raw_data_block */ |
575 | if (bitOffset) { |
576 | inptr++; |
577 | bitsAvail -= (8 - bitOffset); |
578 | bitOffset = 0; |
579 | if (bitsAvail < 0) { |
580 | return ERR_AAC_INDATA_UNDERFLOW; |
581 | } |
582 | } |
583 | } else { |
584 | //trace("align\n"); |
585 | ByteAlignBitstream(0); |
586 | } |
587 | |
588 | /* update pointers */ |
589 | if (AACDataSource == 1) { |
590 | aacDecInfo->frameCount++; |
591 | aacDecInfo->byteParsed += inptr - *inbuf; |
592 | aacDecInfo->sampleDecoded += AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); |
593 | *bytesLeft -= (inptr - *inbuf); |
594 | *inbuf = inptr; |
595 | } else { |
596 | aacDecInfo->frameCount++; |
597 | aacDecInfo->byteParsed = CalcBitsUsed(0, 0, 0) >> 3; |
598 | aacDecInfo->sampleDecoded += AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1); |
599 | *bytesLeft -= (CalcBitsUsed(0, 0, 0) >> 3); |
600 | // *inbuf = *inbuf+; |
601 | } |
602 | |
603 | |
604 | |
605 | return ERR_AAC_NONE; |
606 | } |
607 | |
608 |