📄 aacdec.c.svn-base
字号:
FlushCodecSBR(aacDecInfo);#endif return ERR_AAC_NONE;}/************************************************************************************** * Function: AACDecode * * Description: decode AAC frame * * Inputs: valid AAC decoder instance pointer (HAACDecoder) * double pointer to buffer of AAC data * pointer to number of valid bytes remaining in inbuf * pointer to outbuf, big enough to hold one frame of decoded PCM samples * (outbuf must be double-sized if SBR enabled) * * Outputs: PCM data in outbuf, interleaved LRLRLR... if stereo * number of output samples = 1024 per channel (2048 if SBR enabled) * updated inbuf pointer * updated bytesLeft * * Return: 0 if successful, error code (< 0) if error * * Notes: inbuf pointer and bytesLeft are not updated until whole frame is * successfully decoded, so if ERR_AAC_INDATA_UNDERFLOW is returned * just call AACDecode again with more data in inbuf **************************************************************************************/int AACDecode(HAACDecoder hAACDecoder, unsigned char **inbuf, int *bytesLeft, short *outbuf){ int err, offset, bitOffset, bitsAvail; int ch, baseChan, baseChanSBR, elementChans; unsigned char *inptr; AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;#ifdef AAC_ENABLE_SBR int elementChansSBR;#endif#ifdef PROFILE long time;#endif if (!aacDecInfo) return ERR_AAC_NULL_POINTER; /* make local copies (see "Notes" above) */ inptr = *inbuf; bitOffset = 0; bitsAvail = (*bytesLeft) << 3; /* first time through figure out what the file format is */ if (aacDecInfo->format == AAC_FF_Unknown) { if (bitsAvail < 32) return ERR_AAC_INDATA_UNDERFLOW; if (IS_ADIF(inptr)) { /* unpack ADIF header */ aacDecInfo->format = AAC_FF_ADIF; err = UnpackADIFHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); if (err) return err; } else { /* assume ADTS by default */ aacDecInfo->format = AAC_FF_ADTS; } } /* if ADTS, search for start of next frame */ if (aacDecInfo->format == AAC_FF_ADTS) { /* can have 1-4 raw data blocks per ADTS frame (header only present for first one) */ if (aacDecInfo->adtsBlocksLeft == 0) { offset = AACFindSyncWord(inptr, bitsAvail >> 3); if (offset < 0) return ERR_AAC_INDATA_UNDERFLOW; inptr += offset; bitsAvail -= (offset << 3); err = UnpackADTSHeader(aacDecInfo, &inptr, &bitOffset, &bitsAvail); if (err) return err; if (aacDecInfo->nChans == -1) { /* figure out implicit channel mapping if necessary */ err = GetADTSChannelMapping(aacDecInfo, inptr, bitOffset, bitsAvail); if (err) return err; } } aacDecInfo->adtsBlocksLeft--; } else if (aacDecInfo->format == AAC_FF_RAW) { err = PrepareRawBlock(aacDecInfo); if (err) return err; } /* check for valid number of channels */ if (aacDecInfo->nChans > AAC_MAX_NCHANS || aacDecInfo->nChans <= 0) return ERR_AAC_NCHANS_TOO_HIGH; /* will be set later if active in this frame */ aacDecInfo->tnsUsed = 0; aacDecInfo->pnsUsed = 0; bitOffset = 0; baseChan = 0; baseChanSBR = 0; do { /* parse next syntactic element */ err = DecodeNextElement(aacDecInfo, &inptr, &bitOffset, &bitsAvail); if (err) return err; elementChans = elementNumChans[aacDecInfo->currBlockID]; if (baseChan + elementChans > AAC_MAX_NCHANS) return ERR_AAC_NCHANS_TOO_HIGH; /* noiseless decoder and dequantizer */ for (ch = 0; ch < elementChans; ch++) { #ifdef PROFILE time = systime_get(); #endif err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch); #ifdef PROFILE time = systime_get() - time; printf("noiseless decoder: %i ms\n", time); #endif if (err) return err; #ifdef PROFILE time = systime_get(); #endif if (Dequantize(aacDecInfo, ch)) return ERR_AAC_DEQUANT; #ifdef PROFILE time = systime_get() - time; printf("dequant: %i ms\n", time); #endif }#ifdef PROFILE time = systime_get() - time; printf("noiseless decoder and dequantizer: %i ms\n", time);#endif#ifdef PROFILE time = systime_get();#endif /* mid-side and intensity stereo */ if (aacDecInfo->currBlockID == AAC_ID_CPE) { if (StereoProcess(aacDecInfo)) return ERR_AAC_STEREO_PROCESS; }#ifdef PROFILE time = systime_get() - time; printf("mid-side and intensity stereo: %i ms\n", time);#endif /* PNS, TNS, inverse transform */ for (ch = 0; ch < elementChans; ch++) { #ifdef PROFILE time = systime_get(); #endif if (PNS(aacDecInfo, ch)) return ERR_AAC_PNS; #ifdef PROFILE time = systime_get() - time; printf("PNS: %i ms\n", time); #endif if (aacDecInfo->sbDeinterleaveReqd[ch]) { /* deinterleave short blocks, if required */ if (DeinterleaveShortBlocks(aacDecInfo, ch)) return ERR_AAC_SHORT_BLOCK_DEINT; aacDecInfo->sbDeinterleaveReqd[ch] = 0; } #ifdef PROFILE time = systime_get(); #endif if (TNSFilter(aacDecInfo, ch)) return ERR_AAC_TNS; #ifdef PROFILE time = systime_get() - time; printf("TNS: %i ms\n", time); #endif #ifdef PROFILE time = systime_get(); #endif if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf)) return ERR_AAC_IMDCT; #ifdef PROFILE time = systime_get() - time; printf("IMDCT: %i ms\n", time); #endif }#ifdef AAC_ENABLE_SBR if (aacDecInfo->sbrEnabled && (aacDecInfo->currBlockID == AAC_ID_FIL || aacDecInfo->currBlockID == AAC_ID_LFE)) { if (aacDecInfo->currBlockID == AAC_ID_LFE) elementChansSBR = elementNumChans[AAC_ID_LFE]; else if (aacDecInfo->currBlockID == AAC_ID_FIL && (aacDecInfo->prevBlockID == AAC_ID_SCE || aacDecInfo->prevBlockID == AAC_ID_CPE)) elementChansSBR = elementNumChans[aacDecInfo->prevBlockID]; else elementChansSBR = 0; if (baseChanSBR + elementChansSBR > AAC_MAX_NCHANS) return ERR_AAC_SBR_NCHANS_TOO_HIGH; /* parse SBR extension data if present (contained in a fill element) */ if (DecodeSBRBitstream(aacDecInfo, baseChanSBR)) return ERR_AAC_SBR_BITSTREAM; /* apply SBR */ if (DecodeSBRData(aacDecInfo, baseChanSBR, outbuf)) return ERR_AAC_SBR_DATA; baseChanSBR += elementChansSBR; }#endif baseChan += elementChans; } while (aacDecInfo->currBlockID != AAC_ID_END); /* byte align after each raw_data_block */ if (bitOffset) { inptr++; bitsAvail -= (8-bitOffset); bitOffset = 0; if (bitsAvail < 0) return ERR_AAC_INDATA_UNDERFLOW; } /* update pointers */ aacDecInfo->frameCount++; *bytesLeft -= (inptr - *inbuf); *inbuf = inptr; return ERR_AAC_NONE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -