545 files changed, 230976 insertions, 0 deletions
diff --git a/audio_codec/wfd_aac_decoder/decelmnt.c b/audio_codec/wfd_aac_decoder/decelmnt.c new file mode 100644 index 0000000..4cd4ef8 --- a/dev/null +++ b/audio_codec/wfd_aac_decoder/decelmnt.c @@ -0,0 +1,445 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Source last modified: $Id: decelmnt.c,v 1.1.2.1 2005/02/26 02:05:12 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) + * February 2005 + * + * decelmnt.c - syntactic element decoding + **************************************************************************************/ + +#include "coder.h" + +/************************************************************************************** + * Function: DecodeSingleChannelElement + * + * Description: decode one SCE + * + * Inputs: BitStreamInfo struct pointing to start of SCE (14496-3, table 4.4.4) + * + * Outputs: updated element instance tag + * + * Return: 0 if successful, -1 if error + * + * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + **************************************************************************************/ +static int DecodeSingleChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) +{ + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + + return 0; +} + +/************************************************************************************** + * Function: DecodeChannelPairElement + * + * Description: decode one CPE + * + * Inputs: BitStreamInfo struct pointing to start of CPE (14496-3, table 4.4.5) + * + * Outputs: updated element instance tag + * updated commonWin + * updated ICS info, if commonWin == 1 + * updated mid-side stereo info, if commonWin == 1 + * + * Return: 0 if successful, -1 if error + * + * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + **************************************************************************************/ +static int DecodeChannelPairElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) +{ + int sfb, gp, maskOffset; + unsigned char currBit, *maskPtr; + PSInfoBase *psi; + ICSInfo *icsInfo; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + icsInfo = psi->icsInfo; + + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + + /* read common window flag and mid-side info (if present) + * store msMask bits in psi->msMaskBits[] as follows: + * long blocks - pack bits for each SFB in range [0, maxSFB) starting with lsb of msMaskBits[0] + * short blocks - pack bits for each SFB in range [0, maxSFB), for each group [0, 7] + * msMaskPresent = 0 means no M/S coding + * = 1 means psi->msMaskBits contains 1 bit per SFB to toggle M/S coding + * = 2 means all SFB's are M/S coded (so psi->msMaskBits is not needed) + */ + psi->commonWin = GetBits(bsi, 1); + if (psi->commonWin) { + DecodeICSInfo(bsi, icsInfo, psi->sampRateIdx); + psi->msMaskPresent = GetBits(bsi, 2); + if (psi->msMaskPresent == 1) { + maskPtr = psi->msMaskBits; + *maskPtr = 0; + maskOffset = 0; + for (gp = 0; gp < icsInfo->numWinGroup; gp++) { + for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { + currBit = (unsigned char)GetBits(bsi, 1); + *maskPtr |= currBit << maskOffset; + if (++maskOffset == 8) { + maskPtr++; + *maskPtr = 0; + maskOffset = 0; + } + } + } + } + } + + return 0; +} + +/************************************************************************************** + * Function: DecodeLFEChannelElement + * + * Description: decode one LFE + * + * Inputs: BitStreamInfo struct pointing to start of LFE (14496-3, table 4.4.9) + * + * Outputs: updated element instance tag + * + * Return: 0 if successful, -1 if error + * + * Notes: doesn't decode individual channel stream (part of DecodeNoiselessData) + **************************************************************************************/ +static int DecodeLFEChannelElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) +{ + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + + /* read instance tag */ + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + + return 0; +} + +/************************************************************************************** + * Function: DecodeDataStreamElement + * + * Description: decode one DSE + * + * Inputs: BitStreamInfo struct pointing to start of DSE (14496-3, table 4.4.10) + * + * Outputs: updated element instance tag + * filled in data stream buffer + * + * Return: 0 if successful, -1 if error + **************************************************************************************/ +static int DecodeDataStreamElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) +{ + unsigned int byteAlign, dataCount; + unsigned char *dataBuf; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + aacDecInfo->currInstTag = GetBits(bsi, NUM_INST_TAG_BITS); + byteAlign = GetBits(bsi, 1); + dataCount = GetBits(bsi, 8); + if (dataCount == 255) { + dataCount += GetBits(bsi, 8); + } + + if (byteAlign) { + ByteAlignBitstream(bsi); + } + + psi->dataCount = dataCount; + dataBuf = psi->dataBuf; + while (dataCount--) { + *dataBuf++ = GetBits(bsi, 8); + } + + return 0; +} + +/************************************************************************************** + * Function: DecodeProgramConfigElement + * + * Description: decode one PCE + * + * Inputs: BitStreamInfo struct pointing to start of PCE (14496-3, table 4.4.2) + * + * Outputs: filled-in ProgConfigElement struct + * updated BitStreamInfo struct + * + * Return: 0 if successful, error code (< 0) if error + * + * Notes: #define KEEP_PCE_COMMENTS to save the comment field of the PCE + * (otherwise we just skip it in the bitstream, to save memory) + **************************************************************************************/ +int DecodeProgramConfigElement(ProgConfigElement *pce, BitStreamInfo *bsi) +{ + int i; + + pce->elemInstTag = GetBits(bsi, 4); + pce->profile = GetBits(bsi, 2); + pce->sampRateIdx = GetBits(bsi, 4); + pce->numFCE = GetBits(bsi, 4); + pce->numSCE = GetBits(bsi, 4); + pce->numBCE = GetBits(bsi, 4); + pce->numLCE = GetBits(bsi, 2); + pce->numADE = GetBits(bsi, 3); + pce->numCCE = GetBits(bsi, 4); + + pce->monoMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->monoMixdown) { + pce->monoMixdown |= GetBits(bsi, 4); /* element number */ + } + + pce->stereoMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->stereoMixdown) { + pce->stereoMixdown |= GetBits(bsi, 4); /* element number */ + } + + pce->matrixMixdown = GetBits(bsi, 1) << 4; /* present flag */ + if (pce->matrixMixdown) { + pce->matrixMixdown |= GetBits(bsi, 2) << 1; /* index */ + pce->matrixMixdown |= GetBits(bsi, 1); /* pseudo-surround enable */ + } + + for (i = 0; i < pce->numFCE; i++) { + pce->fce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->fce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numSCE; i++) { + pce->sce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->sce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numBCE; i++) { + pce->bce[i] = GetBits(bsi, 1) << 4; /* is_cpe flag */ + pce->bce[i] |= GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numLCE; i++) { + pce->lce[i] = GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numADE; i++) { + pce->ade[i] = GetBits(bsi, 4); /* tag select */ + } + + for (i = 0; i < pce->numCCE; i++) { + pce->cce[i] = GetBits(bsi, 1) << 4; /* independent/dependent flag */ + pce->cce[i] |= GetBits(bsi, 4); /* tag select */ + } + + + ByteAlignBitstream(bsi); + +#ifdef KEEP_PCE_COMMENTS + pce->commentBytes = GetBits(bsi, 8); + for (i = 0; i < pce->commentBytes; i++) { + pce->commentField[i] = GetBits(bsi, 8); + } +#else + /* eat comment bytes and throw away */ + i = GetBits(bsi, 8); + while (i--) { + GetBits(bsi, 8); + } +#endif + + return 0; +} + +/************************************************************************************** + * Function: DecodeFillElement + * + * Description: decode one fill element + * + * Inputs: BitStreamInfo struct pointing to start of fill element + * (14496-3, table 4.4.11) + * + * Outputs: updated element instance tag + * unpacked extension payload + * + * Return: 0 if successful, -1 if error + **************************************************************************************/ +static int DecodeFillElement(AACDecInfo *aacDecInfo, BitStreamInfo *bsi) +{ + unsigned int fillCount; + unsigned char *fillBuf; + PSInfoBase *psi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return -1; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + fillCount = GetBits(bsi, 4); + if (fillCount == 15) { + fillCount += (GetBits(bsi, 8) - 1); + } + + psi->fillCount = fillCount; + fillBuf = psi->fillBuf; + while (fillCount--) { + *fillBuf++ = GetBits(bsi, 8); + } + + aacDecInfo->currInstTag = -1; /* fill elements don't have instance tag */ + aacDecInfo->fillExtType = 0; + +#ifdef AAC_ENABLE_SBR + /* check for SBR + * aacDecInfo->sbrEnabled is sticky (reset each raw_data_block), so for multichannel + * need to verify that all SCE/CPE/ICCE have valid SBR fill element following, and + * must upsample by 2 for LFE + */ + if (psi->fillCount > 0) { + aacDecInfo->fillExtType = (int)((psi->fillBuf[0] >> 4) & 0x0f); + if (aacDecInfo->fillExtType == EXT_SBR_DATA || aacDecInfo->fillExtType == EXT_SBR_DATA_CRC) { + aacDecInfo->sbrEnabled = 1; + } + } +#endif + + aacDecInfo->fillBuf = psi->fillBuf; + aacDecInfo->fillCount = psi->fillCount; + + return 0; +} + +/************************************************************************************** + * Function: DecodeNextElement + * + * Description: decode next syntactic element in AAC frame + * + * Inputs: valid AACDecInfo struct + * double pointer to buffer containing next element + * pointer to bit offset + * pointer to number of valid bits remaining in buf + * + * Outputs: type of element decoded (aacDecInfo->currBlockID) + * type of element decoded last time (aacDecInfo->prevBlockID) + * updated aacDecInfo state, depending on which element was decoded + * updated buffer pointer + * updated bit offset + * updated number of available bits + * + * Return: 0 if successful, error code (< 0) if error + **************************************************************************************/ +int DecodeNextElement(AACDecInfo *aacDecInfo, unsigned char **buf, int *bitOffset, int *bitsAvail) +{ + int err, bitsUsed; + PSInfoBase *psi; + BitStreamInfo bsi; + + /* validate pointers */ + if (!aacDecInfo || !aacDecInfo->psInfoBase) { + return ERR_AAC_NULL_POINTER; + } + psi = (PSInfoBase *)(aacDecInfo->psInfoBase); + + /* init bitstream reader */ + SetBitstreamPointer(&bsi, (*bitsAvail + 7) >> 3, *buf); + GetBits(&bsi, *bitOffset); + + /* read element ID (save last ID for SBR purposes) */ + aacDecInfo->prevBlockID = aacDecInfo->currBlockID; + aacDecInfo->currBlockID = GetBits(&bsi, NUM_SYN_ID_BITS); + + /* set defaults (could be overwritten by DecodeXXXElement(), depending on currBlockID) */ + psi->commonWin = 0; + + err = 0; + switch (aacDecInfo->currBlockID) { + case AAC_ID_SCE: + err = DecodeSingleChannelElement(aacDecInfo, &bsi); + break; + case AAC_ID_CPE: + err = DecodeChannelPairElement(aacDecInfo, &bsi); + break; + case AAC_ID_CCE: + /* TODO - implement CCE decoding */ + break; + case AAC_ID_LFE: + err = DecodeLFEChannelElement(aacDecInfo, &bsi); + break; + case AAC_ID_DSE: + err = DecodeDataStreamElement(aacDecInfo, &bsi); + break; + case AAC_ID_PCE: + err = DecodeProgramConfigElement(psi->pce + 0, &bsi); + break; + case AAC_ID_FIL: + err = DecodeFillElement(aacDecInfo, &bsi); + break; + case AAC_ID_END: + break; + } + if (err) { + return ERR_AAC_SYNTAX_ELEMENT; + } + + /* update bitstream reader */ + bitsUsed = CalcBitsUsed(&bsi, *buf, *bitOffset); + *buf += (bitsUsed + *bitOffset) >> 3; + *bitOffset = (bitsUsed + *bitOffset) & 0x07; + *bitsAvail -= bitsUsed; + + if (*bitsAvail < 0) { + return ERR_AAC_INDATA_UNDERFLOW; + } + + return ERR_AAC_NONE; +} + |