| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 | 
							- /* ***** BEGIN LICENSE BLOCK *****  
 
-  * Source last modified: $Id: aacdec.c,v 1.1 2005/02/26 01:47:31 jrecker Exp $ 
 
-  *   
 
-  * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.  
 
-  *       
 
-  * The contents of this file, and the files included with this file, 
 
-  * are subject to the current version of the RealNetworks Public 
 
-  * Source License (the "RPSL") available at 
 
-  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 
-  * the file under the current version of the RealNetworks Community 
 
-  * Source License (the "RCSL") available at 
 
-  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL 
 
-  * will apply. You may also obtain the license terms directly from 
 
-  * RealNetworks.  You may not use this file except in compliance with 
 
-  * the RPSL or, if you have a valid RCSL with RealNetworks applicable 
 
-  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for 
 
-  * the rights, obligations and limitations governing use of the 
 
-  * contents of the file. 
 
-  *   
 
-  * This file is part of the Helix DNA Technology. RealNetworks is the 
 
-  * developer of the Original Code and owns the copyrights in the 
 
-  * portions it created. 
 
-  *   
 
-  * This file, and the files included with this file, is distributed 
 
-  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY 
 
-  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS 
 
-  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES 
 
-  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET 
 
-  * ENJOYMENT OR NON-INFRINGEMENT. 
 
-  *  
 
-  * Technology Compatibility Kit Test Suite(s) Location:  
 
-  *    http://www.helixcommunity.org/content/tck  
 
-  *  
 
-  * Contributor(s):  
 
-  *   
 
-  * ***** END LICENSE BLOCK ***** */  
 
- /**************************************************************************************
 
-  * Fixed-point HE-AAC decoder
 
-  * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
 
-  * February 2005
 
-  *
 
-  * aacdec.c - platform-independent top level decoder API
 
-  **************************************************************************************/
 
- #include "aaccommon.h"
 
- //#include "profile.h"
 
- #define PROFILE_START(x)
 
- #define PROFILE_END()
 
- /**************************************************************************************
 
-  * Function:    AACInitDecoder
 
-  *
 
-  * Description: allocate memory for platform-specific data
 
-  *              clear all the user-accessible fields
 
-  *              initialize SBR decoder if enabled
 
-  *
 
-  * Inputs:      none
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      handle to AAC decoder instance, 0 if malloc fails
 
-  **************************************************************************************/
 
- HAACDecoder AACInitDecoder(void)
 
- {
 
- 	AACDecInfo *aacDecInfo;
 
- 	aacDecInfo = AllocateBuffers();
 
- 	if (!aacDecInfo)
 
- 		return 0;
 
- #ifdef AAC_ENABLE_SBR
 
- 	if (InitSBR(aacDecInfo)) {
 
- 		AACFreeDecoder(aacDecInfo);
 
- 		return 0;
 
- 	}
 
- #endif
 
- 	return (HAACDecoder)aacDecInfo;
 
- }
 
- HAACDecoder AACInitDecoderPre(void *ptr, int sz)
 
- {
 
-         AACDecInfo *aacDecInfo;
 
-         aacDecInfo = AllocateBuffersPre(&ptr, &sz);
 
-         if (!aacDecInfo)
 
-                 return 0;
 
- #ifdef AAC_ENABLE_SBR
 
-         if (InitSBRPre(aacDecInfo, &ptr, &sz)) {
 
-                 return 0;
 
-         }
 
- #endif
 
-         return (HAACDecoder)aacDecInfo;
 
- }
 
- /**************************************************************************************
 
-  * Function:    AACFreeDecoder
 
-  *
 
-  * Description: free platform-specific data allocated by AACInitDecoder
 
-  *              free SBR decoder if enabled
 
-  *
 
-  * Inputs:      valid AAC decoder instance pointer (HAACDecoder)
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      none
 
-  **************************************************************************************/
 
- void AACFreeDecoder(HAACDecoder hAACDecoder)
 
- {
 
- 	AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
 
- 	if (!aacDecInfo)
 
- 		return;
 
- #ifdef AAC_ENABLE_SBR
 
- 	FreeSBR(aacDecInfo);
 
- #endif
 
- 	FreeBuffers(aacDecInfo);
 
- }
 
- /**************************************************************************************
 
-  * Function:    AACFindSyncWord
 
-  *
 
-  * Description: locate the next byte-alinged sync word in the raw AAC stream
 
-  *
 
-  * Inputs:      buffer to search for sync word
 
-  *              max number of bytes to search in buffer
 
-  *
 
-  * Outputs:     none
 
-  *
 
-  * Return:      offset to first sync word (bytes from start of buf)
 
-  *              -1 if sync not found after searching nBytes
 
-  **************************************************************************************/
 
- int AACFindSyncWord(unsigned char *buf, int nBytes)
 
- {
 
- 	int i;
 
- 	/* find byte-aligned syncword (12 bits = 0xFFF) */
 
- 	for (i = 0; i < nBytes - 1; i++) {
 
- 		if ( (buf[i+0] & SYNCWORDH) == SYNCWORDH && (buf[i+1] & SYNCWORDL) == SYNCWORDL )
 
- 			return i;
 
- 	}
 
- 	
 
- 	return -1;
 
- }
 
- /**************************************************************************************
 
-  * Function:    AACGetLastFrameInfo
 
-  *
 
-  * Description: get info about last AAC frame decoded (number of samples decoded, 
 
-  *                sample rate, bit rate, etc.)
 
-  *
 
-  * Inputs:      valid AAC decoder instance pointer (HAACDecoder)
 
-  *              pointer to AACFrameInfo struct
 
-  *
 
-  * Outputs:     filled-in AACFrameInfo struct
 
-  *
 
-  * Return:      none
 
-  *
 
-  * Notes:       call this right after calling AACDecode()
 
-  **************************************************************************************/
 
- void AACGetLastFrameInfo(HAACDecoder hAACDecoder, AACFrameInfo *aacFrameInfo)
 
- {
 
- 	AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
 
- 	if (!aacDecInfo) {
 
- 		aacFrameInfo->bitRate =       0;
 
- 		aacFrameInfo->nChans =        0;
 
- 		aacFrameInfo->sampRateCore =  0;
 
- 		aacFrameInfo->sampRateOut =   0;
 
- 		aacFrameInfo->bitsPerSample = 0;
 
- 		aacFrameInfo->outputSamps =   0;
 
- 		aacFrameInfo->profile =       0;
 
- 		aacFrameInfo->tnsUsed =       0;
 
- 		aacFrameInfo->pnsUsed =       0;
 
- 	} else {
 
- 		aacFrameInfo->bitRate =       aacDecInfo->bitRate;
 
- 		aacFrameInfo->nChans =        aacDecInfo->nChans;
 
- 		aacFrameInfo->sampRateCore =  aacDecInfo->sampRate;
 
- 		aacFrameInfo->sampRateOut =   aacDecInfo->sampRate * (aacDecInfo->sbrEnabled ? 2 : 1);
 
- 		aacFrameInfo->bitsPerSample = 16;
 
- 		aacFrameInfo->outputSamps =   aacDecInfo->nChans * AAC_MAX_NSAMPS * (aacDecInfo->sbrEnabled ? 2 : 1);
 
- 		aacFrameInfo->profile =       aacDecInfo->profile;
 
- 		aacFrameInfo->tnsUsed =       aacDecInfo->tnsUsed;
 
- 		aacFrameInfo->pnsUsed =       aacDecInfo->pnsUsed;
 
- 	}
 
- }
 
- /**************************************************************************************
 
-  * Function:    AACSetRawBlockParams
 
-  *
 
-  * Description: set internal state variables for decoding a stream of raw data blocks
 
-  *
 
-  * Inputs:      valid AAC decoder instance pointer (HAACDecoder)
 
-  *              flag indicating source of parameters
 
-  *              AACFrameInfo struct, with the members nChans, sampRate, and profile
 
-  *                optionally filled-in
 
-  *
 
-  * Outputs:     updated codec state 
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  *
 
-  * Notes:       if copyLast == 1, then the codec sets up its internal state (for 
 
-  *                decoding raw blocks) based on previously-decoded ADTS header info
 
-  *              if copyLast == 0, then the codec uses the values passed in
 
-  *                aacFrameInfo to configure its internal state (useful when the
 
-  *                source is MP4 format, for example)
 
-  **************************************************************************************/
 
- int AACSetRawBlockParams(HAACDecoder hAACDecoder, int copyLast, AACFrameInfo *aacFrameInfo)
 
- {
 
- 	AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
 
- 	if (!aacDecInfo)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	aacDecInfo->format = AAC_FF_RAW;
 
- 	if (copyLast)
 
- 		return SetRawBlockParams(aacDecInfo, 1, 0, 0, 0);
 
- 	else
 
- 		return SetRawBlockParams(aacDecInfo, 0, aacFrameInfo->nChans, aacFrameInfo->sampRateCore, aacFrameInfo->profile);
 
- }
 
- /**************************************************************************************
 
-  * Function:    AACFlushCodec
 
-  *
 
-  * Description: flush internal codec state (after seeking, for example)
 
-  *
 
-  * Inputs:      valid AAC decoder instance pointer (HAACDecoder)
 
-  *
 
-  * Outputs:     updated state variables in aacDecInfo
 
-  *
 
-  * Return:      0 if successful, error code (< 0) if error
 
-  **************************************************************************************/
 
- int AACFlushCodec(HAACDecoder hAACDecoder)
 
- {
 
- 	int ch;
 
- 	AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
 
- 	if (!aacDecInfo)
 
- 		return ERR_AAC_NULL_POINTER;
 
- 	/* reset common state variables which change per-frame
 
- 	 * don't touch state variables which are (usually) constant for entire clip 
 
- 	 *   (nChans, sampRate, profile, format, sbrEnabled)
 
- 	 */
 
- 	aacDecInfo->prevBlockID = AAC_ID_INVALID;
 
- 	aacDecInfo->currBlockID = AAC_ID_INVALID;
 
- 	aacDecInfo->currInstTag = -1;
 
- 	for (ch = 0; ch < MAX_NCHANS_ELEM; ch++)
 
- 		aacDecInfo->sbDeinterleaveReqd[ch] = 0;
 
- 	aacDecInfo->adtsBlocksLeft = 0;
 
- 	aacDecInfo->tnsUsed = 0;
 
- 	aacDecInfo->pnsUsed = 0;
 
- 	/* reset internal codec state (flush overlap buffers, etc.) */
 
- 	FlushCodec(aacDecInfo);
 
- #ifdef AAC_ENABLE_SBR
 
- 	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, elementChans;
 
- 	unsigned char *inptr;
 
- 	AACDecInfo *aacDecInfo = (AACDecInfo *)hAACDecoder;
 
- #ifdef AAC_ENABLE_SBR
 
- 	int baseChanSBR, elementChansSBR;
 
- #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;
 
- #ifdef AAC_ENABLE_SBR	
 
- 	baseChanSBR = 0;
 
- #endif	
 
- 	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++) {
 
-       PROFILE_START("noiseless decoder");
 
- 			err = DecodeNoiselessData(aacDecInfo, &inptr, &bitOffset, &bitsAvail, ch);
 
-       PROFILE_END();
 
-       			
 
- 			if (err)
 
- 				return err;
 
- 			PROFILE_START("dequant");
 
- 			if (Dequantize(aacDecInfo, ch))
 
- 				return ERR_AAC_DEQUANT;
 
-       PROFILE_END();
 
- 		}
 
-     PROFILE_START("mid-side and intensity stereo");
 
- 		/* mid-side and intensity stereo */
 
- 		if (aacDecInfo->currBlockID == AAC_ID_CPE) {
 
- 			if (StereoProcess(aacDecInfo))
 
- 				return ERR_AAC_STEREO_PROCESS;
 
- 		}
 
-     PROFILE_END();
 
- 		/* PNS, TNS, inverse transform */
 
- 		for (ch = 0; ch < elementChans; ch++) {
 
-       PROFILE_START("PNS");
 
- 			if (PNS(aacDecInfo, ch))
 
- 				return ERR_AAC_PNS;
 
-       PROFILE_END();
 
- 			if (aacDecInfo->sbDeinterleaveReqd[ch]) {
 
- 				/* deinterleave short blocks, if required */
 
- 				if (DeinterleaveShortBlocks(aacDecInfo, ch))
 
- 					return ERR_AAC_SHORT_BLOCK_DEINT;
 
- 				aacDecInfo->sbDeinterleaveReqd[ch] = 0;
 
- 			}
 
-       PROFILE_START("TNS");
 
- 			if (TNSFilter(aacDecInfo, ch))
 
- 				return ERR_AAC_TNS;
 
-       PROFILE_END();
 
- 	
 
-       PROFILE_START("IMDCT");
 
- 			if (IMDCT(aacDecInfo, ch, baseChan + ch, outbuf))
 
- 				return ERR_AAC_IMDCT;
 
-       PROFILE_END();
 
- 		}
 
- #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;
 
- }
 
 
  |