summaryrefslogtreecommitdiffstats
path: root/libAACdec/src/aacdecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src/aacdecoder.cpp')
-rw-r--r--libAACdec/src/aacdecoder.cpp1787
1 files changed, 0 insertions, 1787 deletions
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
deleted file mode 100644
index 3a2a561..0000000
--- a/libAACdec/src/aacdecoder.cpp
+++ /dev/null
@@ -1,1787 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
- All rights reserved.
-
- 1. INTRODUCTION
-The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
-the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
-This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
-
-AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
-audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
-independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
-of the MPEG specifications.
-
-Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
-may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
-individually for the purpose of encoding or decoding bit streams in products that are compliant with
-the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
-these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
-software may already be covered under those patent licenses when it is used for those licensed purposes only.
-
-Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
-are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
-applications information and documentation.
-
-2. COPYRIGHT LICENSE
-
-Redistribution and use in source and binary forms, with or without modification, are permitted without
-payment of copyright license fees provided that you satisfy the following conditions:
-
-You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
-your modifications thereto in source code form.
-
-You must retain the complete text of this software license in the documentation and/or other materials
-provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
-You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
-modifications thereto to recipients of copies in binary form.
-
-The name of Fraunhofer may not be used to endorse or promote products derived from this library without
-prior written permission.
-
-You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
-software or your modifications thereto.
-
-Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
-and the date of any change. For modified versions of the FDK AAC Codec, the term
-"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
-"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
-
-3. NO PATENT LICENSE
-
-NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
-ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
-respect to this software.
-
-You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
-by appropriate patent licenses.
-
-4. DISCLAIMER
-
-This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
-"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
-of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
-including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
-or business interruption, however caused and on any theory of liability, whether in contract, strict
-liability, or tort (including negligence), arising in any way out of the use of this software, even if
-advised of the possibility of such damage.
-
-5. CONTACT INFORMATION
-
-Fraunhofer Institute for Integrated Circuits IIS
-Attention: Audio and Multimedia Departments - FDK AAC LL
-Am Wolfsmantel 33
-91058 Erlangen, Germany
-
-www.iis.fraunhofer.de/amm
-amm-info@iis.fraunhofer.de
------------------------------------------------------------------------------------------------------------ */
-
-/***************************** MPEG-4 AAC Decoder **************************
-
- Author(s): Josef Hoepfl
- Description:
-
-******************************************************************************/
-
-
-/*!
- \page default General Overview of the AAC Decoder Implementation
-
- The main entry point to decode a AAC frame is CAacDecoder_DecodeFrame(). It handles the different
- transport multiplexes and bitstream formats supported by this implementation. It extracts the
- AAC_raw_data_blocks from these bitstreams to further process then in the actual decoding stages.
-
- Note: Click on a function of file in the above image to see details about the function. Also note, that
- this is just an overview of the most important functions and not a complete call graph.
-
- <h2>1 Bitstream deformatter</h2>
- The basic bit stream parser function CChannelElement_Read() is called. It uses other subcalls in order
- to parse and unpack the bitstreams. Note, that this includes huffmann decoding of the coded spectral data.
- This operation can be computational significant specifically at higher bitrates. Optimization is likely in
- CBlock_ReadSpectralData().
-
- The bitstream deformatter also includes many bitfield operations. Profiling on the target will determine
- required optimizations.
-
- <h2>2 Actual decoding to retain the time domain output</h2>
- The basic bitstream deformatter function CChannelElement_Decode() for CPE elements and SCE elements are called.
- Except for the stereo processing (2.1) which is only used for CPE elements, the function calls for CPE or SCE
- are similar, except that CPE always processes to independent channels while SCE only processes one channel.
-
- Often there is the distinction between long blocks and short blocks. However, computational expensive functions
- that ususally require optimization are being shared by these two groups,
-
- <h3>2.1 Stereo processing for CPE elements</h3>
- CChannelPairElement_Decode() first calles the joint stereo tools in stereo.cpp when required.
-
- <h3>2.2 Scaling of spectral data</h3>
- CBlock_ScaleSpectralData().
-
- <h3>2.3 Apply additional coding tools</h3>
- ApplyTools() calles the PNS tools in case of MPEG-4 bitstreams, and TNS filtering CTns_Apply() for MPEG-2 and MPEG-4 bitstreams.
- The function TnsFilterIIR() which is called by CTns_Apply() (2.3.1) might require some optimization.
-
- <h2>3 Frequency-To-Time conversion</h3>
- The filterbank is called using CBlock_FrequencyToTime() using the MDCT module from the FDK Tools
-
-*/
-
-
-
-#include "aacdecoder.h"
-
-#include "aac_rom.h"
-#include "aac_ram.h"
-#include "channel.h"
-#include "FDK_audio.h"
-
-#include "FDK_tools_rom.h"
-
- #include "aacdec_pns.h"
-
- #include "sbrdecoder.h"
-
-
-
-
- #include "aacdec_hcr.h"
- #include "rvlc.h"
-
-
-#include "tpdec_lib.h"
-
-#include "conceal.h"
-
-
-
-#define CAN_DO_PS(aot) \
- ((aot) == AOT_AAC_LC \
-|| (aot) == AOT_SBR \
-|| (aot) == AOT_PS \
-|| (aot) == AOT_ER_BSAC \
-|| (aot) == AOT_DRM_AAC)
-
-#define IS_USAC(aot) \
- ((aot) == AOT_USAC \
-|| (aot) == AOT_RSVD50)
-
-#define IS_LOWDELAY(aot) \
- ((aot) == AOT_ER_AAC_LD \
-|| (aot) == AOT_ER_AAC_ELD)
-
-void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self)
-{
-
- /* Assign user requested mode */
- self->qmfModeCurr = self->qmfModeUser;
-
- if ( self->qmfModeCurr == NOT_DEFINED )
- {
- if ( (IS_LOWDELAY(self->streamInfo.aot) && (self->flags & AC_MPS_PRESENT))
- || ( (self->streamInfo.aacNumChannels == 1)
- && ( (CAN_DO_PS(self->streamInfo.aot) && !(self->flags & AC_MPS_PRESENT))
- || ( IS_USAC(self->streamInfo.aot) && (self->flags & AC_MPS_PRESENT)) ) ) )
- {
- self->qmfModeCurr = MODE_HQ;
- } else {
- self->qmfModeCurr = MODE_LP;
- }
- }
-
-
- /* Set SBR to current QMF mode. Error does not matter. */
- sbrDecoder_SetParam(self->hSbrDecoder, SBR_QMF_MODE, (self->qmfModeCurr == MODE_LP));
- self->psPossible = ((CAN_DO_PS(self->streamInfo.aot) && self->streamInfo.aacNumChannels == 1 && ! (self->flags & AC_MPS_PRESENT))) && self->qmfModeCurr == MODE_HQ ;
- FDK_ASSERT( ! ( (self->flags & AC_MPS_PRESENT) && self->psPossible ) );
-}
-
-void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self)
-{
-}
-
-/*!
- \brief Reset ancillary data struct. Call before parsing a new frame.
-
- \ancData Pointer to ancillary data structure
-
- \return Error code
-*/
-static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData)
-{
- int i;
- for (i=0; i<8; i++)
- {
- ancData->offset[i] = 0;
- }
- ancData->nrElements = 0;
-
- return AAC_DEC_OK;
-}
-
-/*!
- \brief Initialize ancillary buffer
-
- \ancData Pointer to ancillary data structure
- \buffer Pointer to (external) anc data buffer
- \size Size of the buffer pointed on by buffer in bytes
-
- \return Error code
-*/
-AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, unsigned char *buffer, int size)
-{
- if (size >= 0) {
- ancData->buffer = buffer;
- ancData->bufferSize = size;
-
- CAacDecoder_AncDataReset(ancData);
-
- return AAC_DEC_OK;
- }
-
- return AAC_DEC_ANC_DATA_ERROR;
-}
-
-/*!
- \brief Get one ancillary data element
-
- \ancData Pointer to ancillary data structure
- \index Index of the anc data element to get
- \ptr Pointer to a buffer receiving a pointer to the requested anc data element
- \size Pointer to a buffer receiving the length of the requested anc data element in bytes
-
- \return Error code
-*/
-AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index, unsigned char **ptr, int *size)
-{
- AAC_DECODER_ERROR error = AAC_DEC_OK;
-
- *ptr = NULL;
- *size = 0;
-
- if (index >= 0 && index < 8 && index < ancData->nrElements)
- {
- *ptr = &ancData->buffer[ancData->offset[index]];
- *size = ancData->offset[index+1] - ancData->offset[index];
- }
-
- return error;
-}
-
-
-/*!
- \brief Parse ancillary data
-
- \ancData Pointer to ancillary data structure
- \hBs Handle to FDK bitstream
- \ancBytes Length of ancillary data to read from the bitstream
-
- \return Error code
-*/
-static
-AAC_DECODER_ERROR CAacDecoder_AncDataParse (
- CAncData *ancData,
- HANDLE_FDK_BITSTREAM hBs,
- const int ancBytes )
-{
- AAC_DECODER_ERROR error = AAC_DEC_OK;
- int readBytes = 0;
-
- if (ancData->buffer != NULL)
- {
- if (ancBytes > 0) {
- /* write ancillary data to external buffer */
- int offset = ancData->offset[ancData->nrElements];
-
- if ((offset + ancBytes) > ancData->bufferSize)
- {
- error = AAC_DEC_TOO_SMALL_ANC_BUFFER;
- }
- else if (ancData->nrElements >= 8-1)
- {
- error = AAC_DEC_TOO_MANY_ANC_ELEMENTS;
- }
- else
- {
- int i;
-
- for (i = 0; i < ancBytes; i++) {
- ancData->buffer[i+offset] = FDKreadBits(hBs, 8);
- readBytes++;
- }
-
- ancData->nrElements++;
- ancData->offset[ancData->nrElements] = ancBytes + ancData->offset[ancData->nrElements-1];
- }
- }
- }
-
- readBytes = ancBytes - readBytes;
-
- if (readBytes > 0) {
- /* skip data */
- FDKpushFor(hBs, readBytes<<3);
- }
-
- return error;
-}
-
-/*!
- \brief Read Stream Data Element
-
- \bs Bitstream Handle
-
- \return Error code
-*/
-static AAC_DECODER_ERROR CDataStreamElement_Read (
- HANDLE_FDK_BITSTREAM bs,
- CAncData *ancData,
- HANDLE_AAC_DRC hDrcInfo,
- HANDLE_TRANSPORTDEC pTp,
- UCHAR *elementInstanceTag,
- UINT alignmentAnchor )
-{
- AAC_DECODER_ERROR error = AAC_DEC_OK;
- UINT dataStart;
- int dataByteAlignFlag, count;
-
- int crcReg = transportDec_CrcStartReg(pTp, 0);
-
- /* Element Instance Tag */
- *elementInstanceTag = FDKreadBits(bs,4);
- /* Data Byte Align Flag */
- dataByteAlignFlag = FDKreadBits(bs,1);
-
- count = FDKreadBits(bs,8);
-
- if (count == 255) {
- count += FDKreadBits(bs,8); /* EscCount */
- }
-
- if (dataByteAlignFlag) {
- FDKbyteAlign(bs, alignmentAnchor);
- }
-
- dataStart = FDKgetValidBits(bs);
-
- error = CAacDecoder_AncDataParse(ancData, bs, count);
- transportDec_CrcEndReg(pTp, crcReg);
-
- {
- INT readBits, dataBits = count<<3;
-
- /* Move to the beginning of the data junk */
- FDKpushBack(bs, dataStart-FDKgetValidBits(bs));
-
- /* Read Anc data if available */
- readBits = aacDecoder_drcMarkPayload( hDrcInfo, bs, DVB_DRC_ANC_DATA );
-
- if (readBits != dataBits) {
- /* Move to the end again. */
- FDKpushBiDirectional(bs, FDKgetValidBits(bs)-dataStart+dataBits);
- }
- }
-
- return error;
-}
-
-#ifdef TP_PCE_ENABLE
-/*!
- \brief Read Program Config Element
-
- \bs Bitstream Handle
- \pTp Transport decoder handle for CRC handling
- \pce Pointer to PCE buffer
- \channelConfig Current channel configuration
- \alignAnchor Anchor for byte alignment
-
- \return PCE status (-1: fail, 0: no new PCE, 1: PCE updated, 2: PCE updated need re-config).
-*/
-static int CProgramConfigElement_Read (
- HANDLE_FDK_BITSTREAM bs,
- HANDLE_TRANSPORTDEC pTp,
- CProgramConfig *pce,
- const UINT channelConfig,
- const UINT alignAnchor )
-{
- int pceStatus = 0;
- int crcReg;
-
- /* read PCE to temporal buffer first */
- C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
-
- CProgramConfig_Init(tmpPce);
- CProgramConfig_Reset(tmpPce);
-
- crcReg = transportDec_CrcStartReg(pTp, 0);
-
- CProgramConfig_Read(tmpPce, bs, alignAnchor);
-
- transportDec_CrcEndReg(pTp, crcReg);
-
- if ( CProgramConfig_IsValid(tmpPce)
- && (tmpPce->Profile == 1) )
- {
- if ( !pce->isValid && (channelConfig > 0) ) {
- /* Create a standard channel config PCE to compare with */
- CProgramConfig_GetDefault( pce, channelConfig );
- }
-
- if (pce->isValid) {
- /* Compare the new and the old PCE (tags ignored) */
- switch ( CProgramConfig_Compare( pce, tmpPce ) )
- {
- case 1: /* Channel configuration not changed. Just new metadata. */
- FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); /* Store the complete PCE */
- pceStatus = 1; /* New PCE but no change of config */
- break;
- case 2: /* The number of channels are identical but not the config */
- if (channelConfig == 0) {
- FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); /* Store the complete PCE */
- pceStatus = 2; /* Decoder needs re-configuration */
- }
- break;
- case -1: /* The channel configuration is completely different */
- pceStatus = -1; /* Not supported! */
- break;
- case 0: /* Nothing to do because PCE matches the old one exactly. */
- default:
- /* pceStatus = 0; */
- break;
- }
- }
- }
-
- C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
-
- return pceStatus;
-}
-#endif /* TP_PCE_ENABLE */
-
-/*!
- \brief Parse Extension Payload
-
- \self Handle of AAC decoder
- \count Pointer to bit counter.
- \previous_element ID of previous element (required by some extension payloads)
-
- \return Error code
-*/
-static
-AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
- HANDLE_FDK_BITSTREAM hBs,
- int *count,
- MP4_ELEMENT_ID previous_element,
- int elIndex,
- int fIsFillElement)
-{
- AAC_DECODER_ERROR error = AAC_DEC_OK;
- EXT_PAYLOAD_TYPE extension_type;
- int bytes = (*count) >> 3;
- int crcFlag = 0;
-
- if (*count < 4) {
- return AAC_DEC_PARSE_ERROR;
- } else if ((INT)FDKgetValidBits(hBs) < *count) {
- return AAC_DEC_DECODE_FRAME_ERROR;
- }
-
- extension_type = (EXT_PAYLOAD_TYPE) FDKreadBits(hBs, 4); /* bs_extension_type */
- *count -= 4;
-
- switch (extension_type)
- {
- case EXT_DYNAMIC_RANGE:
- {
- INT readBits = aacDecoder_drcMarkPayload( self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA );
-
- if (readBits > *count)
- { /* Read too much. Something went wrong! */
- error = AAC_DEC_PARSE_ERROR;
- }
- *count -= readBits;
- }
- break;
-
-
- case EXT_SBR_DATA_CRC:
- crcFlag = 1;
- case EXT_SBR_DATA:
- if (IS_CHANNEL_ELEMENT(previous_element)) {
- SBR_ERROR sbrError;
-
- CAacDecoder_SyncQmfMode(self);
-
- sbrError = sbrDecoder_InitElement(
- self->hSbrDecoder,
- self->streamInfo.aacSampleRate,
- self->streamInfo.extSamplingRate,
- self->streamInfo.aacSamplesPerFrame,
- self->streamInfo.aot,
- previous_element,
- elIndex
- );
-
- if (sbrError == SBRDEC_OK) {
- sbrError = sbrDecoder_Parse (
- self->hSbrDecoder,
- hBs,
- count,
- *count,
- crcFlag,
- previous_element,
- elIndex,
- self->flags & AC_INDEP );
- /* Enable SBR for implicit SBR signalling. */
- if (sbrError == SBRDEC_OK) {
- self->sbrEnabled = 1;
- }
- } else {
- /* Do not try to apply SBR because initializing the element failed. */
- self->sbrEnabled = 0;
- }
- /* Citation from ISO/IEC 14496-3 chapter 4.5.2.1.5.2
- Fill elements containing an extension_payload() with an extension_type of EXT_SBR_DATA
- or EXT_SBR_DATA_CRC shall not contain any other extension_payload of any other extension_type.
- */
- if (fIsFillElement) {
- FDKpushBiDirectional(hBs, *count);
- *count = 0;
- } else {
- /* If this is not a fill element with a known length, we are screwed an no further parsing makes sense. */
- if (sbrError != SBRDEC_OK) {
- self->frameOK = 0;
- }
- }
- } else {
- error = AAC_DEC_PARSE_ERROR;
- }
- break;
-
- case EXT_FILL_DATA:
- {
- int temp;
-
- temp = FDKreadBits(hBs,4);
- bytes--;
- if (temp != 0) {
- error = AAC_DEC_PARSE_ERROR;
- break;
- }
- while (bytes > 0) {
- temp = FDKreadBits(hBs,8);
- bytes--;
- if (temp != 0xa5) {
- error = AAC_DEC_PARSE_ERROR;
- break;
- }
- }
- *count = bytes<<3;
- }
- break;
-
- case EXT_DATA_ELEMENT:
- {
- int dataElementVersion;
-
- dataElementVersion = FDKreadBits(hBs,4);
- *count -= 4;
- if (dataElementVersion == 0) /* ANC_DATA */
- {
- int temp, dataElementLength = 0;
- do {
- temp = FDKreadBits(hBs,8);
- *count -= 8;
- dataElementLength += temp;
- } while (temp == 255 );
-
- CAacDecoder_AncDataParse(&self->ancData, hBs, dataElementLength);
- *count -= (dataElementLength<<3);
- } else {
- /* align = 0 */
- error = AAC_DEC_PARSE_ERROR;
- goto bail;
- }
- }
- break;
-
- case EXT_DATA_LENGTH:
- if ( !fIsFillElement /* Makes no sens to have an additional length in a fill ... */
- && (self->flags & AC_ER) ) /* ... element because this extension payload type was ... */
- { /* ... created to circumvent the missing length in ER-Syntax. */
- int bitCnt, len = FDKreadBits(hBs, 4);
- *count -= 4;
-
- if (len == 15) {
- int add_len = FDKreadBits(hBs, 8);
- *count -= 8;
- len += add_len;
-
- if (add_len == 255) {
- len += FDKreadBits(hBs, 16);
- *count -= 16;
- }
- }
- len <<= 3;
- bitCnt = len;
-
- if ( (EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4) == EXT_DATA_LENGTH ) {
- /* Check NOTE 2: The extension_payload() included here must
- not have extension_type == EXT_DATA_LENGTH. */
- error = AAC_DEC_PARSE_ERROR;
- } else {
- /* rewind and call myself again. */
- FDKpushBack(hBs, 4);
-
- error =
- CAacDecoder_ExtPayloadParse (
- self,
- hBs,
- &bitCnt,
- previous_element,
- elIndex,
- 0 );
-
- *count -= len - bitCnt;
- }
- /* Note: the fall through in case the if statement above is not taken is intentional. */
- break;
- }
-
- case EXT_FIL:
-
- default:
- /* align = 4 */
- FDKpushFor(hBs, *count);
- *count = 0;
- break;
- }
-
-bail:
- if ( (error != AAC_DEC_OK)
- && fIsFillElement )
- { /* Skip the remaining extension bytes */
- FDKpushBiDirectional(hBs, *count);
- *count = 0;
- /* Patch error code because decoding can go on. */
- error = AAC_DEC_OK;
- /* Be sure that parsing errors have been stored. */
- }
- return error;
-}
-
-/* Stream Configuration and Information.
-
- This class holds configuration and information data for a stream to be decoded. It
- provides the calling application as well as the decoder with substantial information,
- e.g. profile, sampling rate, number of channels found in the bitstream etc.
-*/
-static
-void CStreamInfoInit(CStreamInfo *pStreamInfo)
-{
- pStreamInfo->aacSampleRate = 0;
- pStreamInfo->profile = -1;
- pStreamInfo->aot = AOT_NONE;
-
- pStreamInfo->channelConfig = -1;
- pStreamInfo->bitRate = 0;
- pStreamInfo->aacSamplesPerFrame = 0;
-
- pStreamInfo->extAot = AOT_NONE;
- pStreamInfo->extSamplingRate = 0;
-
- pStreamInfo->flags = 0;
-
- pStreamInfo->epConfig = -1; /* default is no ER */
-
- pStreamInfo->numChannels = 0;
- pStreamInfo->sampleRate = 0;
- pStreamInfo->frameSize = 0;
-}
-
-/*!
- \brief Initialization of AacDecoderChannelInfo
-
- The function initializes the pointers to AacDecoderChannelInfo for each channel,
- set the start values for window shape and window sequence of overlap&add to zero,
- set the overlap buffer to zero and initializes the pointers to the window coefficients.
- \param bsFormat is the format of the AAC bitstream
-
- \return AACDECODER instance
-*/
-LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(TRANSPORT_TYPE bsFormat) /*!< bitstream format (adif,adts,loas,...). */
-{
- HANDLE_AACDECODER self;
-
- self = GetAacDecoder();
- if (self == NULL) {
- goto bail;
- }
-
- /* Assign channel mapping info arrays (doing so removes dependency of settings header in API header). */
- self->streamInfo.pChannelIndices = self->channelIndices;
- self->streamInfo.pChannelType = self->channelType;
-
- /* set default output mode */
- self->outputInterleaved = 1; /* interleaved */
-
- /* initialize anc data */
- CAacDecoder_AncDataInit(&self->ancData, NULL, 0);
-
- /* initialize stream info */
- CStreamInfoInit(&self->streamInfo);
-
- /* initialize error concealment common data */
- CConcealment_InitCommonData(&self->concealCommonData);
-
- self->hDrcInfo = GetDrcInfo();
- if (self->hDrcInfo == NULL) {
- goto bail;
- }
- /* Init common DRC structure */
- aacDecoder_drcInit( self->hDrcInfo );
- /* Set default frame delay */
- aacDecoder_drcSetParam (
- self->hDrcInfo,
- DRC_BS_DELAY,
- CConcealment_GetDelay(&self->concealCommonData)
- );
-
-
- self->aacCommonData.workBufferCore1 = GetWorkBufferCore1();
- self->aacCommonData.workBufferCore2 = GetWorkBufferCore2();
- if (self->aacCommonData.workBufferCore1 == NULL
- ||self->aacCommonData.workBufferCore2 == NULL )
- goto bail;
-
- return self;
-
-bail:
- CAacDecoder_Close( self );
-
- return NULL;
-}
-
-/* Destroy aac decoder */
-LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self)
-{
- int ch;
-
- if (self == NULL)
- return;
-
- for (ch=0; ch<(6); ch++) {
- if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
- if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
- FreeOverlapBuffer (&self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
- }
- if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
- FreeAacDecoderStaticChannelInfo (&self->pAacDecoderStaticChannelInfo[ch]);
- }
- }
- if (self->pAacDecoderChannelInfo[ch] != NULL) {
- FreeAacDecoderChannelInfo (&self->pAacDecoderChannelInfo[ch]);
- }
- }
-
- self->aacChannels = 0;
-
- if (self->hDrcInfo) {
- FreeDrcInfo(&self->hDrcInfo);
- }
-
- if (self->aacCommonData.workBufferCore1 != NULL) {
- FreeWorkBufferCore1 (&self->aacCommonData.workBufferCore1);
- }
- if (self->aacCommonData.workBufferCore2 != NULL) {
- FreeWorkBufferCore2 (&self->aacCommonData.workBufferCore2);
- }
-
- FreeAacDecoder ( &self);
-}
-
-
-/*!
- \brief Initialization of decoder instance
-
- The function initializes the decoder.
-
- \return error status: 0 for success, <>0 for unsupported configurations
-*/
-LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc)
-{
- AAC_DECODER_ERROR err = AAC_DEC_OK;
- INT ascChannels, ch, ascChanged = 0;
-
- if (!self)
- return AAC_DEC_INVALID_HANDLE;
-
- // set profile and check for supported aot
- // leave profile on default (=-1) for all other supported MPEG-4 aot's except aot=2 (=AAC-LC)
- switch (asc->m_aot) {
- case AOT_AAC_LC:
- self->streamInfo.profile = 1;
- break;
-
- case AOT_SBR:
- case AOT_PS:
- case AOT_ER_AAC_LD:
- case AOT_ER_AAC_ELD:
- break;
-
- default:
- return AAC_DEC_UNSUPPORTED_AOT;
- }
-
- CProgramConfig_Init(&self->pce);
-
- /* set channels */
- switch (asc->m_channelConfiguration) {
- case 0:
-#ifdef TP_PCE_ENABLE
- /* get channels from program config (ASC) */
- if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
- ascChannels = asc->m_progrConfigElement.NumChannels;
- if (ascChannels > 0) {
- int el;
- /* valid number of channels -> copy program config element (PCE) from ASC */
- FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig));
- /* Built element table */
- el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, 7);
- for (; el<7; el++) {
- self->elements[el] = ID_NONE;
- }
- } else {
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
- }
- } else {
- if (transportDec_GetFormat(self->hInput) == TT_MP4_ADTS) {
- /* set default max_channels for memory allocation because in implicit channel mapping mode
- we don't know the actual number of channels until we processed at least one raw_data_block(). */
- ascChannels = (6);
- } else {
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
- }
- }
-#else /* TP_PCE_ENABLE */
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
-#endif /* TP_PCE_ENABLE */
- break;
- case 1: case 2: case 3: case 4: case 5: case 6:
- ascChannels = asc->m_channelConfiguration;
- break;
- case 7:
- ascChannels = 8;
- break;
- default:
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
- }
-
- /* Initialize constant mappings for channel config 1-7 */
- if (asc->m_channelConfiguration > 0) {
- int el;
- FDKmemcpy(self->elements, elementsTab[asc->m_channelConfiguration-1], sizeof(MP4_ELEMENT_ID)*FDKmin(7,7));
- for (el=7; el<7; el++) {
- self->elements[el] = ID_NONE;
- }
- for (ch=0; ch<ascChannels; ch++) {
- self->chMapping[ch] = ch;
- }
- for (; ch<(6); ch++) {
- self->chMapping[ch] = 255;
- }
- }
- #ifdef TP_PCE_ENABLE
- else {
- if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
- /* Set matrix mixdown infos if available from PCE. */
- pcmDmx_SetMatrixMixdownFromPce ( self->hPcmUtils,
- asc->m_progrConfigElement.MatrixMixdownIndexPresent,
- asc->m_progrConfigElement.MatrixMixdownIndex,
- asc->m_progrConfigElement.PseudoSurroundEnable );
- }
- }
- #endif
-
- self->streamInfo.channelConfig = asc->m_channelConfiguration;
-
- if (ascChannels > (6)) {
- return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
- }
- if (self->streamInfo.aot != asc->m_aot) {
- self->streamInfo.aot = asc->m_aot;
- ascChanged = 1;
- }
-
- if (self->streamInfo.aacSamplesPerFrame != (INT)asc->m_samplesPerFrame) {
- self->streamInfo.aacSamplesPerFrame = asc->m_samplesPerFrame;
- ascChanged = 1;
- }
-
- self->streamInfo.bitRate = 0;
-
- /* Set syntax flags */
- self->flags = 0;
-
- self->streamInfo.extAot = asc->m_extensionAudioObjectType;
- self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency;
- self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
- self->flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
- self->sbrEnabled = 0;
-
- /* --------- vcb11 ------------ */
- self->flags |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
-
- /* ---------- rvlc ------------ */
- self->flags |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0;
-
- /* ----------- hcr ------------ */
- self->flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
-
- if (asc->m_aot == AOT_ER_AAC_ELD) {
- self->flags |= AC_ELD;
- self->flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
- self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0;
- }
- self->flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
- self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0;
-
-
- if (asc->m_sbrPresentFlag) {
- self->sbrEnabled = 1;
- self->sbrEnabledPrev = 1;
- }
- if (asc->m_psPresentFlag) {
- self->flags |= AC_PS_PRESENT;
- }
-
- if ( (asc->m_epConfig >= 0)
- && (asc->m_channelConfiguration <= 0) ) {
- /* we have to know the number of channels otherwise no decoding is possible */
- return AAC_DEC_UNSUPPORTED_ER_FORMAT;
- }
-
- self->streamInfo.epConfig = asc->m_epConfig;
- /* self->hInput->asc.m_epConfig = asc->m_epConfig; */
-
- if (asc->m_epConfig > 1)
- return AAC_DEC_UNSUPPORTED_ER_FORMAT;
-
- /* Check if samplerate changed. */
- if (self->streamInfo.aacSampleRate != (INT)asc->m_samplingFrequency) {
- AAC_DECODER_ERROR error;
-
- ascChanged = 1;
-
- /* Update samplerate info. */
- error = getSamplingRateInfo(&self->samplingRateInfo, asc->m_samplesPerFrame, asc->m_samplingFrequencyIndex, asc->m_samplingFrequency);
- if (error != AAC_DEC_OK) {
- return error;
- }
- self->streamInfo.aacSampleRate = self->samplingRateInfo.samplingRate;
- }
-
- /* Check if amount of channels has changed. */
- if (self->ascChannels != ascChannels)
- {
- ascChanged = 1;
-
- /* Allocate all memory structures for each channel */
- {
- for (ch = 0; ch < ascChannels; ch++) {
- CAacDecoderDynamicData *aacDecoderDynamicData = &self->aacCommonData.workBufferCore1->pAacDecoderDynamicData[ch%2];
-
- /* initialize pointer to CAacDecoderChannelInfo */
- if (self->pAacDecoderChannelInfo[ch] == NULL) {
- self->pAacDecoderChannelInfo[ch] = GetAacDecoderChannelInfo(ch);
- /* This is temporary until the DynamicData is split into two or more regions!
- The memory could be reused after completed core decoding. */
- if (self->pAacDecoderChannelInfo[ch] == NULL) {
- goto bail;
- }
- /* Hook shared work memory into channel data structure */
- self->pAacDecoderChannelInfo[ch]->pDynData = aacDecoderDynamicData;
- self->pAacDecoderChannelInfo[ch]->pComData = &self->aacCommonData;
- }
-
- /* Allocate persistent channel memory */
- if (self->pAacDecoderStaticChannelInfo[ch] == NULL) {
- self->pAacDecoderStaticChannelInfo[ch] = GetAacDecoderStaticChannelInfo(ch);
- if (self->pAacDecoderStaticChannelInfo[ch] == NULL) {
- goto bail;
- }
- self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer = GetOverlapBuffer(ch); /* This area size depends on the AOT */
- if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) {
- goto bail;
- }
- self->pAacDecoderChannelInfo[ch]->pSpectralCoefficient = (SPECTRAL_PTR) &self->aacCommonData.workBufferCore2[ch*1024];
-
- }
- CPns_InitPns(&self->pAacDecoderChannelInfo[ch]->data.aac.PnsData, &self->aacCommonData.pnsInterChannelData, &self->aacCommonData.pnsCurrentSeed, self->aacCommonData.pnsRandomSeed);
- }
-
- if (ascChannels > self->aacChannels)
- {
- /* Make allocated channel count persistent in decoder context. */
- self->aacChannels = ascChannels;
- }
-
- HcrInitRom(&self->aacCommonData.overlay.aac.erHcrInfo);
- setHcrType(&self->aacCommonData.overlay.aac.erHcrInfo, ID_SCE);
- }
-
- /* Make amount of signalled channels persistent in decoder context. */
- self->ascChannels = ascChannels;
- }
-
- /* Update structures */
- if (ascChanged) {
-
- /* Things to be done for each channel, which do not involve allocating memory.
- Doing these things only on the channels needed for the current configuration
- (ascChannels) could lead to memory access violation later (error concealment). */
- for (ch = 0; ch < self->aacChannels; ch++) {
- switch (self->streamInfo.aot) {
- case AOT_ER_AAC_ELD:
- case AOT_ER_AAC_LD:
- self->pAacDecoderChannelInfo[ch]->granuleLength = self->streamInfo.aacSamplesPerFrame;
- break;
- default:
- self->pAacDecoderChannelInfo[ch]->granuleLength = self->streamInfo.aacSamplesPerFrame / 8;
- break;
- }
- mdct_init( &self->pAacDecoderStaticChannelInfo[ch]->IMdct,
- self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
- OverlapBufferSize );
-
-
- /* Reset DRC control data for this channel */
- aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[ch]->drcData );
-
- /* Reset concealment only if ASC changed. Otherwise it will be done with any config callback.
- E.g. every time the LATM SMC is present. */
- CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
- &self->concealCommonData,
- self->streamInfo.aacSamplesPerFrame );
- }
- }
-
- /* Update externally visible copy of flags */
- self->streamInfo.flags = self->flags;
-
- return err;
-
-bail:
- aacDecoder_Close( self );
- return AAC_DEC_OUT_OF_MEMORY;
-}
-
-
-LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
- HANDLE_AACDECODER self,
- const UINT flags,
- INT_PCM *pTimeData,
- const INT timeDataSize,
- const INT interleaved
- )
-{
- AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
-
- CProgramConfig *pce;
- HANDLE_FDK_BITSTREAM bs = transportDec_GetBitstream(self->hInput, 0);
-
- MP4_ELEMENT_ID type = ID_NONE; /* Current element type */
- INT aacChannels=0; /* Channel counter for channels found in the bitstream */
-
- INT auStartAnchor = (INT)FDKgetValidBits(bs); /* AU start bit buffer position for AU byte alignment */
-
- self->frameOK = 1;
-
- /* Any supported base layer valid AU will require more than 16 bits. */
- if ( (transportDec_GetAuBitsRemaining(self->hInput, 0) < 15) && (flags & (AACDEC_CONCEAL|AACDEC_FLUSH)) == 0) {
- self->frameOK = 0;
- ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
- }
-
-
- /* Reset Program Config structure */
- pce = &self->pce;
- CProgramConfig_Reset(pce);
-
- CAacDecoder_AncDataReset(&self->ancData);
-
- {
- int ch;
-
- if (self->streamInfo.channelConfig == 0) {
- /* Init Channel/Element mapping table */
- for (ch=0; ch<(6); ch++) {
- self->chMapping[ch] = 255;
- }
- if (!CProgramConfig_IsValid(pce)) {
- int el;
- for (el=0; el<7; el++) {
- self->elements[el] = ID_NONE;
- }
- }
- }
- }
-
- /* Check sampling frequency */
- switch ( self->streamInfo.aacSampleRate ) {
- case 16000:
- case 12000:
- case 11025:
- case 8000:
- case 7350:
- case 48000:
- case 44100:
- case 32000:
- case 24000:
- case 22050:
- break;
- default:
- if ( ! (self->flags & (AC_USAC|AC_RSVD50)) ) {
- return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
- }
- break;
- }
-
-
- if ( flags & AACDEC_CLRHIST )
- {
- int ch;
- /* Clear history */
- for (ch = 0; ch < self->aacChannels; ch++) {
- /* Reset concealment */
- CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
- &self->concealCommonData,
- self->streamInfo.aacSamplesPerFrame );
- /* Clear concealment buffers to get rid of the complete history */
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.spectralCoefficient, 1024 * sizeof(FIXP_CNCL));
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo.specScale, 8 * sizeof(SHORT));
- /* Clear overlap-add buffers to avoid clicks. */
- FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->IMdct.overlap.freq, OverlapBufferSize*sizeof(FIXP_DBL));
- }
- }
-
-
-
-#ifdef TP_PCE_ENABLE
- int pceRead = 0; /* Flag indicating a PCE in the current raw_data_block() */
-#endif
-
-
- INT hdaacDecoded = 0;
- MP4_ELEMENT_ID previous_element = ID_END; /* Last element ID (required for extension payload mapping */
- UCHAR previous_element_index = 0; /* Canonical index of last element */
- int element_count = 0; /* Element counter for elements found in the bitstream */
- int el_cnt[ID_LAST] = { 0 }; /* element counter ( robustness ) */
-
- while ( (type != ID_END) && (! (flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) && self->frameOK )
- {
- int el_channels;
-
- if (! (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_SCALABLE|AC_ER)))
- type = (MP4_ELEMENT_ID) FDKreadBits(bs,3);
- else
- type = self->elements[element_count];
-
- setHcrType(&self->aacCommonData.overlay.aac.erHcrInfo, type);
-
-
- if ((INT)FDKgetValidBits(bs) < 0)
- self->frameOK = 0;
-
- switch (type)
- {
- case ID_SCE:
- case ID_CPE:
- case ID_LFE:
- /*
- Consistency check
- */
-
- if (type == ID_CPE) {
- el_channels = 2;
- } else {
- el_channels = 1;
- }
-
- if ( (el_cnt[type] >= (self->ascChannels>>(el_channels-1))) || (aacChannels > (self->ascChannels-el_channels)) ) {
- ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
- self->frameOK = 0;
- break;
- }
-
- if ( !(self->flags & (AC_USAC|AC_RSVD50)) ) {
- int ch;
- for (ch=0; ch < el_channels; ch+=1) {
- CPns_ResetData(&self->pAacDecoderChannelInfo[aacChannels+ch]->data.aac.PnsData,
- &self->pAacDecoderChannelInfo[aacChannels+ch]->pComData->pnsInterChannelData);
- }
- }
-
- if(self->frameOK) {
- ErrorStatus = CChannelElement_Read( bs,
- &self->pAacDecoderChannelInfo[aacChannels],
- &self->pAacDecoderStaticChannelInfo[aacChannels],
- self->streamInfo.aot,
- &self->samplingRateInfo,
- self->flags,
- self->streamInfo.aacSamplesPerFrame,
- el_channels,
- self->streamInfo.epConfig,
- self->hInput
- );
- if (ErrorStatus) {
- self->frameOK = 0;
- }
- }
-
-
- if ( self->frameOK) {
- /* Lookup the element and decode it only if it belongs to the current program */
- if ( CProgramConfig_LookupElement(
- pce,
- self->streamInfo.channelConfig,
- self->pAacDecoderChannelInfo[aacChannels]->ElementInstanceTag,
- aacChannels,
- self->chMapping,
- self->channelType,
- self->channelIndices,
- &previous_element_index,
- self->elements,
- type) )
- {
- if ( !hdaacDecoded ) {
- CChannelElement_Decode(
- &self->pAacDecoderChannelInfo[aacChannels],
- &self->pAacDecoderStaticChannelInfo[aacChannels],
- &self->samplingRateInfo,
- self->flags,
- el_channels
- );
- }
- aacChannels += 1;
- if (type == ID_CPE) {
- aacChannels += 1;
- }
- }
- else {
- self->frameOK = 0;
- }
- /* Create SBR element for SBR for upsampling for LFE elements,
- and if SBR was explicitly signaled, because the first frame(s)
- may not contain SBR payload (broken encoder, bit errors). */
- if ( (self->flags & AC_SBR_PRESENT) || (self->sbrEnabled == 1) )
- {
- SBR_ERROR sbrError;
-
- sbrError = sbrDecoder_InitElement(
- self->hSbrDecoder,
- self->streamInfo.aacSampleRate,
- self->streamInfo.extSamplingRate,
- self->streamInfo.aacSamplesPerFrame,
- self->streamInfo.aot,
- type,
- previous_element_index
- );
- if (sbrError != SBRDEC_OK) {
- /* Do not try to apply SBR because initializing the element failed. */
- self->sbrEnabled = 0;
- }
- }
- }
-
- el_cnt[type]++;
- break;
-
- case ID_CCE:
- /*
- Consistency check
- */
- if ( el_cnt[type] > self->ascChannels ) {
- ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
- self->frameOK = 0;
- break;
- }
-
- if (self->frameOK)
- {
- /* memory for spectral lines temporal on scratch */
- C_ALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024);
-
- /* create dummy channel for CCE parsing on stack */
- CAacDecoderChannelInfo tmpAacDecoderChannelInfo, *pTmpAacDecoderChannelInfo;
-
- FDKmemclear(mdctSpec, 1024*sizeof(FIXP_DBL));
-
- tmpAacDecoderChannelInfo.pDynData = self->aacCommonData.workBufferCore1->pAacDecoderDynamicData;
- tmpAacDecoderChannelInfo.pComData = &self->aacCommonData;
- tmpAacDecoderChannelInfo.pSpectralCoefficient = (SPECTRAL_PTR)mdctSpec;
- /* Assume AAC-LC */
- tmpAacDecoderChannelInfo.granuleLength = self->streamInfo.aacSamplesPerFrame / 8;
-
- /* Reset PNS data. */
- CPns_ResetData(&tmpAacDecoderChannelInfo.data.aac.PnsData, &tmpAacDecoderChannelInfo.pComData->pnsInterChannelData);
-
- pTmpAacDecoderChannelInfo = &tmpAacDecoderChannelInfo;
- /* do CCE parsing */
- ErrorStatus = CChannelElement_Read( bs,
- &pTmpAacDecoderChannelInfo,
- NULL,
- self->streamInfo.aot,
- &self->samplingRateInfo,
- self->flags,
- self->streamInfo.aacSamplesPerFrame,
- 1,
- self->streamInfo.epConfig,
- self->hInput
- );
-
- C_ALLOC_SCRATCH_END(mdctSpec, FIXP_DBL, 1024);
-
- if (ErrorStatus) {
- self->frameOK = 0;
- }
-
- if (self->frameOK) {
- /* Lookup the element and decode it only if it belongs to the current program */
- if (CProgramConfig_LookupElement(
- pce,
- self->streamInfo.channelConfig,
- pTmpAacDecoderChannelInfo->ElementInstanceTag,
- 0,
- self->chMapping,
- self->channelType,
- self->channelIndices,
- &previous_element_index,
- self->elements,
- type) )
- {
- /* decoding of CCE not supported */
- }
- else {
- self->frameOK = 0;
- }
- }
- }
- el_cnt[type]++;
- break;
-
- case ID_DSE:
- {
- UCHAR element_instance_tag;
-
- CDataStreamElement_Read( bs,
- &self->ancData,
- self->hDrcInfo,
- self->hInput,
- &element_instance_tag,
- auStartAnchor );
-
- if (!CProgramConfig_LookupElement(
- pce,
- self->streamInfo.channelConfig,
- element_instance_tag,
- 0,
- self->chMapping,
- self->channelType,
- self->channelIndices,
- &previous_element_index,
- self->elements,
- type) )
- {
- /* most likely an error in bitstream occured */
- //self->frameOK = 0;
- }
- }
-
- {
- UCHAR *pDvbAncData = NULL;
- AAC_DECODER_ERROR ancErr;
- int ancIndex;
- int dvbAncDataSize = 0;
-
- /* Ask how many anc data elements are in buffer */
- ancIndex = self->ancData.nrElements - 1;
- /* Get the last one (if available) */
- ancErr = CAacDecoder_AncDataGet( &self->ancData,
- ancIndex,
- &pDvbAncData,
- &dvbAncDataSize );
-
- if (ancErr == AAC_DEC_OK) {
- pcmDmx_ReadDvbAncData (
- self->hPcmUtils,
- pDvbAncData,
- dvbAncDataSize,
- 0 /* not mpeg2 */ );
- }
- }
- break;
-
-#ifdef TP_PCE_ENABLE
- case ID_PCE:
- {
- int result = CProgramConfigElement_Read(
- bs,
- self->hInput,
- pce,
- self->streamInfo.channelConfig,
- auStartAnchor );
- if ( result < 0 ) {
- /* Something went wrong */
- ErrorStatus = AAC_DEC_PARSE_ERROR;
- self->frameOK = 0;
- }
- else if ( result > 1 ) {
- /* Built element table */
- int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
- /* Reset the remaining tabs */
- for ( ; elIdx<7; elIdx++) {
- self->elements[elIdx] = ID_NONE;
- }
- /* Make new number of channel persistant */
- self->ascChannels = pce->NumChannels;
- /* If PCE is not first element conceal this frame to avoid inconsistencies */
- if ( element_count != 0 ) {
- self->frameOK = 0;
- }
- }
- pceRead = (result>=0) ? 1 : 0;
- }
- break;
-#endif /* TP_PCE_ENABLE */
-
- case ID_FIL:
- {
- int bitCnt = FDKreadBits(bs,4); /* bs_count */
-
- if (bitCnt == 15)
- {
- int esc_count = FDKreadBits(bs,8); /* bs_esc_count */
- bitCnt = esc_count + 14;
- }
-
- /* Convert to bits */
- bitCnt <<= 3;
-
- while (bitCnt > 0) {
- ErrorStatus = CAacDecoder_ExtPayloadParse(self, bs, &bitCnt, previous_element, previous_element_index, 1);
- if (ErrorStatus != AAC_DEC_OK) {
- self->frameOK = 0;
- break;
- }
- }
- }
- break;
-
- case ID_EXT:
- {
- INT bitCnt = 0;
-
- /* get the remaining bits of this frame */
- bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
-
- if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
- {
- SBR_ERROR err = SBRDEC_OK;
- int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
-
- for (elIdx = 0; elIdx < numChElements; elIdx += 1)
- {
- err = sbrDecoder_Parse (
- self->hSbrDecoder,
- bs,
- &bitCnt,
- -1,
- self->flags & AC_SBRCRC,
- self->elements[elIdx],
- elIdx,
- self->flags & AC_INDEP );
-
- if (err != SBRDEC_OK) {
- break;
- }
- }
- if (err == SBRDEC_OK) {
- self->sbrEnabled = 1;
- } else {
- self->frameOK = 0;
- }
- }
-
-
- if ( ! (self->flags & (AC_USAC|AC_RSVD50|AC_DRM)) )
- {
- while ( bitCnt > 7 ) {
- ErrorStatus = CAacDecoder_ExtPayloadParse(self, bs, &bitCnt, previous_element, previous_element_index, 0);
- if (ErrorStatus != AAC_DEC_OK) {
- self->frameOK = 0;
- ErrorStatus = AAC_DEC_PARSE_ERROR;
- break;
- }
- }
- }
- }
- break;
-
- case ID_END:
- break;
-
- default:
- ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
- self->frameOK = 0;
- break;
- }
-
- previous_element = type;
- element_count++;
-
- } /* while ( (type != ID_END) ... ) */
-
- if ( !(flags & (AACDEC_CONCEAL|AACDEC_FLUSH)) )
- {
- /* Byte alignment with respect to the first bit of the raw_data_block(). */
- {
- FDKbyteAlign(bs, auStartAnchor);
- }
-
- /* Check if all bits of the raw_data_block() have been read. */
- if ( transportDec_GetAuBitsTotal(self->hInput, 0) > 0 ) {
- INT unreadBits = transportDec_GetAuBitsRemaining(self->hInput, 0);
- if ( unreadBits != 0 ) {
-
- self->frameOK = 0;
- /* Do not overwrite current error */
- if (ErrorStatus == AAC_DEC_OK && self->frameOK == 0) {
- ErrorStatus = AAC_DEC_PARSE_ERROR;
- }
- /* Always put the bitbuffer at the right position after the current Access Unit. */
- FDKpushBiDirectional(bs, unreadBits);
- }
- }
-
- /* Check the last element. The terminator (ID_END) has to be the last one (even if ER syntax is used). */
- if ( self->frameOK && type != ID_END ) {
- /* Do not overwrite current error */
- if (ErrorStatus == AAC_DEC_OK) {
- ErrorStatus = AAC_DEC_PARSE_ERROR;
- }
- self->frameOK = 0;
- }
- }
-
- /* More AAC channels than specified by the ASC not allowed. */
- if ( (aacChannels == 0 || aacChannels > self->aacChannels) && !(flags & (AACDEC_CONCEAL|AACDEC_FLUSH)) ) {
- {
- /* Do not overwrite current error */
- if (ErrorStatus == AAC_DEC_OK) {
- ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
- }
- self->frameOK = 0;
- }
- aacChannels = 0;
- }
- else if ( aacChannels > self->ascChannels ) {
- /* Do not overwrite current error */
- if (ErrorStatus == AAC_DEC_OK) {
- ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
- }
- self->frameOK = 0;
- aacChannels = 0;
- }
-
- if ( TRANSPORTDEC_OK != transportDec_CrcCheck(self->hInput) )
- {
- self->frameOK=0;
- }
-
- /* store or restore the number of channels */
- if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) {
- self->concealChannels = aacChannels; /* store */
- self->sbrEnabledPrev = self->sbrEnabled;
- } else {
- if (self->aacChannels > 0) {
- aacChannels = self->concealChannels; /* restore */
- self->sbrEnabled = self->sbrEnabledPrev;
- }
- }
-
- /* Update number of output channels */
- self->streamInfo.aacNumChannels = aacChannels;
-
- #ifdef TP_PCE_ENABLE
- if (pceRead == 1 && CProgramConfig_IsValid(pce)) {
- /* Set matrix mixdown infos if available from PCE. */
- pcmDmx_SetMatrixMixdownFromPce ( self->hPcmUtils,
- pce->MatrixMixdownIndexPresent,
- pce->MatrixMixdownIndex,
- pce->PseudoSurroundEnable );
- }
- #endif
-
- /* If there is no valid data to transfrom into time domain, return. */
- if ( ! IS_OUTPUT_VALID(ErrorStatus) ) {
- return ErrorStatus;
- }
-
- /*
- Inverse transform
- */
- {
- int stride, offset, c;
-
- /* Extract DRC control data and map it to channels (without bitstream delay) */
- aacDecoder_drcProlog (
- self->hDrcInfo,
- bs,
- self->pAacDecoderStaticChannelInfo,
- self->pce.ElementInstanceTag,
- self->chMapping,
- aacChannels
- );
-
- /* "c" iterates in canonical MPEG channel order */
- for (c=0; c < aacChannels; c++)
- {
- CAacDecoderChannelInfo *pAacDecoderChannelInfo;
-
- /* Select correct pAacDecoderChannelInfo for current channel */
- if (self->chMapping[c] >= aacChannels) {
- pAacDecoderChannelInfo = self->pAacDecoderChannelInfo[c];
- } else {
- pAacDecoderChannelInfo = self->pAacDecoderChannelInfo[self->chMapping[c]];
- }
-
- /* Setup offset and stride for time buffer traversal. */
- if (interleaved) {
- stride = aacChannels;
- offset = self->channelOutputMapping[aacChannels-1][c];
- } else {
- stride = 1;
- offset = self->channelOutputMapping[aacChannels-1][c] * self->streamInfo.aacSamplesPerFrame;
- }
-
-
- /*
- Conceal defective spectral data
- */
- CConcealment_Apply(&self->pAacDecoderStaticChannelInfo[c]->concealmentInfo,
- pAacDecoderChannelInfo,
- self->pAacDecoderStaticChannelInfo[c],
- &self->samplingRateInfo,
- self->streamInfo.aacSamplesPerFrame,
- 0,
- (self->frameOK && !(flags&AACDEC_CONCEAL)),
- self->flags
- );
-
-
- if (flags & (AACDEC_INTR|AACDEC_CLRHIST)) {
- /* Reset DRC control data for this channel */
- aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[c]->drcData );
- }
- /* DRC processing */
- aacDecoder_drcApply (
- self->hDrcInfo,
- self->hSbrDecoder,
- pAacDecoderChannelInfo,
- &self->pAacDecoderStaticChannelInfo[c]->drcData,
- c,
- self->streamInfo.aacSamplesPerFrame,
- self->sbrEnabled
- );
-
- switch (pAacDecoderChannelInfo->renderMode)
- {
- case AACDEC_RENDER_IMDCT:
- CBlock_FrequencyToTime(
- self->pAacDecoderStaticChannelInfo[c],
- pAacDecoderChannelInfo,
- pTimeData + offset,
- self->streamInfo.aacSamplesPerFrame,
- stride,
- (self->frameOK && !(flags&AACDEC_CONCEAL)),
- self->aacCommonData.workBufferCore1->mdctOutTemp
- );
- break;
- case AACDEC_RENDER_ELDFB:
- CBlock_FrequencyToTimeLowDelay(
- self->pAacDecoderStaticChannelInfo[c],
- pAacDecoderChannelInfo,
- pTimeData + offset,
- self->streamInfo.aacSamplesPerFrame,
- stride
- );
- break;
- default:
- ErrorStatus = AAC_DEC_UNKNOWN;
- break;
- }
- if ( flags&AACDEC_FLUSH ) {
- FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, sizeof(FIXP_DBL)*self->streamInfo.aacSamplesPerFrame);
- FDKmemclear(self->pAacDecoderStaticChannelInfo[c]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL));
- }
- }
-
-
- /* Extract DRC control data and map it to channels (with bitstream delay) */
- aacDecoder_drcEpilog (
- self->hDrcInfo,
- bs,
- self->pAacDecoderStaticChannelInfo,
- self->pce.ElementInstanceTag,
- self->chMapping,
- aacChannels
- );
- }
-
-
- /* Reorder channel type information tables. */
- {
- AUDIO_CHANNEL_TYPE types[(6)];
- UCHAR idx[(6)];
- int c;
-
- FDK_ASSERT(sizeof(self->channelType) == sizeof(types));
- FDK_ASSERT(sizeof(self->channelIndices) == sizeof(idx));
-
- FDKmemcpy(types, self->channelType, sizeof(types));
- FDKmemcpy(idx, self->channelIndices, sizeof(idx));
-
- for (c=0; c<aacChannels; c++) {
- self->channelType[self->channelOutputMapping[aacChannels-1][c]] = types[c];
- self->channelIndices[self->channelOutputMapping[aacChannels-1][c]] = idx[c];
- }
- }
-
- self->blockNumber++;
-
- return ErrorStatus;
-}
-
-/*!
- \brief returns the streaminfo pointer
-
- The function hands back a pointer to the streaminfo structure
-
- \return pointer to the struct
-*/
-LINKSPEC_CPP CStreamInfo* CAacDecoder_GetStreamInfo ( HANDLE_AACDECODER self )
-{
- if (!self) {
- return NULL;
- }
- return &self->streamInfo;
-}
-
-
-
-