/* -----------------------------------------------------------------------------
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_SbrCallback(
    void *handle, HANDLE_FDK_BITSTREAM hBs, const INT sampleRateIn,
    const INT sampleRateOut, const INT samplesPerFrame,
    const AUDIO_OBJECT_TYPE coreCodec, const MP4_ELEMENT_ID elementID,
    const INT elementIndex, const UCHAR harmonicSBR,
    const UCHAR stereoConfigIndex, const UCHAR configMode, UCHAR *configChanged,
    const INT downscaleFactor) {
  HANDLE_SBRDECODER self = (HANDLE_SBRDECODER)handle;

  INT errTp = sbrDecoder_Header(self, hBs, sampleRateIn, sampleRateOut,
                                samplesPerFrame, coreCodec, elementID,
                                elementIndex, harmonicSBR, stereoConfigIndex,
                                configMode, configChanged, downscaleFactor);

  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, aacDecoder_SbrCallback,
                                   (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;
}
