/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 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
----------------------------------------------------------------------------- */

/**************************** AAC decoder library ******************************

   Author(s):   Manuel Jander

   Description:

*******************************************************************************/

#include "aacdecoder_lib.h"

#include "aac_ram.h"
#include "aacdecoder.h"
#include "tpdec_lib.h"
#include "FDK_core.h" /* FDK_tools version info */

#include "sbrdecoder.h"

#include "conceal.h"

#include "aacdec_drc.h"

#include "sac_dec_lib.h"

#include "pcm_utils.h"

/* Decoder library info */
#define AACDECODER_LIB_VL0 3
#define AACDECODER_LIB_VL1 0
#define AACDECODER_LIB_VL2 0
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE ""
#define AACDECODER_LIB_BUILD_TIME ""
#else
#define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__
#endif

static AAC_DECODER_ERROR setConcealMethod(const HANDLE_AACDECODER self,
                                          const INT method);

static void aacDecoder_setMetadataExpiry(const HANDLE_AACDECODER self,
                                         const INT value) {
  /* check decoder handle */
  if (self != NULL) {
    INT mdExpFrame = 0; /* default: disable */

    if ((value > 0) &&
        (self->streamInfo.aacSamplesPerFrame >
         0)) { /* Determine the corresponding number of frames: */
      FIXP_DBL frameTime = fDivNorm(self->streamInfo.aacSampleRate,
                                    self->streamInfo.aacSamplesPerFrame * 1000);
      mdExpFrame = fMultIceil(frameTime, value);
    }

    /* Configure DRC module */
    aacDecoder_drcSetParam(self->hDrcInfo, DRC_DATA_EXPIRY_FRAME, mdExpFrame);

    /* Configure PCM downmix module */
    pcmDmx_SetParam(self->hPcmUtils, DMX_BS_DATA_EXPIRY_FRAME, mdExpFrame);
  }
}

LINKSPEC_CPP AAC_DECODER_ERROR
aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes) {
  /* reset free bytes */
  *pFreeBytes = 0;

  /* check handle */
  if (!self) return AAC_DEC_INVALID_HANDLE;

  /* return nr of free bytes */
  HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0);
  *pFreeBytes = FDKgetFreeBits(hBs) >> 3;

  /* success */
  return AAC_DEC_OK;
}

/**
 * Config Decoder using a CSAudioSpecificConfig struct.
 */
static LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Config(
    HANDLE_AACDECODER self, const CSAudioSpecificConfig *pAscStruct,
    UCHAR configMode, UCHAR *configChanged) {
  AAC_DECODER_ERROR err;

  /* Initialize AAC core decoder, and update self->streaminfo */
  err = CAacDecoder_Init(self, pAscStruct, configMode, configChanged);

  if (!FDK_chMapDescr_isValid(&self->mapDescr)) {
    return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
  }

  return err;
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self,
                                                    UCHAR *conf[],
                                                    const UINT length[]) {
  AAC_DECODER_ERROR err = AAC_DEC_OK;
  TRANSPORTDEC_ERROR errTp;
  UINT layer, nrOfLayers = self->nrOfLayers;

  for (layer = 0; layer < nrOfLayers; layer++) {
    if (length[layer] > 0) {
      errTp = transportDec_OutOfBandConfig(self->hInput, conf[layer],
                                           length[layer], layer);
      if (errTp != TRANSPORTDEC_OK) {
        switch (errTp) {
          case TRANSPORTDEC_NEED_TO_RESTART:
            err = AAC_DEC_NEED_TO_RESTART;
            break;
          case TRANSPORTDEC_UNSUPPORTED_FORMAT:
            err = AAC_DEC_UNSUPPORTED_FORMAT;
            break;
          default:
            err = AAC_DEC_UNKNOWN;
            break;
        }
        /* if baselayer is OK we continue decoding */
        if (layer >= 1) {
          self->nrOfLayers = layer;
          err = AAC_DEC_OK;
        }
        break;
      }
    }
  }

  return err;
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self,
                                                         UCHAR *buffer,
                                                         UINT length) {
  FDK_BITSTREAM bs;
  HANDLE_FDK_BITSTREAM hBs = &bs;
  AAC_DECODER_ERROR err = AAC_DEC_OK;

  if (length < 8) return AAC_DEC_UNKNOWN;

  while (length >= 8) {
    UINT size =
        (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
    DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;

    if (length < size) return AAC_DEC_UNKNOWN;
    if (size <= 8) return AAC_DEC_UNKNOWN;

    FDKinitBitStream(hBs, buffer + 8, 0x10000000, (size - 8) * 8);

    if ((buffer[4] == 'l') && (buffer[5] == 'u') && (buffer[6] == 'd') &&
        (buffer[7] == 't')) {
      uniDrcErr = FDK_drcDec_ReadLoudnessBox(self->hUniDrcDecoder, hBs);
    } else if ((buffer[4] == 'd') && (buffer[5] == 'm') && (buffer[6] == 'i') &&
               (buffer[7] == 'x')) {
      uniDrcErr =
          FDK_drcDec_ReadDownmixInstructions_Box(self->hUniDrcDecoder, hBs);
    } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'i') &&
               (buffer[7] == '2')) {
      uniDrcErr =
          FDK_drcDec_ReadUniDrcInstructions_Box(self->hUniDrcDecoder, hBs);
    } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'c') &&
               (buffer[7] == '2')) {
      uniDrcErr =
          FDK_drcDec_ReadUniDrcCoefficients_Box(self->hUniDrcDecoder, hBs);
    }

    if (uniDrcErr != DRC_DEC_OK) err = AAC_DEC_UNKNOWN;

    buffer += size;
    length -= size;
  }

  return err;
}

static INT aacDecoder_ConfigCallback(void *handle,
                                     const CSAudioSpecificConfig *pAscStruct,
                                     UCHAR configMode, UCHAR *configChanged) {
  HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
  AAC_DECODER_ERROR err = AAC_DEC_OK;
  TRANSPORTDEC_ERROR errTp;

  FDK_ASSERT(self != NULL);
  {
    { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); }
  }
  if (err == AAC_DEC_OK) {
    /*
    revert concealment method if either
       - Interpolation concealment might not be meaningful
       - Interpolation concealment is not implemented
    */
    if ((self->flags[0] & (AC_LD | AC_ELD) &&
         (self->concealMethodUser == ConcealMethodNone) &&
         CConcealment_GetDelay(&self->concealCommonData) >
             0) /* might not be meaningful but allow if user has set it
                   expicitly */
        || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) &&
            CConcealment_GetDelay(&self->concealCommonData) >
                0) /* not implemented */
    ) {
      /* Revert to error concealment method Noise Substitution.
         Because interpolation is not implemented for USAC or
         the additional delay is unwanted for low delay codecs. */
      setConcealMethod(self, 1);
    }
    aacDecoder_setMetadataExpiry(self, self->metadataExpiry);
    errTp = TRANSPORTDEC_OK;
  } else {
    if (err == AAC_DEC_NEED_TO_RESTART) {
      errTp = TRANSPORTDEC_NEED_TO_RESTART;
    } else if (IS_INIT_ERROR(err)) {
      errTp = TRANSPORTDEC_UNSUPPORTED_FORMAT;
    } /* Fatal errors */
    else {
      errTp = TRANSPORTDEC_UNKOWN_ERROR;
    }
  }

  return errTp;
}

static INT aacDecoder_FreeMemCallback(void *handle,
                                      const CSAudioSpecificConfig *pAscStruct) {
  TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
  HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;

  const int subStreamIndex = 0;

  FDK_ASSERT(self != NULL);

  if (CAacDecoder_FreeMem(self, subStreamIndex) != AAC_DEC_OK) {
    errTp = TRANSPORTDEC_UNKOWN_ERROR;
  }

  /* free Ram_SbrDecoder and Ram_SbrDecChannel */
  if (self->hSbrDecoder != NULL) {
    if (sbrDecoder_FreeMem(&self->hSbrDecoder) != SBRDEC_OK) {
      errTp = TRANSPORTDEC_UNKOWN_ERROR;
    }
  }

  /* free pSpatialDec and mpsData */
  if (self->pMpegSurroundDecoder != NULL) {
    if (mpegSurroundDecoder_FreeMem(
            (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) != MPS_OK) {
      errTp = TRANSPORTDEC_UNKOWN_ERROR;
    }
  }

  /* free persistent qmf domain buffer, QmfWorkBufferCore3, QmfWorkBufferCore4,
   * QmfWorkBufferCore5 and configuration variables */
  FDK_QmfDomain_FreeMem(&self->qmfDomain);

  return errTp;
}

static INT aacDecoder_CtrlCFGChangeCallback(
    void *handle, const CCtrlCFGChange *pCtrlCFGChangeStruct) {
  TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
  HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;

  if (self != NULL) {
    CAacDecoder_CtrlCFGChange(
        self, pCtrlCFGChangeStruct->flushStatus, pCtrlCFGChangeStruct->flushCnt,
        pCtrlCFGChangeStruct->buildUpStatus, pCtrlCFGChangeStruct->buildUpCnt);
  } else {
    errTp = TRANSPORTDEC_UNKOWN_ERROR;
  }

  return errTp;
}

static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
                                  const AUDIO_OBJECT_TYPE coreCodec,
                                  const INT samplingRate,
                                  const INT stereoConfigIndex,
                                  const INT coreSbrFrameLengthIndex,
                                  const INT configBytes, const UCHAR configMode,
                                  UCHAR *configChanged) {
  SACDEC_ERROR err;
  TRANSPORTDEC_ERROR errTp;
  HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;

  err = mpegSurroundDecoder_Config(
      (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
      samplingRate, stereoConfigIndex, coreSbrFrameLengthIndex, configBytes,
      configMode, configChanged);

  switch (err) {
    case MPS_UNSUPPORTED_CONFIG:
      /* MPS found but invalid or not decodable by this instance            */
      /* We switch off MPS and keep going                                   */
      hAacDecoder->mpsEnableCurr = 0;
      hAacDecoder->mpsApplicable = 0;
      errTp = TRANSPORTDEC_OK;
      break;
    case MPS_PARSE_ERROR:
      /* MPS found but invalid or not decodable by this instance            */
      hAacDecoder->mpsEnableCurr = 0;
      hAacDecoder->mpsApplicable = 0;
      if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) ||
          IS_LOWDELAY(coreCodec)) {
        errTp = TRANSPORTDEC_PARSE_ERROR;
      } else {
        errTp = TRANSPORTDEC_OK;
      }
      break;
    case MPS_OK:
      hAacDecoder->mpsApplicable = 1;
      errTp = TRANSPORTDEC_OK;
      break;
    default:
      /* especially Parsing error is critical for transport layer          */
      hAacDecoder->mpsApplicable = 0;
      errTp = TRANSPORTDEC_UNKOWN_ERROR;
  }

  return (INT)errTp;
}

static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
                                     const INT fullPayloadLength,
                                     const INT payloadType,
                                     const INT subStreamIndex,
                                     const INT payloadStart,
                                     const AUDIO_OBJECT_TYPE aot) {
  DRC_DEC_ERROR err = DRC_DEC_OK;
  TRANSPORTDEC_ERROR errTp;
  HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
  DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;

  if (subStreamIndex != 0) {
    return TRANSPORTDEC_OK;
  }

  else if (aot == AOT_USAC) {
    drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
  }

  err = FDK_drcDec_SetCodecMode(hAacDecoder->hUniDrcDecoder, drcDecCodecMode);
  if (err) return (INT)TRANSPORTDEC_UNKOWN_ERROR;

  if (payloadType == 0) /* uniDrcConfig */
  {
    err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs);
  } else /* loudnessInfoSet */
  {
    err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs);
    hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
    hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
  }

  if (err == DRC_DEC_OK)
    errTp = TRANSPORTDEC_OK;
  else
    errTp = TRANSPORTDEC_UNKOWN_ERROR;

  return (INT)errTp;
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self,
                                                      UCHAR *buffer, int size) {
  CAncData *ancData = &self->ancData;

  return CAacDecoder_AncDataInit(ancData, buffer, size);
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self,
                                                     int index, UCHAR **ptr,
                                                     int *size) {
  CAncData *ancData = &self->ancData;

  return CAacDecoder_AncDataGet(ancData, index, ptr, size);
}

/* If MPS is present in stream, but not supported by this instance, we'll
   have to switch off MPS and use QMF synthesis in the SBR module if required */
static int isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot,
                                unsigned int numInChannels,
                                unsigned int fMpsPresent) {
  LIB_INFO libInfo[FDK_MODULE_LAST];
  UINT mpsCaps;
  int isSupportedCfg = 1;

  FDKinitLibInfo(libInfo);

  mpegSurroundDecoder_GetLibInfo(libInfo);

  mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);

  if (!(mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot)) {
    /* We got an LD AOT but MPS decoder does not support LD. */
    isSupportedCfg = 0;
  }
  if ((mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot) && !fMpsPresent) {
    /* We got an LD AOT and the MPS decoder supports it.
     * But LD-MPS is not explicitly signaled. */
    isSupportedCfg = 0;
  }
  if (!(mpsCaps & CAPF_MPS_USAC) && IS_USAC(aot)) {
    /* We got an USAC AOT but MPS decoder does not support USAC. */
    isSupportedCfg = 0;
  }
  if (!(mpsCaps & CAPF_MPS_STD) && !IS_LOWDELAY(aot) && !IS_USAC(aot)) {
    /* We got an GA AOT but MPS decoder does not support it. */
    isSupportedCfg = 0;
  }
  /* Check whether the MPS modul supports the given number of input channels: */
  switch (numInChannels) {
    case 1:
      if (!(mpsCaps & CAPF_MPS_1CH_IN)) {
        /* We got a one channel input to MPS decoder but it does not support it.
         */
        isSupportedCfg = 0;
      }
      break;
    case 2:
      if (!(mpsCaps & CAPF_MPS_2CH_IN)) {
        /* We got a two channel input to MPS decoder but it does not support it.
         */
        isSupportedCfg = 0;
      }
      break;
    case 5:
    case 6:
      if (!(mpsCaps & CAPF_MPS_6CH_IN)) {
        /* We got a six channel input to MPS decoder but it does not support it.
         */
        isSupportedCfg = 0;
      }
      break;
    default:
      isSupportedCfg = 0;
  }

  return (isSupportedCfg);
}

static AAC_DECODER_ERROR setConcealMethod(
    const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
    const INT method) {
  AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
  CConcealParams *pConcealData = NULL;
  int method_revert = 0;
  HANDLE_SBRDECODER hSbrDec = NULL;
  HANDLE_AAC_DRC hDrcInfo = NULL;
  HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
  CConcealmentMethod backupMethod = ConcealMethodNone;
  int backupDelay = 0;
  int bsDelay = 0;

  /* check decoder handle */
  if (self != NULL) {
    pConcealData = &self->concealCommonData;
    hSbrDec = self->hSbrDecoder;
    hDrcInfo = self->hDrcInfo;
    hPcmDmx = self->hPcmUtils;
    if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
      /* Interpolation concealment is not implemented for USAC/RSVD50 */
      /* errorStatus = AAC_DEC_SET_PARAM_FAIL;
         goto bail; */
      method_revert = 1;
    }
    if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
      /* Interpolation concealment is not implemented for USAC/RSVD50 */
      errorStatus = AAC_DEC_SET_PARAM_FAIL;
      goto bail;
    }
  }

  /* Get current method/delay */
  backupMethod = CConcealment_GetMethod(pConcealData);
  backupDelay = CConcealment_GetDelay(pConcealData);

  /* Be sure to set AAC and SBR concealment method simultaneously! */
  errorStatus = CConcealment_SetParams(
      pConcealData,
      (method_revert == 0) ? (int)method : (int)1,  // concealMethod
      AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,           // concealFadeOutSlope
      AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,           // concealFadeInSlope
      AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,           // concealMuteRelease
      AACDEC_CONCEAL_PARAM_NOT_SPECIFIED            // concealComfNoiseLevel
  );
  if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
    goto bail;
  }

  /* Get new delay */
  bsDelay = CConcealment_GetDelay(pConcealData);

  {
    SBR_ERROR sbrErr = SBRDEC_OK;

    /* set SBR bitstream delay */
    sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay);

    switch (sbrErr) {
      case SBRDEC_OK:
      case SBRDEC_NOT_INITIALIZED:
        if (self != NULL) {
          /* save the param value and set later
             (when SBR has been initialized) */
          self->sbrParams.bsDelay = bsDelay;
        }
        break;
      default:
        errorStatus = AAC_DEC_SET_PARAM_FAIL;
        goto bail;
    }
  }

  errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay);
  if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
    goto bail;
  }

  if (errorStatus == AAC_DEC_OK) {
    PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay);
    switch (err) {
      case PCMDMX_INVALID_HANDLE:
        errorStatus = AAC_DEC_INVALID_HANDLE;
      case PCMDMX_OK:
        break;
      default:
        errorStatus = AAC_DEC_SET_PARAM_FAIL;
        goto bail;
    }
  }

bail:
  if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
    /* Revert to the initial state */
    CConcealment_SetParams(
        pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
        AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
        AACDEC_CONCEAL_PARAM_NOT_SPECIFIED);
    /* Revert SBR bitstream delay */
    sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay);
    /* Revert DRC bitstream delay */
    aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay);
    /* Revert PCM mixdown bitstream delay */
    pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay);
  }

  return errorStatus;
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam(
    const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
    const AACDEC_PARAM param,     /*!< Parameter to set               */
    const INT value)              /*!< Parameter valued               */
{
  AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
  HANDLE_TRANSPORTDEC hTpDec = NULL;
  TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
  HANDLE_AAC_DRC hDrcInfo = NULL;
  HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
  PCMDMX_ERROR dmxErr = PCMDMX_OK;
  TDLimiterPtr hPcmTdl = NULL;
  DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;

  /* check decoder handle */
  if (self != NULL) {
    hTpDec = self->hInput;
    hDrcInfo = self->hDrcInfo;
    hPcmDmx = self->hPcmUtils;
    hPcmTdl = self->hLimiter;
  } else {
    errorStatus = AAC_DEC_INVALID_HANDLE;
    goto bail;
  }

  /* configure the subsystems */
  switch (param) {
    case AAC_PCM_MIN_OUTPUT_CHANNELS:
      if (value < -1 || value > (8)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      dmxErr = pcmDmx_SetParam(hPcmDmx, MIN_NUMBER_OF_OUTPUT_CHANNELS, value);
      break;

    case AAC_PCM_MAX_OUTPUT_CHANNELS:
      if (value < -1 || value > (8)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      dmxErr = pcmDmx_SetParam(hPcmDmx, MAX_NUMBER_OF_OUTPUT_CHANNELS, value);

      if (dmxErr != PCMDMX_OK) {
        goto bail;
      }
      errorStatus =
          aacDecoder_drcSetParam(hDrcInfo, MAX_OUTPUT_CHANNELS, value);
      if (value > 0) {
        uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
                                        DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED,
                                        (FIXP_DBL)value);
      }
      break;

    case AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE:
      dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_DUAL_CHANNEL_MODE, value);
      break;

    case AAC_PCM_LIMITER_ENABLE:
      if (value < -2 || value > 1) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      self->limiterEnableUser = value;
      break;

    case AAC_PCM_LIMITER_ATTACK_TIME:
      if (value <= 0) { /* module function converts value to unsigned */
        return AAC_DEC_SET_PARAM_FAIL;
      }
      switch (pcmLimiter_SetAttack(hPcmTdl, value)) {
        case TDLIMIT_OK:
          break;
        case TDLIMIT_INVALID_HANDLE:
          return AAC_DEC_INVALID_HANDLE;
        case TDLIMIT_INVALID_PARAMETER:
        default:
          return AAC_DEC_SET_PARAM_FAIL;
      }
      break;

    case AAC_PCM_LIMITER_RELEAS_TIME:
      if (value <= 0) { /* module function converts value to unsigned */
        return AAC_DEC_SET_PARAM_FAIL;
      }
      switch (pcmLimiter_SetRelease(hPcmTdl, value)) {
        case TDLIMIT_OK:
          break;
        case TDLIMIT_INVALID_HANDLE:
          return AAC_DEC_INVALID_HANDLE;
        case TDLIMIT_INVALID_PARAMETER:
        default:
          return AAC_DEC_SET_PARAM_FAIL;
      }
      break;

    case AAC_METADATA_PROFILE: {
      DMX_PROFILE_TYPE dmxProfile;
      INT mdExpiry = -1; /* in ms (-1: don't change) */

      switch ((AAC_MD_PROFILE)value) {
        case AAC_MD_PROFILE_MPEG_STANDARD:
          dmxProfile = DMX_PRFL_STANDARD;
          break;
        case AAC_MD_PROFILE_MPEG_LEGACY:
          dmxProfile = DMX_PRFL_MATRIX_MIX;
          break;
        case AAC_MD_PROFILE_MPEG_LEGACY_PRIO:
          dmxProfile = DMX_PRFL_FORCE_MATRIX_MIX;
          break;
        case AAC_MD_PROFILE_ARIB_JAPAN:
          dmxProfile = DMX_PRFL_ARIB_JAPAN;
          mdExpiry = 550; /* ms */
          break;
        default:
          return AAC_DEC_SET_PARAM_FAIL;
      }
      dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_PROFILE_SETTING, (INT)dmxProfile);
      if (dmxErr != PCMDMX_OK) {
        goto bail;
      }
      if ((self != NULL) && (mdExpiry >= 0)) {
        self->metadataExpiry = mdExpiry;
        /* Determine the corresponding number of frames and configure all
         * related modules. */
        aacDecoder_setMetadataExpiry(self, mdExpiry);
      }
    } break;

    case AAC_METADATA_EXPIRY_TIME:
      if (value < 0) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self != NULL) {
        self->metadataExpiry = value;
        /* Determine the corresponding number of frames and configure all
         * related modules. */
        aacDecoder_setMetadataExpiry(self, value);
      }
      break;

    case AAC_PCM_OUTPUT_CHANNEL_MAPPING:
      if (value < 0 || value > 1) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      /* CAUTION: The given value must be inverted to match the logic! */
      FDK_chMapDescr_setPassThrough(&self->mapDescr, !value);
      break;

    case AAC_QMF_LOWPOWER:
      if (value < -1 || value > 1) {
        return AAC_DEC_SET_PARAM_FAIL;
      }

      /**
       * Set QMF mode (might be overriden)
       *  0:HQ (complex)
       *  1:LP (partially complex)
       */
      self->qmfModeUser = (QMF_MODE)value;
      break;

    case AAC_DRC_ATTENUATION_FACTOR:
      /* DRC compression factor (where 0 is no and 127 is max compression) */
      errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value);
      break;

    case AAC_DRC_BOOST_FACTOR:
      /* DRC boost factor (where 0 is no and 127 is max boost) */
      errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value);
      break;

    case AAC_DRC_REFERENCE_LEVEL:
      if ((value >= 0) &&
          ((value < 40) || (value > 127))) /* allowed range: -10 to -31.75 dB */
        return AAC_DEC_SET_PARAM_FAIL;
      /* DRC target reference level quantized in 0.25dB steps using values
         [40..127]. Negative values switch off loudness normalisation. Negative
         values also switch off MPEG-4 DRC, while MPEG-D DRC can be separately
         switched on/off with AAC_UNIDRC_SET_EFFECT */
      errorStatus = aacDecoder_drcSetParam(hDrcInfo, TARGET_REF_LEVEL, value);
      uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
                                      DRC_DEC_LOUDNESS_NORMALIZATION_ON,
                                      (FIXP_DBL)(value >= 0));
      /* set target loudness also for MPEG-D DRC */
      self->defaultTargetLoudness = (SCHAR)value;
      break;

    case AAC_DRC_HEAVY_COMPRESSION:
      /* Don't need to overwrite cut/boost values */
      errorStatus =
          aacDecoder_drcSetParam(hDrcInfo, APPLY_HEAVY_COMPRESSION, value);
      break;

    case AAC_DRC_DEFAULT_PRESENTATION_MODE:
      /* DRC default presentation mode */
      errorStatus =
          aacDecoder_drcSetParam(hDrcInfo, DEFAULT_PRESENTATION_MODE, value);
      break;

    case AAC_DRC_ENC_TARGET_LEVEL:
      /* Encoder target level for light (i.e. not heavy) compression:
         Target reference level assumed at encoder for deriving limiting gains
       */
      errorStatus =
          aacDecoder_drcSetParam(hDrcInfo, ENCODER_TARGET_LEVEL, value);
      break;

    case AAC_UNIDRC_SET_EFFECT:
      if ((value < -1) || (value > 6)) return AAC_DEC_SET_PARAM_FAIL;
      uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_EFFECT_TYPE,
                                      (FIXP_DBL)value);
      break;
    case AAC_TPDEC_CLEAR_BUFFER:
      errTp = transportDec_SetParam(hTpDec, TPDEC_PARAM_RESET, 1);
      self->streamInfo.numLostAccessUnits = 0;
      self->streamInfo.numBadBytes = 0;
      self->streamInfo.numTotalBytes = 0;
      /* aacDecoder_SignalInterruption(self); */
      break;
    case AAC_CONCEAL_METHOD:
      /* Changing the concealment method can introduce additional bitstream
         delay. And that in turn affects sub libraries and modules which makes
         the whole thing quite complex.  So the complete changing routine is
         packed into a helper function which keeps all modules and libs in a
         consistent state even in the case an error occures. */
      errorStatus = setConcealMethod(self, value);
      if (errorStatus == AAC_DEC_OK) {
        self->concealMethodUser = (CConcealmentMethod)value;
      }
      break;

    default:
      return AAC_DEC_SET_PARAM_FAIL;
  } /* switch(param) */

bail:

  if (errorStatus == AAC_DEC_OK) {
    /* Check error code returned by DMX module library: */
    switch (dmxErr) {
      case PCMDMX_OK:
        break;
      case PCMDMX_INVALID_HANDLE:
        errorStatus = AAC_DEC_INVALID_HANDLE;
        break;
      default:
        errorStatus = AAC_DEC_SET_PARAM_FAIL;
    }
  }

  if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) {
    errorStatus = AAC_DEC_SET_PARAM_FAIL;
  }

  if (errorStatus == AAC_DEC_OK) {
    /* Check error code returned by MPEG-D DRC decoder library: */
    switch (uniDrcErr) {
      case 0:
        break;
      case -9998:
        errorStatus = AAC_DEC_INVALID_HANDLE;
        break;
      default:
        errorStatus = AAC_DEC_SET_PARAM_FAIL;
        break;
    }
  }

  return (errorStatus);
}
LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,
                                               UINT nrOfLayers) {
  AAC_DECODER_INSTANCE *aacDec = NULL;
  HANDLE_TRANSPORTDEC pIn;
  int err = 0;
  int stereoConfigIndex = -1;

  UINT nrOfLayers_min = fMin(nrOfLayers, (UINT)1);

  /* Allocate transport layer struct. */
  pIn = transportDec_Open(transportFmt, TP_FLAG_MPEG4, nrOfLayers_min);
  if (pIn == NULL) {
    return NULL;
  }

  /* Allocate AAC decoder core struct. */
  aacDec = CAacDecoder_Open(transportFmt);

  if (aacDec == NULL) {
    transportDec_Close(&pIn);
    goto bail;
  }
  aacDec->hInput = pIn;

  aacDec->nrOfLayers = nrOfLayers_min;

  /* Setup channel mapping descriptor. */
  FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0);

  /* Register Config Update callback. */
  transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback,
                                   (void *)aacDec);

  /* Register Free Memory callback. */
  transportDec_RegisterFreeMemCallback(pIn, aacDecoder_FreeMemCallback,
                                       (void *)aacDec);

  /* Register config switch control callback. */
  transportDec_RegisterCtrlCFGChangeCallback(
      pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec);

  FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN));
  /* open SBR decoder */
  if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) {
    err = -1;
    goto bail;
  }
  aacDec->qmfModeUser = NOT_DEFINED;
  transportDec_RegisterSbrCallback(aacDec->hInput, (cbSbr_t)sbrDecoder_Header,
                                   (void *)aacDec->hSbrDecoder);

  if (mpegSurroundDecoder_Open(
          (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder,
          stereoConfigIndex, &aacDec->qmfDomain)) {
    err = -1;
    goto bail;
  }
  /* Set MPEG Surround defaults */
  aacDec->mpsEnableUser = 0;
  aacDec->mpsEnableCurr = 0;
  aacDec->mpsApplicable = 0;
  aacDec->mpsOutputMode = (SCHAR)SACDEC_OUT_MODE_NORMAL;
  transportDec_RegisterSscCallback(pIn, aacDecoder_SscCallback, (void *)aacDec);

  {
    if (FDK_drcDec_Open(&(aacDec->hUniDrcDecoder), DRC_DEC_ALL) != 0) {
      err = -1;
      goto bail;
    }
  }

  transportDec_RegisterUniDrcConfigCallback(pIn, aacDecoder_UniDrcCallback,
                                            (void *)aacDec,
                                            aacDec->loudnessInfoSetPosition);
  aacDec->defaultTargetLoudness = (SCHAR)96;

  pcmDmx_Open(&aacDec->hPcmUtils);
  if (aacDec->hPcmUtils == NULL) {
    err = -1;
    goto bail;
  }

  aacDec->hLimiter =
      pcmLimiter_Create(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS,
                        (FIXP_DBL)MAXVAL_DBL, (8), 96000);
  if (NULL == aacDec->hLimiter) {
    err = -1;
    goto bail;
  }
  aacDec->limiterEnableUser = (UCHAR)-1;
  aacDec->limiterEnableCurr = 0;

  /* Assure that all modules have same delay */
  if (setConcealMethod(aacDec,
                       CConcealment_GetMethod(&aacDec->concealCommonData))) {
    err = -1;
    goto bail;
  }

bail:
  if (err == -1) {
    aacDecoder_Close(aacDec);
    aacDec = NULL;
  }
  return aacDec;
}

LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
                                               UCHAR *pBuffer[],
                                               const UINT bufferSize[],
                                               UINT *pBytesValid) {
  TRANSPORTDEC_ERROR tpErr;
  /* loop counter for layers; if not TT_MP4_RAWPACKETS used as index for only
     available layer */
  INT layer = 0;
  INT nrOfLayers = self->nrOfLayers;

  {
    for (layer = 0; layer < nrOfLayers; layer++) {
      {
        tpErr = transportDec_FillData(self->hInput, pBuffer[layer],
                                      bufferSize[layer], &pBytesValid[layer],
                                      layer);
        if (tpErr != TRANSPORTDEC_OK) {
          return AAC_DEC_UNKNOWN; /* Must be an internal error */
        }
      }
    }
  }

  return AAC_DEC_OK;
}

static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
  CAacDecoder_SignalInterruption(self);

  if (self->hSbrDecoder != NULL) {
    sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1);
  }
  if (self->mpsEnableUser) {
    mpegSurroundDecoder_SetParam(
        (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
        SACDEC_BS_INTERRUPTION, 1);
  }
}

static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi,
                                               HANDLE_FDK_BITSTREAM hBs,
                                               INT nBits,
                                               AAC_DECODER_ERROR ErrorStatus) {
  /* calculate bit difference (amount of bits moved forward) */
  nBits = nBits - (INT)FDKgetValidBits(hBs);

  /* Note: The amount of bits consumed might become negative when parsing a
     bit stream with several sub frames, and we find out at the last sub frame
     that the total frame length does not match the sum of sub frame length.
     If this happens, the transport decoder might want to rewind to the supposed
     ending of the transport frame, and this position might be before the last
     access unit beginning. */

  /* Calc bitrate. */
  if (pSi->frameSize > 0) {
    /* bitRate = nBits * sampleRate / frameSize */
    int ratio_e = 0;
    FIXP_DBL ratio_m = fDivNorm(pSi->sampleRate, pSi->frameSize, &ratio_e);
    pSi->bitRate = (INT)fMultNorm(nBits, DFRACT_BITS - 1, ratio_m, ratio_e,
                                  DFRACT_BITS - 1);
  }

  /* bit/byte counters */
  {
    INT nBytes;

    nBytes = nBits >> 3;
    pSi->numTotalBytes += nBytes;
    if (IS_OUTPUT_VALID(ErrorStatus)) {
      pSi->numTotalAccessUnits++;
    }
    if (IS_DECODE_ERROR(ErrorStatus)) {
      pSi->numBadBytes += nBytes;
      pSi->numBadAccessUnits++;
    }
  }
}

static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
  INT n;

  transportDec_GetMissingAccessUnitCount(&n, self->hInput);

  return n;
}

LINKSPEC_CPP AAC_DECODER_ERROR
aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
                       const INT timeDataSize_extern, const UINT flags) {
  AAC_DECODER_ERROR ErrorStatus;
  INT layer;
  INT nBits;
  HANDLE_FDK_BITSTREAM hBs;
  int fTpInterruption = 0; /* Transport originated interruption detection. */
  int fTpConceal = 0;      /* Transport originated concealment. */
  INT_PCM *pTimeData = NULL;
  INT timeDataSize = 0;
  UINT accessUnit = 0;
  UINT numAccessUnits = 1;
  UINT numPrerollAU = 0;
  int fEndAuNotAdjusted = 0;  /* The end of the access unit was not adjusted */
  int applyCrossfade = 1;     /* flag indicates if flushing was possible */
  FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
                                 processing */
  INT timeDataFixpPcmSize;
  PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
  INT timeDataPcmPostSize;

  if (self == NULL) {
    return AAC_DEC_INVALID_HANDLE;
  }

  pTimeData = self->pcmOutputBuffer;
  timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);

  if (flags & AACDEC_INTR) {
    self->streamInfo.numLostAccessUnits = 0;
  }
  hBs = transportDec_GetBitstream(self->hInput, 0);

  /* Get current bits position for bitrate calculation. */
  nBits = FDKgetValidBits(hBs);

  if (flags & AACDEC_CLRHIST) {
    if (self->flags[0] & AC_USAC) {
      /* 1) store AudioSpecificConfig always in AudioSpecificConfig_Parse() */
      /* 2) free memory of dynamic allocated data */
      CSAudioSpecificConfig asc;
      transportDec_GetAsc(self->hInput, 0, &asc);
      aacDecoder_FreeMemCallback(self, &asc);
      self->streamInfo.numChannels = 0;
      /* 3) restore AudioSpecificConfig */
      transportDec_OutOfBandConfig(self->hInput, asc.config,
                                   (asc.configBits + 7) >> 3, 0);
    }
  }

  if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) ||
        (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
        (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) ||
        (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND))) {
    TRANSPORTDEC_ERROR err;

    for (layer = 0; layer < self->nrOfLayers; layer++) {
      err = transportDec_ReadAccessUnit(self->hInput, layer);
      if (err != TRANSPORTDEC_OK) {
        switch (err) {
          case TRANSPORTDEC_NOT_ENOUGH_BITS:
            ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
            goto bail;
          case TRANSPORTDEC_SYNC_ERROR:
            self->streamInfo.numLostAccessUnits =
                aacDecoder_EstimateNumberOfLostFrames(self);
            fTpInterruption = 1;
            break;
          case TRANSPORTDEC_NEED_TO_RESTART:
            ErrorStatus = AAC_DEC_NEED_TO_RESTART;
            goto bail;
          case TRANSPORTDEC_CRC_ERROR:
            fTpConceal = 1;
            break;
          case TRANSPORTDEC_UNSUPPORTED_FORMAT:
            ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
            goto bail;
          default:
            ErrorStatus = AAC_DEC_UNKNOWN;
            goto bail;
        }
      }
    }
  } else {
    if (self->streamInfo.numLostAccessUnits > 0) {
      self->streamInfo.numLostAccessUnits--;
    }
  }

  self->frameOK = 1;

  UINT prerollAUOffset[AACDEC_MAX_NUM_PREROLL_AU];
  UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU];
  for (int i = 0; i < AACDEC_MAX_NUM_PREROLL_AU + 1; i++)
    self->prerollAULength[i] = 0;

  INT auStartAnchor;
  HANDLE_FDK_BITSTREAM hBsAu;

  /* Process preroll frames and current frame */
  do {
    if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
        (self->flushStatus != AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON) &&
        (accessUnit == 0) &&
        (self->hasAudioPreRoll ||
         (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) &&
        !fTpInterruption &&
        !fTpConceal /* Bit stream pointer needs to be at the beginning of a
                       (valid) AU. */
    ) {
      ErrorStatus = CAacDecoder_PreRollExtensionPayloadParse(
          self, &numPrerollAU, prerollAUOffset, prerollAULength);

      if (ErrorStatus != AAC_DEC_OK) {
        switch (ErrorStatus) {
          case AAC_DEC_NOT_ENOUGH_BITS:
            goto bail;
          case AAC_DEC_PARSE_ERROR:
            self->frameOK = 0;
            break;
          default:
            break;
        }
      }

      numAccessUnits += numPrerollAU;
    }

    hBsAu = transportDec_GetBitstream(self->hInput, 0);
    auStartAnchor = (INT)FDKgetValidBits(hBsAu);

    self->accessUnit = accessUnit;
    if (accessUnit < numPrerollAU) {
      FDKpushFor(hBsAu, prerollAUOffset[accessUnit]);
    }

    /* Signal bit stream interruption to other modules if required. */
    if (fTpInterruption || (flags & AACDEC_INTR)) {
      aacDecoder_SignalInterruption(self);
      if (!(flags & AACDEC_INTR)) {
        ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
        goto bail;
      }
    }

    /* Clearing core data will be done in CAacDecoder_DecodeFrame() below.
       Tell other modules to clear states if required. */
    if (flags & AACDEC_CLRHIST) {
      if (!(self->flags[0] & AC_USAC)) {
        sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1);
        mpegSurroundDecoder_SetParam(
            (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
            SACDEC_CLEAR_HISTORY, 1);
        if (FDK_QmfDomain_ClearPersistentMemory(&self->qmfDomain) != 0) {
          ErrorStatus = AAC_DEC_UNKNOWN;
          goto bail;
        }
      }
    }

    /* Empty bit buffer in case of flush request. */
    if (flags & AACDEC_FLUSH && !(flags & AACDEC_CONCEAL)) {
      if (!self->flushStatus) {
        transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1);
        self->streamInfo.numLostAccessUnits = 0;
        self->streamInfo.numBadBytes = 0;
        self->streamInfo.numTotalBytes = 0;
      }
    }
    /* Reset the output delay field. The modules will add their figures one
     * after another. */
    self->streamInfo.outputDelay = 0;

    if (self->limiterEnableUser == (UCHAR)-2) {
      /* Enable limiter only for RSVD60. */
      self->limiterEnableCurr = (self->flags[0] & AC_RSV603DA) ? 1 : 0;
    } else if (self->limiterEnableUser == (UCHAR)-1) {
      /* Enable limiter for all non-lowdelay AOT's. */
      self->limiterEnableCurr = (self->flags[0] & (AC_LD | AC_ELD)) ? 0 : 1;
    } else {
      /* Use limiter configuration as requested. */
      self->limiterEnableCurr = self->limiterEnableUser;
    }
    /* reset limiter gain on a per frame basis */
    self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING));

    pTimeDataFixpPcm = pTimeData;
    timeDataFixpPcmSize = timeDataSize;

    ErrorStatus = CAacDecoder_DecodeFrame(
        self,
        flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
            ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
                                                              : 0),
        pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
        self->streamInfo.aacSamplesPerFrame + 0);

    /* if flushing for USAC DASH IPF was not possible go on with decoding
     * preroll */
    if ((self->flags[0] & AC_USAC) &&
        (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
        !(flags & AACDEC_CONCEAL) && (ErrorStatus != AAC_DEC_OK)) {
      applyCrossfade = 0;
    } else /* USAC DASH IPF flushing possible begin */
    {
      if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || fTpConceal ||
            self->flushStatus) &&
          (!(IS_OUTPUT_VALID(ErrorStatus)) || !(accessUnit < numPrerollAU))) {
        TRANSPORTDEC_ERROR tpErr;
        tpErr = transportDec_EndAccessUnit(self->hInput);
        if (tpErr != TRANSPORTDEC_OK) {
          self->frameOK = 0;
        }
      } else { /* while preroll processing later possibly an error in the
                  renderer part occurrs */
        if (IS_OUTPUT_VALID(ErrorStatus)) {
          fEndAuNotAdjusted = 1;
        }
      }

      /* If the current pTimeDataFixpPcm does not contain a valid signal, there
       * nothing else we can do, so bail. */
      if (!IS_OUTPUT_VALID(ErrorStatus)) {
        goto bail;
      }

      {
        self->streamInfo.sampleRate = self->streamInfo.aacSampleRate;
        self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
      }

      self->streamInfo.numChannels = self->streamInfo.aacNumChannels;

      {
        FDK_Delay_Apply(&self->usacResidualDelay,
                        pTimeDataFixpPcm +
                            1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
                        self->streamInfo.frameSize, 0);
      }

      /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
         if decoder is unable to decode with user defined qmfMode */
      if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD))) {
        self->mpsEnableCurr =
            (self->mpsEnableUser &&
             isSupportedMpsConfig(self->streamInfo.aot,
                                  self->streamInfo.numChannels,
                                  (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0));
      }

      if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
          self->mpsEnableCurr) {
        /* if not done yet, allocate full MPEG Surround decoder instance */
        if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
                (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
            SAC_INSTANCE_NOT_FULL_AVAILABLE) {
          if (mpegSurroundDecoder_Open(
                  (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
                  &self->qmfDomain)) {
            return AAC_DEC_OUT_OF_MEMORY;
          }
        }
      }

      CAacDecoder_SyncQmfMode(self);

      if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
          self->mpsEnableCurr) {
        SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder)
                                             ? SAC_INTERFACE_QMF
                                             : SAC_INTERFACE_TIME;
        /* needs to be done before first SBR apply. */
        mpegSurroundDecoder_ConfigureQmfDomain(
            (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
            (UINT)self->streamInfo.aacSampleRate, self->streamInfo.aot);
        self->qmfDomain.globalConf.nQmfTimeSlots_requested =
            self->streamInfo.aacSamplesPerFrame /
            self->qmfDomain.globalConf.nBandsAnalysis_requested;
      }

      self->qmfDomain.globalConf.TDinput = pTimeData;

      switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
        default:
        case QMF_DOMAIN_INIT_ERROR:
          ErrorStatus = AAC_DEC_UNKNOWN;
          goto bail;
        case QMF_DOMAIN_OUT_OF_MEMORY:
          ErrorStatus = AAC_DEC_OUT_OF_MEMORY;
          goto bail;
        case QMF_DOMAIN_OK:
          break;
      }

      /* sbr decoder */

      if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) ||
          self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState >
              ConcealState_FadeIn) {
        self->frameOK = 0; /* if an error has occured do concealment in the SBR
                              decoder too */
      }

      if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) {
        SBR_ERROR sbrError = SBRDEC_OK;
        int chIdx, numCoreChannel = self->streamInfo.numChannels;

        /* set params */
        sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
                            self->sbrParams.bsDelay);
        sbrDecoder_SetParam(
            self->hSbrDecoder, SBR_FLUSH_DATA,
            (flags & AACDEC_FLUSH) |
                ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
                                                                  : 0));

        if (self->streamInfo.aot == AOT_ER_AAC_ELD) {
          /* Configure QMF */
          sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN,
                              (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0);
        }

        {
          PCMDMX_ERROR dmxErr;
          INT maxOutCh = 0;

          dmxErr = pcmDmx_GetParam(self->hPcmUtils,
                                   MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh);
          if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) {
            /* Disable PS processing if we have to create a mono output signal.
             */
            self->psPossible = 0;
          }
        }

        sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
                            (self->mpsEnableCurr) ? 2 : 0);

        INT_PCM *input;
        input = (INT_PCM *)self->workBufferCore2;
        FDKmemcpy(input, pTimeData,
                  sizeof(INT_PCM) * (self->streamInfo.numChannels) *
                      (self->streamInfo.frameSize));

        /* apply SBR processing */
        sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
                                    timeDataSize, &self->streamInfo.numChannels,
                                    &self->streamInfo.sampleRate,
                                    &self->mapDescr, self->chMapIndex,
                                    self->frameOK, &self->psPossible);

        if (sbrError == SBRDEC_OK) {
          /* Update data in streaminfo structure. Assume that the SBR upsampling
             factor is either 1, 2, 8/3 or 4. Maximum upsampling factor is 4
             (CELP+SBR or USAC 4:1 SBR) */
          self->flags[0] |= AC_SBR_PRESENT;
          if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
            if (self->streamInfo.aacSampleRate >> 2 ==
                self->streamInfo.sampleRate) {
              self->streamInfo.frameSize =
                  self->streamInfo.aacSamplesPerFrame >> 2;
              self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2;
            } else if (self->streamInfo.aacSampleRate >> 1 ==
                       self->streamInfo.sampleRate) {
              self->streamInfo.frameSize =
                  self->streamInfo.aacSamplesPerFrame >> 1;
              self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1;
            } else if (self->streamInfo.aacSampleRate << 1 ==
                       self->streamInfo.sampleRate) {
              self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
                                           << 1;
              self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1;
            } else if (self->streamInfo.aacSampleRate << 2 ==
                       self->streamInfo.sampleRate) {
              self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
                                           << 2;
              self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2;
            } else if (self->streamInfo.frameSize == 768) {
              self->streamInfo.frameSize =
                  (self->streamInfo.aacSamplesPerFrame << 3) / 3;
              self->streamInfo.outputDelay =
                  (self->streamInfo.outputDelay << 3) / 3;
            } else {
              ErrorStatus = AAC_DEC_SET_PARAM_FAIL;
              goto bail;
            }
          } else {
            self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
          }
          self->streamInfo.outputDelay +=
              sbrDecoder_GetDelay(self->hSbrDecoder);

          if (self->psPossible) {
            self->flags[0] |= AC_PS_PRESENT;
          }
          for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels;
               chIdx += 1) {
            self->channelType[chIdx] = ACT_FRONT;
            self->channelIndices[chIdx] = chIdx;
          }
        }
        if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
          ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
          goto bail;
        }
      }

      if (self->mpsEnableCurr) {
        int err, sac_interface, nChannels, frameSize;

        nChannels = self->streamInfo.numChannels;
        frameSize = self->streamInfo.frameSize;
        sac_interface = SAC_INTERFACE_TIME;

        if (self->sbrEnabled && self->hSbrDecoder)
          sac_interface = SAC_INTERFACE_QMF;
        if (self->streamInfo.aot == AOT_USAC) {
          if (self->flags[0] & AC_USAC_SCFGI3) {
            sac_interface = SAC_INTERFACE_TIME;
          }
        }
        err = mpegSurroundDecoder_SetParam(
            (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
            SACDEC_INTERFACE, sac_interface);

        if (err == 0) {
          err = mpegSurroundDecoder_Apply(
              (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
              (INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
              self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
              self->streamInfo.sampleRate, self->streamInfo.aot,
              self->channelType, self->channelIndices, &self->mapDescr);
        }

        if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
          ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
          goto bail;
        }
        if (err == 0) {
          /* Update output parameter */
          self->streamInfo.numChannels = nChannels;
          self->streamInfo.frameSize = frameSize;
          self->streamInfo.outputDelay += mpegSurroundDecoder_GetDelay(
              (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
          /* Save current parameter for possible concealment of next frame */
          self->mpsOutChannelsLast = nChannels;
          self->mpsFrameSizeLast = frameSize;
        } else if ((self->mpsOutChannelsLast > 0) &&
                   (self->mpsFrameSizeLast > 0)) {
          /* Restore parameters of last frame ... */
          self->streamInfo.numChannels = self->mpsOutChannelsLast;
          self->streamInfo.frameSize = self->mpsFrameSizeLast;
          /* ... and clear output buffer so that potentially corrupted data does
           * not reach the framework. */
          FDKmemclear(pTimeData, self->mpsOutChannelsLast *
                                     self->mpsFrameSizeLast * sizeof(INT_PCM));
          /* Additionally proclaim that this frame had errors during decoding.
           */
          ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
        } else {
          ErrorStatus = AAC_DEC_UNKNOWN; /* no output */
        }
      }

      /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */

      if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) {
        SBR_ERROR sbrError = SBRDEC_OK;

        /* set params */
        sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
                            self->sbrParams.bsDelay);

        sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);

        /* apply SBR processing */
        sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
                                    timeDataSize, &self->streamInfo.numChannels,
                                    &self->streamInfo.sampleRate,
                                    &self->mapDescr, self->chMapIndex,
                                    self->frameOK, &self->psPossible);

        if (sbrError == SBRDEC_OK) {
          /* Update data in streaminfo structure. Assume that the SBR upsampling
           * factor is either 1,2 or 4 */
          self->flags[0] |= AC_SBR_PRESENT;
          if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
            if (self->streamInfo.frameSize == 768) {
              self->streamInfo.frameSize =
                  (self->streamInfo.aacSamplesPerFrame * 8) / 3;
            } else if (self->streamInfo.aacSampleRate << 2 ==
                       self->streamInfo.sampleRate) {
              self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
                                           << 2;
            } else {
              self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
                                           << 1;
            }
          }

          self->flags[0] &= ~AC_PS_PRESENT;
        }
        if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
          ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
          goto bail;
        }
      }

      /* Use dedicated memory for PCM postprocessing */
      pTimeDataPcmPost = self->pTimeData2;
      timeDataPcmPostSize = self->timeData2Size;

      {
        const int size =
            self->streamInfo.frameSize * self->streamInfo.numChannels;
        FDK_ASSERT(timeDataPcmPostSize >= size);
        for (int i = 0; i < size; i++) {
          pTimeDataPcmPost[i] =
              (PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
        }
      }

      {
        if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) &&
            !(self->flags[0] & AC_RSV603DA)) {
          /* Apply DRC gains*/
          int ch, drcDelay = 0;
          int needsDeinterleaving = 0;
          FIXP_DBL *drcWorkBuffer = NULL;
          FIXP_DBL channelGain[(8)];
          int reverseInChannelMap[(8)];
          int reverseOutChannelMap[(8)];
          int numDrcOutChannels = FDK_drcDec_GetParam(
              self->hUniDrcDecoder, DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED);
          FDKmemclear(channelGain, sizeof(channelGain));
          for (ch = 0; ch < (8); ch++) {
            reverseInChannelMap[ch] = ch;
            reverseOutChannelMap[ch] = ch;
          }

          /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF
             domain signal before the QMF synthesis. Therefore the DRC gains
             need to be delayed by the QMF synthesis delay. */
          if (self->sbrEnabled) drcDelay = 257;
          if (self->mpsEnableCurr) drcDelay = 257;
          /* Take into account concealment delay */
          drcDelay += CConcealment_GetDelay(&self->concealCommonData) *
                      self->streamInfo.frameSize;

          for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
            UCHAR mapValue = FDK_chMapDescr_getMapValue(
                &self->mapDescr, (UCHAR)ch, self->chMapIndex);
            if (mapValue < (8)) reverseInChannelMap[mapValue] = ch;
          }
          for (ch = 0; ch < (int)numDrcOutChannels; ch++) {
            UCHAR mapValue = FDK_chMapDescr_getMapValue(
                &self->mapDescr, (UCHAR)ch, numDrcOutChannels);
            if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch;
          }

          /* The output of SBR and MPS is interleaved. Deinterleaving may be
           * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved
           * audio only. */
          if ((self->streamInfo.numChannels > 1) &&
              (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
            /* interleaving/deinterleaving is performed on upper part of
             * pTimeDataPcmPost. Check if this buffer is large enough. */
            if (timeDataPcmPostSize <
                (INT)(2 * self->streamInfo.numChannels *
                      self->streamInfo.frameSize * sizeof(PCM_DEC))) {
              ErrorStatus = AAC_DEC_UNKNOWN;
              goto bail;
            }
            needsDeinterleaving = 1;
            drcWorkBuffer =
                (FIXP_DBL *)pTimeDataPcmPost +
                self->streamInfo.numChannels * self->streamInfo.frameSize;
            FDK_deinterleave(
                pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
                self->streamInfo.frameSize, self->streamInfo.frameSize);
          } else {
            drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
          }

          /* prepare Loudness Normalisation gain */
          FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_TARGET_LOUDNESS,
                              (INT)-self->defaultTargetLoudness *
                                  FL2FXCONST_DBL(1.0f / (float)(1 << 9)));
          FDK_drcDec_SetChannelGains(self->hUniDrcDecoder,
                                     self->streamInfo.numChannels,
                                     self->streamInfo.frameSize, channelGain,
                                     drcWorkBuffer, self->streamInfo.frameSize);
          FDK_drcDec_Preprocess(self->hUniDrcDecoder);

          /* apply DRC1 gain sequence */
          for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
            FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1,
                                   ch, reverseInChannelMap[ch] - ch, 1,
                                   drcWorkBuffer, self->streamInfo.frameSize);
          }
          /* apply downmix */
          FDK_drcDec_ApplyDownmix(
              self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap,
              drcWorkBuffer,
              &self->streamInfo.numChannels); /* self->streamInfo.numChannels
                                                 may change here */
          /* apply DRC2/3 gain sequence */
          for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
            FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay,
                                   DRC_DEC_DRC2_DRC3, ch,
                                   reverseOutChannelMap[ch] - ch, 1,
                                   drcWorkBuffer, self->streamInfo.frameSize);
          }

          if (needsDeinterleaving) {
            FDK_interleave(
                drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
                self->streamInfo.frameSize, self->streamInfo.frameSize);
          }
        }
      }

      if (self->streamInfo.extAot != AOT_AAC_SLS) {
        INT pcmLimiterScale = 0;
        PCMDMX_ERROR dmxErr = PCMDMX_OK;
        if (flags & (AACDEC_INTR)) {
          /* delete data from the past (e.g. mixdown coeficients) */
          pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
        }
        if (flags & (AACDEC_CLRHIST)) {
          if (!(self->flags[0] & AC_USAC)) {
            /* delete data from the past (e.g. mixdown coeficients) */
            pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
          }
        }

        INT interleaved = 0;
        interleaved |= (self->sbrEnabled) ? 1 : 0;
        interleaved |= (self->mpsEnableCurr) ? 1 : 0;

        /* do PCM post processing */
        dmxErr = pcmDmx_ApplyFrame(
            self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
            self->streamInfo.frameSize, &self->streamInfo.numChannels,
            interleaved, self->channelType, self->channelIndices,
            &self->mapDescr,
            (self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
        if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
          ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
          goto bail;
        }
        if ((ErrorStatus == AAC_DEC_OK) && (dmxErr == PCMDMX_INVALID_MODE)) {
          /* Announce the framework that the current combination of channel
           * configuration and downmix settings are not know to produce a
           * predictable behavior and thus maybe produce strange output. */
          ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
        }

        if (flags & AACDEC_CLRHIST) {
          if (!(self->flags[0] & AC_USAC)) {
            /* Delete the delayed signal. */
            pcmLimiter_Reset(self->hLimiter);
          }
        }

        if (self->limiterEnableCurr) {
          /* use workBufferCore2 buffer for interleaving */
          PCM_LIM *pInterleaveBuffer;
          int blockLength = self->streamInfo.frameSize;

          /* Set actual signal parameters */
          pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
          pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
          pcmLimiterScale += PCM_OUT_HEADROOM;

          if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
              (self->mpsEnableCurr)) {
            pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
          } else {
            pInterleaveBuffer = (PCM_LIM *)pTimeData;
            /* applyLimiter requests for interleaved data */
            /* Interleave ouput buffer */
            FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
                           self->streamInfo.numChannels, blockLength,
                           self->streamInfo.frameSize);
          }

          pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
                           self->extGain, &pcmLimiterScale, 1,
                           self->extGainDelay, self->streamInfo.frameSize);

          {
            /* Announce the additional limiter output delay */
            self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
          }
        } else {
          /* If numChannels = 1 we do not need interleaving. The same applies if
          SBR or MPS are used, since their output is interleaved already
          (resampled or not) */
          if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
              (self->mpsEnableCurr)) {
            scaleValuesSaturate(
                pTimeData, pTimeDataPcmPost,
                self->streamInfo.frameSize * self->streamInfo.numChannels,
                PCM_OUT_HEADROOM);

          } else {
            scaleValuesSaturate(
                (INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
                self->streamInfo.frameSize * self->streamInfo.numChannels,
                PCM_OUT_HEADROOM);
            /* Interleave ouput buffer */
            FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
                           self->streamInfo.numChannels,
                           self->streamInfo.frameSize,
                           self->streamInfo.frameSize);
          }
        }
      } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/

      if (self->flags[0] & AC_USAC) {
        if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
            !(flags & AACDEC_CONCEAL)) {
          CAacDecoder_PrepareCrossFade(pTimeData, self->pTimeDataFlush,
                                       self->streamInfo.numChannels,
                                       self->streamInfo.frameSize, 1);
        }

        /* prepare crossfade buffer for fade in */
        if (!applyCrossfade && self->applyCrossfade &&
            !(flags & AACDEC_CONCEAL)) {
          for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
            for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
              self->pTimeDataFlush[ch][i] = 0;
            }
          }
          applyCrossfade = 1;
        }

        if (applyCrossfade && self->applyCrossfade &&
            !(accessUnit < numPrerollAU) &&
            (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
          CAacDecoder_ApplyCrossFade(pTimeData, self->pTimeDataFlush,
                                     self->streamInfo.numChannels,
                                     self->streamInfo.frameSize, 1);
          self->applyCrossfade = 0;
        }
      }

      /* Signal interruption to take effect in next frame. */
      if ((flags & AACDEC_FLUSH || self->flushStatus) &&
          !(flags & AACDEC_CONCEAL)) {
        aacDecoder_SignalInterruption(self);
      }

      /* Update externally visible copy of flags */
      self->streamInfo.flags = self->flags[0];

    } /* USAC DASH IPF flushing possible end */
    if (accessUnit < numPrerollAU) {
      FDKpushBack(hBsAu, auStartAnchor - FDKgetValidBits(hBsAu));
    } else {
      if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
          (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
          (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
        self->buildUpCnt--;

        if (self->buildUpCnt < 0) {
          self->buildUpStatus = 0;
        }
      }

      if (self->flags[0] & AC_USAC) {
        if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
            !(flags & AACDEC_CONCEAL)) {
          self->streamInfo.frameSize = 0;
        }
      }
    }

    if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
      accessUnit++;
    }
  } while ((accessUnit < numAccessUnits) ||
           ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
            !(flags & AACDEC_CONCEAL)));

bail:

  /* error in renderer part occurred, ErrorStatus was set to invalid output */
  if (fEndAuNotAdjusted && !IS_OUTPUT_VALID(ErrorStatus) &&
      (accessUnit < numPrerollAU)) {
    transportDec_EndAccessUnit(self->hInput);
  }

  /* Update Statistics */
  aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits,
                                     ErrorStatus);
  if (((self->streamInfo.numChannels <= 0) ||
       (self->streamInfo.frameSize <= 0) ||
       (self->streamInfo.sampleRate <= 0)) &&
      IS_OUTPUT_VALID(ErrorStatus)) {
    /* Ensure consistency of IS_OUTPUT_VALID() macro. */
    ErrorStatus = AAC_DEC_UNKNOWN;
  }

  /* Check whether external output buffer is large enough. */
  if (timeDataSize_extern <
      self->streamInfo.numChannels * self->streamInfo.frameSize) {
    ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
  }

  /* Update external output buffer. */
  if (IS_OUTPUT_VALID(ErrorStatus)) {
    FDKmemcpy(pTimeData_extern, pTimeData,
              self->streamInfo.numChannels * self->streamInfo.frameSize *
                  sizeof(*pTimeData));
  } else {
    FDKmemclear(pTimeData_extern,
                timeDataSize_extern * sizeof(*pTimeData_extern));
  }

  return ErrorStatus;
}

LINKSPEC_CPP void aacDecoder_Close(HANDLE_AACDECODER self) {
  if (self == NULL) return;

  if (self->hLimiter != NULL) {
    pcmLimiter_Destroy(self->hLimiter);
  }

  if (self->hPcmUtils != NULL) {
    pcmDmx_Close(&self->hPcmUtils);
  }

  FDK_drcDec_Close(&self->hUniDrcDecoder);

  if (self->pMpegSurroundDecoder != NULL) {
    mpegSurroundDecoder_Close(
        (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
  }

  if (self->hSbrDecoder != NULL) {
    sbrDecoder_Close(&self->hSbrDecoder);
  }

  if (self->hInput != NULL) {
    transportDec_Close(&self->hInput);
  }

  CAacDecoder_Close(self);
}

LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
  return CAacDecoder_GetStreamInfo(self);
}

LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) {
  int i;

  if (info == NULL) {
    return -1;
  }

  sbrDecoder_GetLibInfo(info);
  mpegSurroundDecoder_GetLibInfo(info);
  transportDec_GetLibInfo(info);
  FDK_toolsGetLibInfo(info);
  pcmDmx_GetLibInfo(info);
  pcmLimiter_GetLibInfo(info);
  FDK_drcDec_GetLibInfo(info);

  /* search for next free tab */
  for (i = 0; i < FDK_MODULE_LAST; i++) {
    if (info[i].module_id == FDK_NONE) break;
  }
  if (i == FDK_MODULE_LAST) {
    return -1;
  }
  info += i;

  info->module_id = FDK_AACDEC;
  /* build own library info */
  info->version =
      LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2);
  LIB_VERSION_STRING(info);
  info->build_date = AACDECODER_LIB_BUILD_DATE;
  info->build_time = AACDECODER_LIB_BUILD_TIME;
  info->title = AACDECODER_LIB_TITLE;

  /* Set flags */
  info->flags = 0 | CAPF_AAC_LC | CAPF_ER_AAC_LC | CAPF_ER_AAC_SCAL |
                CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC | CAPF_ER_AAC_LD |
                CAPF_ER_AAC_ELD | CAPF_AAC_CONCEALMENT | CAPF_AAC_DRC |
                CAPF_AAC_MPEG4 | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 |
                CAPF_AAC_960 | CAPF_AAC_512 | CAPF_AAC_480 |
                CAPF_AAC_ELD_DOWNSCALE

                | CAPF_AAC_USAC | CAPF_ER_AAC_ELDV2 | CAPF_AAC_UNIDRC;
  /* End of flags */

  return 0;
}
