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

© Copyright  1995 - 2019 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 2
#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 frameSize,
                                  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, frameSize, 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;
        break;
      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);
      uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS,
                                      value * (FL2FXCONST_DBL(0.5f / 127.0f)));
      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);
      uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST,
                                      value * (FL2FXCONST_DBL(0.5f / 127.0f)));
      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_UNIDRC_ALBUM_MODE:
      uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_ALBUM_MODE,
                                      (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,
                                                      const INT timeDataSize,
                                                      const UINT flags) {
  AAC_DECODER_ERROR ErrorStatus;
  INT layer;
  INT nBits;
  INT timeData2Size;
  INT timeData3Size;
  INT timeDataHeadroom;
  HANDLE_FDK_BITSTREAM hBs;
  int fTpInterruption = 0; /* Transport originated interruption detection. */
  int fTpConceal = 0;      /* Transport originated concealment. */
  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 */
  PCM_DEC *pTimeData2;
  PCM_AAC *pTimeData3;

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

  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) && (accessUnit == 0))) {
      aacDecoder_SignalInterruption(self);
      if (!((flags & AACDEC_INTR) && (accessUnit == 0))) {
        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 DRC level normalization gain on a per frame basis */
    self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE;

    pTimeData2 = self->pTimeData2;
    timeData2Size = self->timeData2Size / sizeof(PCM_DEC);
    pTimeData3 = (PCM_AAC *)self->pTimeData2;
    timeData3Size = self->timeData2Size / sizeof(PCM_AAC);

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

    timeDataHeadroom = self->aacOutDataHeadroom;

    /* 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 pTimeData2 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,
            pTimeData2 + 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);
        if (self->qmfDomain.globalConf.nBandsAnalysis_requested > 0) {
          self->qmfDomain.globalConf.nQmfTimeSlots_requested =
              self->streamInfo.aacSamplesPerFrame /
              self->qmfDomain.globalConf.nBandsAnalysis_requested;
        } else {
          self->qmfDomain.globalConf.nQmfTimeSlots_requested = 0;
        }
      }

      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);

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

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

        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,
              (PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size,
              self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
              self->streamInfo.sampleRate, self->streamInfo.aot,
              self->channelType, self->channelIndices, &self->mapDescr,
              self->aacOutDataHeadroom, &timeDataHeadroom);
        }

        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(pTimeData3, self->mpsOutChannelsLast *
                                      self->mpsFrameSizeLast * sizeof(PCM_AAC));
          /* 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, pTimeData3, pTimeData3, timeData3Size,
            &self->streamInfo.numChannels, &self->streamInfo.sampleRate,
            &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible,
            self->aacOutDataHeadroom, &timeDataHeadroom);

        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;
        }
      }

      {
        if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) {
          for (int i = ((self->streamInfo.frameSize *
                         self->streamInfo.numChannels) -
                        1);
               i >= 0; i--) {
            pTimeData2[i] =
                (PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom);
          }
        }
      }

      {
        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;
          }

          /* Update sampleRate and frameSize. This may be necessary in case of
           * implicit SBR signaling */
          FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_SAMPLE_RATE,
                              self->streamInfo.sampleRate);
          FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_FRAME_SIZE,
                              self->streamInfo.frameSize);

          /* 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
             * pTimeData2. Check if this buffer is large enough. */
            if (timeData2Size < (INT)(2 * self->streamInfo.numChannels *
                                      self->streamInfo.frameSize)) {
              ErrorStatus = AAC_DEC_UNKNOWN;
              goto bail;
            }
            needsDeinterleaving = 1;
            drcWorkBuffer =
                (FIXP_DBL *)pTimeData2 +
                self->streamInfo.numChannels * self->streamInfo.frameSize;
            FDK_deinterleave(
                pTimeData2, drcWorkBuffer, self->streamInfo.numChannels,
                self->streamInfo.frameSize, self->streamInfo.frameSize);
          } else {
            drcWorkBuffer = pTimeData2;
          }

          /* 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, pTimeData2, self->streamInfo.numChannels,
                self->streamInfo.frameSize, self->streamInfo.frameSize);
          }
        }
      }
      if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) {
        /* return output loudness information for MPEG-D DRC */
        LONG outputLoudness =
            FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS);
        if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) {
          /* no valid MPEG-D DRC loudness value contained */
          self->streamInfo.outputLoudness = -1;
        } else {
          if (outputLoudness > 0) {
            /* positive output loudness values (very unusual) are limited to 0
             * dB */
            self->streamInfo.outputLoudness = 0;
          } else {
            self->streamInfo.outputLoudness =
                -(INT)outputLoudness >>
                22; /* negate and scale from e = 7 to e = (31-2) */
          }
        }
      } else {
        /* return output loudness information for MPEG-4 DRC */
        if (self->streamInfo.drcProgRefLev <
            0) { /* no MPEG-4 DRC loudness metadata contained */
          self->streamInfo.outputLoudness = -1;
        } else {
          if (self->defaultTargetLoudness <
              0) { /* loudness normalization is off */
            self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev;
          } else {
            self->streamInfo.outputLoudness = self->defaultTargetLoudness;
          }
        }
      }

      if (self->streamInfo.extAot != AOT_AAC_SLS) {
        INT pcmLimiterScale = 0;
        INT interleaved = 0;
        interleaved |= (self->sbrEnabled) ? 1 : 0;
        interleaved |= (self->mpsEnableCurr) ? 1 : 0;
        PCMDMX_ERROR dmxErr = PCMDMX_OK;
        if ((flags & AACDEC_INTR) && (accessUnit == 0)) {
          /* 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);
          }
        }

        /* do PCM post processing */
        dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size,
                                   self->streamInfo.frameSize,
                                   &self->streamInfo.numChannels, interleaved,
                                   self->channelType, self->channelIndices,
                                   &self->mapDescr, &pcmLimiterScale);
        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;
        }

        pcmLimiterScale += PCM_OUT_HEADROOM;

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

        /* Set applyExtGain if DRC processing is enabled and if
           progRefLevelPresent is present for the first time. Consequences: The
           headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING
           only for audio formats which support legacy DRC Level Normalization.
                         For all other audio formats the headroom of the output
           signal is set to PCM_OUT_HEADROOM. */
        if (self->hDrcInfo->enable &&
            (self->hDrcInfo->progRefLevelPresent == 1)) {
          self->hDrcInfo->applyExtGain |= 1;
        }

        /* Check whether time data buffer is large enough. */
        if (timeDataSize <
            (self->streamInfo.numChannels * self->streamInfo.frameSize)) {
          ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
          goto bail;
        }

        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);

          if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
              (self->mpsEnableCurr)) {
            pInterleaveBuffer = (PCM_LIM *)pTimeData2;
          } else {
            pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2;

            /* applyLimiter requests for interleaved data */
            /* Interleave ouput buffer */
            FDK_interleave(pTimeData2, pInterleaveBuffer,
                           self->streamInfo.numChannels, blockLength,
                           self->streamInfo.frameSize);
          }

          FIXP_DBL *pGainPerSample = NULL;

          if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
            pGainPerSample = self->workBufferCore1;

            if ((INT)GetRequiredMemWorkBufferCore1() <
                (INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) {
              ErrorStatus = AAC_DEC_UNKNOWN;
              goto bail;
            }

            pcmLimiterScale = applyDrcLevelNormalization(
                self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain,
                pGainPerSample, pcmLimiterScale, self->extGainDelay,
                self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1);
          }

          pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
                           pGainPerSample, pcmLimiterScale,
                           self->streamInfo.frameSize);

          {
            /* Announce the additional limiter output delay */
            self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
          }
        } else {
          if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) {
            pcmLimiterScale = applyDrcLevelNormalization(
                self->hDrcInfo, pTimeData2, self->extGain, NULL,
                pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize,
                self->streamInfo.numChannels,
                (interleaved || (self->streamInfo.numChannels == 1))
                    ? 1
                    : self->streamInfo.frameSize,
                0);
          }

          /* 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, pTimeData2,
                self->streamInfo.frameSize * self->streamInfo.numChannels,
                pcmLimiterScale);

          } else {
            scaleValuesSaturate(
                (INT_PCM *)self->workBufferCore2, pTimeData2,
                self->streamInfo.frameSize * self->streamInfo.numChannels,
                pcmLimiterScale);
            /* 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 - (INT)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;
  }

  if (!IS_OUTPUT_VALID(ErrorStatus)) {
    FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData));
  }

  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;
}
