/* -----------------------------------------------------------------------------
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
----------------------------------------------------------------------------- */

/**************************** SBR decoder library ******************************

   Author(s):

   Description:

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

/*!
  \file
  \brief  SBR decoder frontend
  This module provides a frontend to the SBR decoder. The function openSBR() is
  called for initialization. The function sbrDecoder_Apply() is called for each
  frame. sbr_Apply() will call the required functions to decode the raw SBR data
  (provided by env_extr.cpp), to decode the envelope data and noise floor levels
  [decodeSbrData()], and to finally apply SBR to the current frame [sbr_dec()].

  \sa sbrDecoder_Apply(), \ref documentationOverview
*/

/*!
  \page documentationOverview Overview of important information resources and
  source code documentation

  As part of this documentation you can find more extensive descriptions about
  key concepts and algorithms at the following locations:

  <h2>Programming</h2>

  \li Buffer management: sbrDecoder_Apply() and sbr_dec()
  \li Internal scale factors to maximize SNR on fixed point processors:
  #QMF_SCALE_FACTOR \li Special mantissa-exponent format: Created in
  requantizeEnvelopeData() and used in calculateSbrEnvelope()

  <h2>Algorithmic details</h2>
  \li About the SBR data format: \ref SBR_HEADER_ELEMENT and \ref
  SBR_STANDARD_ELEMENT \li Details about the bitstream decoder: env_extr.cpp \li
  Details about the QMF filterbank and the provided polyphase implementation:
  qmf_dec.cpp \li Details about the transposer: lpp_tran.cpp \li Details about
  the envelope adjuster: env_calc.cpp

*/

#include "sbrdecoder.h"

#include "FDK_bitstream.h"

#include "sbrdec_freq_sca.h"
#include "env_extr.h"
#include "sbr_dec.h"
#include "env_dec.h"
#include "sbr_crc.h"
#include "sbr_ram.h"
#include "sbr_rom.h"
#include "lpp_tran.h"
#include "transcendent.h"

#include "FDK_crc.h"

#include "sbrdec_drc.h"

#include "psbitdec.h"

/* Decoder library info */
#define SBRDECODER_LIB_VL0 3
#define SBRDECODER_LIB_VL1 0
#define SBRDECODER_LIB_VL2 0
#define SBRDECODER_LIB_TITLE "SBR Decoder"
#ifdef __ANDROID__
#define SBRDECODER_LIB_BUILD_DATE ""
#define SBRDECODER_LIB_BUILD_TIME ""
#else
#define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__
#endif

static void setFrameErrorFlag(SBR_DECODER_ELEMENT *pSbrElement, UCHAR value) {
  if (pSbrElement != NULL) {
    switch (value) {
      case FRAME_ERROR_ALLSLOTS:
        FDKmemset(pSbrElement->frameErrorFlag, FRAME_ERROR,
                  sizeof(pSbrElement->frameErrorFlag));
        break;
      default:
        pSbrElement->frameErrorFlag[pSbrElement->useFrameSlot] = value;
    }
  }
}

static UCHAR getHeaderSlot(UCHAR currentSlot, UCHAR hdrSlotUsage[(1) + 1]) {
  UINT occupied = 0;
  int s;
  UCHAR slot = hdrSlotUsage[currentSlot];

  FDK_ASSERT((1) + 1 < 32);

  for (s = 0; s < (1) + 1; s++) {
    if ((hdrSlotUsage[s] == slot) && (s != slot)) {
      occupied = 1;
      break;
    }
  }

  if (occupied) {
    occupied = 0;

    for (s = 0; s < (1) + 1; s++) {
      occupied |= 1 << hdrSlotUsage[s];
    }
    for (s = 0; s < (1) + 1; s++) {
      if (!(occupied & 0x1)) {
        slot = s;
        break;
      }
      occupied >>= 1;
    }
  }

  return slot;
}

static void copySbrHeader(HANDLE_SBR_HEADER_DATA hDst,
                          const HANDLE_SBR_HEADER_DATA hSrc) {
  /* copy the whole header memory (including pointers) */
  FDKmemcpy(hDst, hSrc, sizeof(SBR_HEADER_DATA));

  /* update pointers */
  hDst->freqBandData.freqBandTable[0] = hDst->freqBandData.freqBandTableLo;
  hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi;
}

static int compareSbrHeader(const HANDLE_SBR_HEADER_DATA hHdr1,
                            const HANDLE_SBR_HEADER_DATA hHdr2) {
  int result = 0;

  /* compare basic data */
  result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0;
  result |= (hHdr1->status != hHdr2->status) ? 1 : 0;
  result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0;
  result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0;
  result |=
      (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0;
  result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0;
  result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0;

  /* compare bitstream data */
  result |=
      FDKmemcmp(&hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS));
  result |=
      FDKmemcmp(&hHdr1->bs_dflt, &hHdr2->bs_dflt, sizeof(SBR_HEADER_DATA_BS));
  result |= FDKmemcmp(&hHdr1->bs_info, &hHdr2->bs_info,
                      sizeof(SBR_HEADER_DATA_BS_INFO));

  /* compare frequency band data */
  result |= FDKmemcmp(&hHdr1->freqBandData, &hHdr2->freqBandData,
                      (8 + MAX_NUM_LIMITERS + 1) * sizeof(UCHAR));
  result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableLo,
                      hHdr2->freqBandData.freqBandTableLo,
                      (MAX_FREQ_COEFFS / 2 + 1) * sizeof(UCHAR));
  result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableHi,
                      hHdr2->freqBandData.freqBandTableHi,
                      (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR));
  result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableNoise,
                      hHdr2->freqBandData.freqBandTableNoise,
                      (MAX_NOISE_COEFFS + 1) * sizeof(UCHAR));
  result |=
      FDKmemcmp(hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master,
                (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR));

  return result;
}

/*!
  \brief Reset SBR decoder.

  Reset should only be called if SBR has been sucessfully detected by
  an appropriate checkForPayload() function.

  \return Error code.
*/
static SBR_ERROR sbrDecoder_ResetElement(HANDLE_SBRDECODER self,
                                         int sampleRateIn, int sampleRateOut,
                                         int samplesPerFrame,
                                         const MP4_ELEMENT_ID elementID,
                                         const int elementIndex,
                                         const int overlap) {
  SBR_ERROR sbrError = SBRDEC_OK;
  HANDLE_SBR_HEADER_DATA hSbrHeader;
  UINT qmfFlags = 0;

  int i, synDownsampleFac;

  /* USAC: assuming theoretical case 8 kHz output sample rate with 4:1 SBR */
  const int sbr_min_sample_rate_in = IS_USAC(self->coreCodec) ? 2000 : 6400;

  /* Check in/out samplerates */
  if (sampleRateIn < sbr_min_sample_rate_in || sampleRateIn > (96000)) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  if (sampleRateOut > (96000)) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  /* Set QMF mode flags */
  if (self->flags & SBRDEC_LOW_POWER) qmfFlags |= QMF_FLAG_LP;

  if (self->coreCodec == AOT_ER_AAC_ELD) {
    if (self->flags & SBRDEC_LD_MPS_QMF) {
      qmfFlags |= QMF_FLAG_MPSLDFB;
    } else {
      qmfFlags |= QMF_FLAG_CLDFB;
    }
  }

  /* Set downsampling factor for synthesis filter bank */
  if (sampleRateOut == 0) {
    /* no single rate mode */
    sampleRateOut =
        sampleRateIn
        << 1; /* In case of implicit signalling, assume dual rate SBR */
  }

  if (sampleRateIn == sampleRateOut) {
    synDownsampleFac = 2;
    self->flags |= SBRDEC_DOWNSAMPLE;
  } else {
    synDownsampleFac = 1;
    self->flags &= ~SBRDEC_DOWNSAMPLE;
  }

  self->synDownsampleFac = synDownsampleFac;
  self->sampleRateOut = sampleRateOut;

  {
    for (i = 0; i < (1) + 1; i++) {
      int setDflt;
      hSbrHeader = &(self->sbrHeader[elementIndex][i]);
      setDflt = ((hSbrHeader->syncState == SBR_NOT_INITIALIZED) ||
                 (self->flags & SBRDEC_FORCE_RESET))
                    ? 1
                    : 0;

      /* init a default header such that we can at least do upsampling later */
      sbrError = initHeaderData(hSbrHeader, sampleRateIn, sampleRateOut,
                                self->downscaleFactor, samplesPerFrame,
                                self->flags, setDflt);

      /* Set synchState to UPSAMPLING in case it already is initialized */
      hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING
                                  ? UPSAMPLING
                                  : hSbrHeader->syncState;
    }
  }

  if (sbrError != SBRDEC_OK) {
    goto bail;
  }

  if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) {
    self->pQmfDomain->globalConf.flags_requested |= qmfFlags;
    self->pQmfDomain->globalConf.nBandsAnalysis_requested =
        self->sbrHeader[elementIndex][0].numberOfAnalysisBands;
    self->pQmfDomain->globalConf.nBandsSynthesis_requested =
        (synDownsampleFac == 1) ? 64 : 32; /* may be overwritten by MPS */
    self->pQmfDomain->globalConf.nBandsSynthesis_requested /=
        self->downscaleFactor;
    self->pQmfDomain->globalConf.nQmfTimeSlots_requested =
        self->sbrHeader[elementIndex][0].numberTimeSlots *
        self->sbrHeader[elementIndex][0].timeStep;
    self->pQmfDomain->globalConf.nQmfOvTimeSlots_requested = overlap;
    self->pQmfDomain->globalConf.nQmfProcBands_requested = 64; /* always 64 */
    self->pQmfDomain->globalConf.nQmfProcChannels_requested =
        1; /* may be overwritten by MPS */
  }

  /* Init SBR channels going to be assigned to a SBR element */
  {
    int ch;
    for (ch = 0; ch < self->pSbrElement[elementIndex]->nChannels; ch++) {
      int headerIndex =
          getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
                        self->pSbrElement[elementIndex]->useHeaderSlot);

      /* and create sbrDec */
      sbrError =
          createSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch],
                       &self->sbrHeader[elementIndex][headerIndex],
                       &self->pSbrElement[elementIndex]->transposerSettings,
                       synDownsampleFac, qmfFlags, self->flags, overlap, ch,
                       self->codecFrameSize);

      if (sbrError != SBRDEC_OK) {
        goto bail;
      }
    }
  }

  // FDKmemclear(sbr_OverlapBuffer, sizeof(sbr_OverlapBuffer));

  if (self->numSbrElements == 1) {
    switch (self->coreCodec) {
      case AOT_AAC_LC:
      case AOT_SBR:
      case AOT_PS:
      case AOT_ER_AAC_SCAL:
      case AOT_DRM_AAC:
      case AOT_DRM_SURROUND:
        if (CreatePsDec(&self->hParametricStereoDec, samplesPerFrame)) {
          sbrError = SBRDEC_CREATE_ERROR;
          goto bail;
        }
        break;
      default:
        break;
    }
  }

  /* Init frame delay slot handling */
  self->pSbrElement[elementIndex]->useFrameSlot = 0;
  for (i = 0; i < ((1) + 1); i++) {
    self->pSbrElement[elementIndex]->useHeaderSlot[i] = i;
  }

bail:

  return sbrError;
}

/*!
  \brief Assign QMF domain provided QMF channels to SBR channels.

  \return void
*/
static void sbrDecoder_AssignQmfChannels2SbrChannels(HANDLE_SBRDECODER self) {
  int ch, el, absCh_offset = 0;
  for (el = 0; el < self->numSbrElements; el++) {
    if (self->pSbrElement[el] != NULL) {
      for (ch = 0; ch < self->pSbrElement[el]->nChannels; ch++) {
        FDK_ASSERT(((absCh_offset + ch) < ((8) + (1))) &&
                   ((absCh_offset + ch) < ((8) + (1))));
        self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainInCh =
            &self->pQmfDomain->QmfDomainIn[absCh_offset + ch];
        self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainOutCh =
            &self->pQmfDomain->QmfDomainOut[absCh_offset + ch];
      }
      absCh_offset += self->pSbrElement[el]->nChannels;
    }
  }
}

SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf,
                          HANDLE_FDK_QMF_DOMAIN pQmfDomain) {
  HANDLE_SBRDECODER self = NULL;
  SBR_ERROR sbrError = SBRDEC_OK;
  int elIdx;

  if ((pSelf == NULL) || (pQmfDomain == NULL)) {
    return SBRDEC_INVALID_ARGUMENT;
  }

  /* Get memory for this instance */
  self = GetRam_SbrDecoder();
  if (self == NULL) {
    sbrError = SBRDEC_MEM_ALLOC_FAILED;
    goto bail;
  }

  self->pQmfDomain = pQmfDomain;

  /*
  Already zero because of calloc
  self->numSbrElements = 0;
  self->numSbrChannels = 0;
  self->codecFrameSize = 0;
  */

  self->numDelayFrames = (1); /* set to the max value by default */

  /* Initialize header sync state */
  for (elIdx = 0; elIdx < (8); elIdx += 1) {
    int i;
    for (i = 0; i < (1) + 1; i += 1) {
      self->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED;
    }
  }

  *pSelf = self;

bail:
  return sbrError;
}

/**
 * \brief determine if the given core codec AOT can be processed or not.
 * \param coreCodec core codec audio object type.
 * \return 1 if SBR can be processed, 0 if SBR cannot be processed/applied.
 */
static int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) {
  switch (coreCodec) {
    case AOT_AAC_LC:
    case AOT_SBR:
    case AOT_PS:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_AAC_ELD:
    case AOT_DRM_AAC:
    case AOT_DRM_SURROUND:
    case AOT_USAC:
      return 1;
    default:
      return 0;
  }
}

static void sbrDecoder_DestroyElement(HANDLE_SBRDECODER self,
                                      const int elementIndex) {
  if (self->pSbrElement[elementIndex] != NULL) {
    int ch;

    for (ch = 0; ch < SBRDEC_MAX_CH_PER_ELEMENT; ch++) {
      if (self->pSbrElement[elementIndex]->pSbrChannel[ch] != NULL) {
        deleteSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch]);
        FreeRam_SbrDecChannel(
            &self->pSbrElement[elementIndex]->pSbrChannel[ch]);
        self->numSbrChannels -= 1;
      }
    }
    FreeRam_SbrDecElement(&self->pSbrElement[elementIndex]);
    self->numSbrElements -= 1;
  }
}

SBR_ERROR sbrDecoder_InitElement(
    HANDLE_SBRDECODER self, 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) {
  SBR_ERROR sbrError = SBRDEC_OK;
  int chCnt = 0;
  int nSbrElementsStart;
  int nSbrChannelsStart;
  if (self == NULL) {
    return SBRDEC_INVALID_ARGUMENT;
  }

  nSbrElementsStart = self->numSbrElements;
  nSbrChannelsStart = self->numSbrChannels;

  /* Check core codec AOT */
  if (!sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  if (elementID != ID_SCE && elementID != ID_CPE && elementID != ID_LFE) {
    sbrError = SBRDEC_UNSUPPORTED_CONFIG;
    goto bail;
  }

  if (self->sampleRateIn == sampleRateIn &&
      self->codecFrameSize == samplesPerFrame && self->coreCodec == coreCodec &&
      self->pSbrElement[elementIndex] != NULL &&
      self->pSbrElement[elementIndex]->elementID == elementID &&
      !(self->flags & SBRDEC_FORCE_RESET) &&
      ((sampleRateOut == 0) ? 1 : (self->sampleRateOut == sampleRateOut)) &&
      ((harmonicSBR == 2) ? 1
                          : (self->harmonicSBR ==
                             harmonicSBR)) /* The value 2 signalizes that
                                              harmonicSBR shall be ignored in
                                              the config change detection */
  ) {
    /* Nothing to do */
    return SBRDEC_OK;
  } else {
    if (configMode & AC_CM_DET_CFG_CHANGE) {
      *configChanged = 1;
    }
  }

  /* reaching this point the SBR-decoder gets (re-)configured */

  /* The flags field is used for all elements! */
  self->flags &=
      (SBRDEC_FORCE_RESET | SBRDEC_FLUSH); /* Keep the global flags. They will
                                              be reset after decoding. */
  self->flags |= (downscaleFactor > 1) ? SBRDEC_ELD_DOWNSCALE : 0;
  self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0;
  self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0;
  self->flags |=
      (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM : 0;
  self->flags |= (coreCodec == AOT_DRM_SURROUND)
                     ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM
                     : 0;
  self->flags |= (coreCodec == AOT_USAC) ? SBRDEC_SYNTAX_USAC : 0;
  /* Robustness: Take integer division rounding into consideration. E.g. 22050
   * Hz with 4:1 SBR => 5512 Hz core sampling rate. */
  self->flags |= (sampleRateIn == sampleRateOut / 4) ? SBRDEC_QUAD_RATE : 0;
  self->flags |= (harmonicSBR == 1) ? SBRDEC_USAC_HARMONICSBR : 0;

  if (configMode & AC_CM_DET_CFG_CHANGE) {
    return SBRDEC_OK;
  }

  self->sampleRateIn = sampleRateIn;
  self->codecFrameSize = samplesPerFrame;
  self->coreCodec = coreCodec;
  self->harmonicSBR = harmonicSBR;
  self->downscaleFactor = downscaleFactor;

  /* Init SBR elements */
  {
    int elChannels, ch;

    if (self->pSbrElement[elementIndex] == NULL) {
      self->pSbrElement[elementIndex] = GetRam_SbrDecElement(elementIndex);
      if (self->pSbrElement[elementIndex] == NULL) {
        sbrError = SBRDEC_MEM_ALLOC_FAILED;
        goto bail;
      }
      self->numSbrElements++;
    } else {
      self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels;
    }

    /* Save element ID for sanity checks and to have a fallback for concealment.
     */
    self->pSbrElement[elementIndex]->elementID = elementID;

    /* Determine amount of channels for this element */
    switch (elementID) {
      case ID_NONE:
      case ID_CPE:
        elChannels = 2;
        break;
      case ID_LFE:
      case ID_SCE:
        elChannels = 1;
        break;
      default:
        elChannels = 0;
        break;
    }

    /* Handle case of Parametric Stereo */
    if (elementIndex == 0 && elementID == ID_SCE) {
      switch (coreCodec) {
        case AOT_AAC_LC:
        case AOT_SBR:
        case AOT_PS:
        case AOT_ER_AAC_SCAL:
        case AOT_DRM_AAC:
        case AOT_DRM_SURROUND:
          elChannels = 2;
          break;
        default:
          break;
      }
    }

    /* Sanity check to avoid memory leaks */
    if (elChannels < self->pSbrElement[elementIndex]->nChannels) {
      self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels;
      sbrError = SBRDEC_PARSE_ERROR;
      goto bail;
    }

    self->pSbrElement[elementIndex]->nChannels = elChannels;

    for (ch = 0; ch < elChannels; ch++) {
      if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
        self->pSbrElement[elementIndex]->pSbrChannel[ch] =
            GetRam_SbrDecChannel(chCnt);
        if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) {
          sbrError = SBRDEC_MEM_ALLOC_FAILED;
          goto bail;
        }
      }
      self->numSbrChannels++;

      sbrDecoder_drcInitChannel(&self->pSbrElement[elementIndex]
                                     ->pSbrChannel[ch]
                                     ->SbrDec.sbrDrcChannel);

      chCnt++;
    }
  }

  if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) {
    self->pQmfDomain->globalConf.nInputChannels_requested =
        self->numSbrChannels;
    self->pQmfDomain->globalConf.nOutputChannels_requested =
        fMax((INT)self->numSbrChannels,
             (INT)self->pQmfDomain->globalConf.nOutputChannels_requested);
  }

  /* Make sure each SBR channel has one QMF channel assigned even if
   * numSbrChannels or element set-up has changed. */
  sbrDecoder_AssignQmfChannels2SbrChannels(self);

  /* clear error flags for all delay slots */
  FDKmemclear(self->pSbrElement[elementIndex]->frameErrorFlag,
              ((1) + 1) * sizeof(UCHAR));

  {
    int overlap;

    if (coreCodec == AOT_ER_AAC_ELD) {
      overlap = 0;
    } else if (self->flags & SBRDEC_QUAD_RATE) {
      overlap = (3 * 4);
    } else {
      overlap = (3 * 2);
    }
    /* Initialize this instance */
    sbrError = sbrDecoder_ResetElement(self, sampleRateIn, sampleRateOut,
                                       samplesPerFrame, elementID, elementIndex,
                                       overlap);
  }

bail:
  if (sbrError != SBRDEC_OK) {
    if ((nSbrElementsStart < self->numSbrElements) ||
        (nSbrChannelsStart < self->numSbrChannels)) {
      /* Free the memory allocated for this element */
      sbrDecoder_DestroyElement(self, elementIndex);
    } else if ((elementIndex < (8)) &&
               (self->pSbrElement[elementIndex] !=
                NULL)) { /* Set error flag to trigger concealment */
      setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
    }
  }

  return sbrError;
}

/**
 * \brief Free config dependent SBR memory.
 * \param self SBR decoder instance handle
 */
SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self) {
  int i;
  int elIdx;

  if (self != NULL && *self != NULL) {
    for (i = 0; i < (8); i++) {
      sbrDecoder_DestroyElement(*self, i);
    }

    for (elIdx = 0; elIdx < (8); elIdx += 1) {
      for (i = 0; i < (1) + 1; i += 1) {
        (*self)->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED;
      }
    }
  }

  return SBRDEC_OK;
}

/**
 * \brief Apply decoded SBR header for one element.
 * \param self SBR decoder instance handle
 * \param hSbrHeader SBR header handle to be processed.
 * \param hSbrChannel pointer array to the SBR element channels corresponding to
 * the SBR header.
 * \param headerStatus header status value returned from SBR header parser.
 * \param numElementChannels amount of channels for the SBR element whos header
 * is to be processed.
 */
static SBR_ERROR sbrDecoder_HeaderUpdate(HANDLE_SBRDECODER self,
                                         HANDLE_SBR_HEADER_DATA hSbrHeader,
                                         SBR_HEADER_STATUS headerStatus,
                                         HANDLE_SBR_CHANNEL hSbrChannel[],
                                         const int numElementChannels) {
  SBR_ERROR errorStatus = SBRDEC_OK;

  /*
    change of control data, reset decoder
  */
  errorStatus = resetFreqBandTables(hSbrHeader, self->flags);

  if (errorStatus == SBRDEC_OK) {
    if (hSbrHeader->syncState == UPSAMPLING && headerStatus != HEADER_RESET) {
#if (SBRDEC_MAX_HB_FADE_FRAMES > 0)
      int ch;
      for (ch = 0; ch < numElementChannels; ch += 1) {
        hSbrChannel[ch]->SbrDec.highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES;
      }

#endif
      /* As the default header would limit the frequency range,
         lowSubband and highSubband must be patched. */
      hSbrHeader->freqBandData.lowSubband = hSbrHeader->numberOfAnalysisBands;
      hSbrHeader->freqBandData.highSubband = hSbrHeader->numberOfAnalysisBands;
    }

    /* Trigger a reset before processing this slot */
    hSbrHeader->status |= SBRDEC_HDR_STAT_RESET;
  }

  return errorStatus;
}

INT sbrDecoder_Header(HANDLE_SBRDECODER self, 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) {
  SBR_HEADER_STATUS headerStatus;
  HANDLE_SBR_HEADER_DATA hSbrHeader;
  SBR_ERROR sbrError = SBRDEC_OK;
  int headerIndex;
  UINT flagsSaved =
      0; /* flags should not be changed in AC_CM_DET_CFG_CHANGE - mode after
            parsing */

  if (self == NULL || elementIndex >= (8)) {
    return SBRDEC_UNSUPPORTED_CONFIG;
  }

  if (!sbrDecoder_isCoreCodecValid(coreCodec)) {
    return SBRDEC_UNSUPPORTED_CONFIG;
  }

  if (configMode & AC_CM_DET_CFG_CHANGE) {
    flagsSaved = self->flags; /* store */
  }

  sbrError = sbrDecoder_InitElement(
      self, sampleRateIn, sampleRateOut, samplesPerFrame, coreCodec, elementID,
      elementIndex, harmonicSBR, stereoConfigIndex, configMode, configChanged,
      downscaleFactor);

  if ((sbrError != SBRDEC_OK) || (elementID == ID_LFE)) {
    goto bail;
  }

  if (configMode & AC_CM_DET_CFG_CHANGE) {
    hSbrHeader = NULL;
  } else {
    headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
                                self->pSbrElement[elementIndex]->useHeaderSlot);

    hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]);
  }

  headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 0, configMode);

  if (coreCodec == AOT_USAC) {
    if (configMode & AC_CM_DET_CFG_CHANGE) {
      self->flags = flagsSaved; /* restore */
    }
    return sbrError;
  }

  if (configMode & AC_CM_ALLOC_MEM) {
    SBR_DECODER_ELEMENT *pSbrElement;

    pSbrElement = self->pSbrElement[elementIndex];

    /* Sanity check */
    if (pSbrElement != NULL) {
      if ((elementID == ID_CPE && pSbrElement->nChannels != 2) ||
          (elementID != ID_CPE && pSbrElement->nChannels != 1)) {
        return SBRDEC_UNSUPPORTED_CONFIG;
      }
      if (headerStatus == HEADER_RESET) {
        sbrError = sbrDecoder_HeaderUpdate(self, hSbrHeader, headerStatus,
                                           pSbrElement->pSbrChannel,
                                           pSbrElement->nChannels);

        if (sbrError == SBRDEC_OK) {
          hSbrHeader->syncState = SBR_HEADER;
          hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
        }
        /* else {
          Since we already have overwritten the old SBR header the only way out
        is UPSAMPLING! This will be prepared in the next step.
        } */
      }
    }
  }
bail:
  if (configMode & AC_CM_DET_CFG_CHANGE) {
    self->flags = flagsSaved; /* restore */
  }
  return sbrError;
}

SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param,
                              const INT value) {
  SBR_ERROR errorStatus = SBRDEC_OK;

  /* configure the subsystems */
  switch (param) {
    case SBR_SYSTEM_BITSTREAM_DELAY:
      if (value < 0 || value > (1)) {
        errorStatus = SBRDEC_SET_PARAM_FAIL;
        break;
      }
      if (self == NULL) {
        errorStatus = SBRDEC_NOT_INITIALIZED;
      } else {
        self->numDelayFrames = (UCHAR)value;
      }
      break;
    case SBR_QMF_MODE:
      if (self == NULL) {
        errorStatus = SBRDEC_NOT_INITIALIZED;
      } else {
        if (value == 1) {
          self->flags |= SBRDEC_LOW_POWER;
        } else {
          self->flags &= ~SBRDEC_LOW_POWER;
        }
      }
      break;
    case SBR_LD_QMF_TIME_ALIGN:
      if (self == NULL) {
        errorStatus = SBRDEC_NOT_INITIALIZED;
      } else {
        if (value == 1) {
          self->flags |= SBRDEC_LD_MPS_QMF;
        } else {
          self->flags &= ~SBRDEC_LD_MPS_QMF;
        }
      }
      break;
    case SBR_FLUSH_DATA:
      if (value != 0) {
        if (self == NULL) {
          errorStatus = SBRDEC_NOT_INITIALIZED;
        } else {
          self->flags |= SBRDEC_FLUSH;
        }
      }
      break;
    case SBR_CLEAR_HISTORY:
      if (value != 0) {
        if (self == NULL) {
          errorStatus = SBRDEC_NOT_INITIALIZED;
        } else {
          self->flags |= SBRDEC_FORCE_RESET;
        }
      }
      break;
    case SBR_BS_INTERRUPTION: {
      int elementIndex;

      if (self == NULL) {
        errorStatus = SBRDEC_NOT_INITIALIZED;
        break;
      }

      /* Loop over SBR elements */
      for (elementIndex = 0; elementIndex < self->numSbrElements;
           elementIndex++) {
        if (self->pSbrElement[elementIndex] != NULL) {
          HANDLE_SBR_HEADER_DATA hSbrHeader;
          int headerIndex =
              getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot,
                            self->pSbrElement[elementIndex]->useHeaderSlot);

          hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]);

          /* Set sync state UPSAMPLING for the corresponding slot.
             This switches off bitstream parsing until a new header arrives. */
          hSbrHeader->syncState = UPSAMPLING;
          hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE;
        }
      }
    } break;

    case SBR_SKIP_QMF:
      if (self == NULL) {
        errorStatus = SBRDEC_NOT_INITIALIZED;
      } else {
        if (value == 1) {
          self->flags |= SBRDEC_SKIP_QMF_ANA;
        } else {
          self->flags &= ~SBRDEC_SKIP_QMF_ANA;
        }
        if (value == 2) {
          self->flags |= SBRDEC_SKIP_QMF_SYN;
        } else {
          self->flags &= ~SBRDEC_SKIP_QMF_SYN;
        }
      }
      break;
    default:
      errorStatus = SBRDEC_SET_PARAM_FAIL;
      break;
  } /* switch(param) */

  return (errorStatus);
}

static SBRDEC_DRC_CHANNEL *sbrDecoder_drcGetChannel(
    const HANDLE_SBRDECODER self, const INT channel) {
  SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
  int elementIndex, elChanIdx = 0, numCh = 0;

  for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel);
       elementIndex++) {
    SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex];
    int c, elChannels;

    elChanIdx = 0;
    if (pSbrElement == NULL) break;

    /* Determine amount of channels for this element */
    switch (pSbrElement->elementID) {
      case ID_CPE:
        elChannels = 2;
        break;
      case ID_LFE:
      case ID_SCE:
        elChannels = 1;
        break;
      case ID_NONE:
      default:
        elChannels = 0;
        break;
    }

    /* Limit with actual allocated element channels */
    elChannels = fMin(elChannels, pSbrElement->nChannels);

    for (c = 0; (c < elChannels) && (numCh <= channel); c++) {
      if (pSbrElement->pSbrChannel[elChanIdx] != NULL) {
        numCh++;
        elChanIdx++;
      }
    }
  }
  elementIndex -= 1;
  elChanIdx -= 1;

  if (elChanIdx < 0 || elementIndex < 0) {
    return NULL;
  }

  if (self->pSbrElement[elementIndex] != NULL) {
    if (self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx] != NULL) {
      pSbrDrcChannelData = &self->pSbrElement[elementIndex]
                                ->pSbrChannel[elChanIdx]
                                ->SbrDec.sbrDrcChannel;
    }
  }

  return (pSbrDrcChannelData);
}

SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch,
                                    UINT numBands, FIXP_DBL *pNextFact_mag,
                                    INT nextFact_exp,
                                    SHORT drcInterpolationScheme,
                                    UCHAR winSequence, USHORT *pBandTop) {
  SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;
  int band, isValidData = 0;

  if (self == NULL) {
    return SBRDEC_NOT_INITIALIZED;
  }
  if (ch > (8) || pNextFact_mag == NULL) {
    return SBRDEC_SET_PARAM_FAIL;
  }

  /* Search for gain values different to 1.0f */
  for (band = 0; band < (int)numBands; band += 1) {
    if (!((pNextFact_mag[band] == FL2FXCONST_DBL(0.5)) &&
          (nextFact_exp == 1)) &&
        !((pNextFact_mag[band] == (FIXP_DBL)MAXVAL_DBL) &&
          (nextFact_exp == 0))) {
      isValidData = 1;
      break;
    }
  }

  /* Find the right SBR channel */
  pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch);

  if (pSbrDrcChannelData != NULL) {
    if (pSbrDrcChannelData->enable ||
        isValidData) { /* Activate processing only with real and valid data */
      int i;

      pSbrDrcChannelData->enable = 1;
      pSbrDrcChannelData->numBandsNext = numBands;

      pSbrDrcChannelData->winSequenceNext = winSequence;
      pSbrDrcChannelData->drcInterpolationSchemeNext = drcInterpolationScheme;
      pSbrDrcChannelData->nextFact_exp = nextFact_exp;

      for (i = 0; i < (int)numBands; i++) {
        pSbrDrcChannelData->bandTopNext[i] = pBandTop[i];
        pSbrDrcChannelData->nextFact_mag[i] = pNextFact_mag[i];
      }
    }
  }

  return SBRDEC_OK;
}

void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch) {
  SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL;

  if ((self == NULL) || (ch > (8)) || (self->numSbrElements == 0) ||
      (self->numSbrChannels == 0)) {
    return;
  }

  /* Find the right SBR channel */
  pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch);

  if (pSbrDrcChannelData != NULL) {
    sbrDecoder_drcInitChannel(pSbrDrcChannelData);
  }
}

SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs,
                           UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize,
                           int *count, int bsPayLen, int crcFlag,
                           MP4_ELEMENT_ID prevElement, int elementIndex,
                           UINT acFlags, UINT acElFlags[]) {
  SBR_DECODER_ELEMENT *hSbrElement = NULL;
  HANDLE_SBR_HEADER_DATA hSbrHeader = NULL;
  HANDLE_SBR_CHANNEL *pSbrChannel;

  SBR_FRAME_DATA *hFrameDataLeft = NULL;
  SBR_FRAME_DATA *hFrameDataRight = NULL;
  SBR_FRAME_DATA frameDataLeftCopy;
  SBR_FRAME_DATA frameDataRightCopy;

  SBR_ERROR errorStatus = SBRDEC_OK;
  SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;

  INT startPos = FDKgetValidBits(hBs);
  INT CRCLen = 0;
  HANDLE_FDK_BITSTREAM hBsOriginal = hBs;
  FDK_BITSTREAM bsBwd;

  FDK_CRCINFO crcInfo;
  INT crcReg = 0;
  USHORT drmSbrCrc = 0;
  const int fGlobalIndependencyFlag = acFlags & AC_INDEP;
  const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC;
  const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES;
  int stereo;
  int fDoDecodeSbrData = 1;

  int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0;

  if (*count <= 0) {
    setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
    return SBRDEC_OK;
  }

  /* SBR sanity checks */
  if (self == NULL) {
    errorStatus = SBRDEC_NOT_INITIALIZED;
    goto bail;
  }

  /* Reverse bits of DRM SBR payload */
  if ((self->flags & SBRDEC_SYNTAX_DRM) && *count > 0) {
    int dataBytes, dataBits;

    FDK_ASSERT(drmBsBufferSize >= (512));
    dataBits = *count;

    if (dataBits > ((512) * 8)) {
      /* do not flip more data than needed */
      dataBits = (512) * 8;
    }

    dataBytes = (dataBits + 7) >> 3;

    int j;

    if ((j = (int)FDKgetValidBits(hBs)) != 8) {
      FDKpushBiDirectional(hBs, (j - 8));
    }

    j = 0;
    for (; dataBytes > 0; dataBytes--) {
      int i;
      UCHAR tmpByte;
      UCHAR buffer = 0x00;

      tmpByte = (UCHAR)FDKreadBits(hBs, 8);
      for (i = 0; i < 4; i++) {
        int shift = 2 * i + 1;
        buffer |= (tmpByte & (0x08 >> i)) << shift;
        buffer |= (tmpByte & (0x10 << i)) >> shift;
      }
      pDrmBsBuffer[j++] = buffer;
      FDKpushBack(hBs, 16);
    }

    FDKinitBitStream(&bsBwd, pDrmBsBuffer, (512), dataBits, BS_READER);

    /* Use reversed data */
    hBs = &bsBwd;
    bsPayLen = *count;
  }

  /* Remember start position of  SBR element */
  startPos = FDKgetValidBits(hBs);

  /* SBR sanity checks */
  if (self->pSbrElement[elementIndex] == NULL) {
    errorStatus = SBRDEC_NOT_INITIALIZED;
    goto bail;
  }
  hSbrElement = self->pSbrElement[elementIndex];

  lastSlot = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot - 1
                                             : self->numDelayFrames;
  lastHdrSlot = hSbrElement->useHeaderSlot[lastSlot];
  thisHdrSlot = getHeaderSlot(
      hSbrElement->useFrameSlot,
      hSbrElement->useHeaderSlot); /* Get a free header slot not used by
                                      frames not processed yet. */

  /* Assign the free slot to store a new header if there is one. */
  hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot];

  pSbrChannel = hSbrElement->pSbrChannel;
  stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;

  hFrameDataLeft = &self->pSbrElement[elementIndex]
                        ->pSbrChannel[0]
                        ->frameData[hSbrElement->useFrameSlot];
  if (stereo) {
    hFrameDataRight = &self->pSbrElement[elementIndex]
                           ->pSbrChannel[1]
                           ->frameData[hSbrElement->useFrameSlot];
  }

  /* store frameData; new parsed frameData possibly corrupted */
  FDKmemcpy(&frameDataLeftCopy, hFrameDataLeft, sizeof(SBR_FRAME_DATA));
  if (stereo) {
    FDKmemcpy(&frameDataRightCopy, hFrameDataRight, sizeof(SBR_FRAME_DATA));
  }

  /* reset PS flag; will be set after PS was found */
  self->flags &= ~SBRDEC_PS_DECODED;

  if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) {
    /* Got a new header from extern (e.g. from an ASC) */
    headerStatus = HEADER_OK;
    hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE;
  } else if (thisHdrSlot != lastHdrSlot) {
    /* Copy the last header into this slot otherwise the
       header compare will trigger more HEADER_RESETs than needed. */
    copySbrHeader(hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot]);
  }

  /*
     Check if bit stream data is valid and matches the element context
  */
  if (((prevElement != ID_SCE) && (prevElement != ID_CPE)) ||
      prevElement != hSbrElement->elementID) {
    /* In case of LFE we also land here, since there is no LFE SBR element (do
     * upsampling only) */
    fDoDecodeSbrData = 0;
  }

  if (fDoDecodeSbrData) {
    if ((INT)FDKgetValidBits(hBs) <= 0) {
      fDoDecodeSbrData = 0;
    }
  }

  /*
     SBR CRC-check
  */
  if (fDoDecodeSbrData) {
    if (crcFlag) {
      switch (self->coreCodec) {
        case AOT_ER_AAC_ELD:
          FDKpushFor(hBs, 10);
          /* check sbrcrc later: we don't know the payload length now */
          break;
        case AOT_DRM_AAC:
        case AOT_DRM_SURROUND:
          drmSbrCrc = (USHORT)FDKreadBits(hBs, 8);
          /* Setup CRC decoder */
          FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8);
          /* Start CRC region */
          crcReg = FDKcrcStartReg(&crcInfo, hBs, 0);
          break;
        default:
          CRCLen = bsPayLen - 10; /* change: 0 => i */
          if (CRCLen < 0) {
            fDoDecodeSbrData = 0;
          } else {
            fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen);
          }
          break;
      }
    }
  } /* if (fDoDecodeSbrData) */

  /*
     Read in the header data and issue a reset if change occured
  */
  if (fDoDecodeSbrData) {
    int sbrHeaderPresent;

    if (self->flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) {
      SBR_HEADER_DATA_BS_INFO newSbrInfo;
      int sbrInfoPresent;

      if (bs_interTes) {
        self->flags |= SBRDEC_USAC_ITES;
      } else {
        self->flags &= ~SBRDEC_USAC_ITES;
      }

      if (fGlobalIndependencyFlag) {
        self->flags |= SBRDEC_USAC_INDEP;
        sbrInfoPresent = 1;
        sbrHeaderPresent = 1;
      } else {
        self->flags &= ~SBRDEC_USAC_INDEP;
        sbrInfoPresent = FDKreadBit(hBs);
        if (sbrInfoPresent) {
          sbrHeaderPresent = FDKreadBit(hBs);
        } else {
          sbrHeaderPresent = 0;
        }
      }

      if (sbrInfoPresent) {
        newSbrInfo.ampResolution = FDKreadBit(hBs);
        newSbrInfo.xover_band = FDKreadBits(hBs, 4);
        newSbrInfo.sbr_preprocessing = FDKreadBit(hBs);
        if (bs_pvc) {
          newSbrInfo.pvc_mode = FDKreadBits(hBs, 2);
          /* bs_pvc_mode: 0 -> no PVC, 1 -> PVC mode 1, 2 -> PVC mode 2, 3 ->
           * reserved */
          if (newSbrInfo.pvc_mode > 2) {
            headerStatus = HEADER_ERROR;
          }
          if (stereo && newSbrInfo.pvc_mode > 0) {
            /* bs_pvc is always transmitted but pvc_mode is set to zero in case
             * of stereo SBR. The config might be wrong but we cannot tell for
             * sure. */
            newSbrInfo.pvc_mode = 0;
          }
        } else {
          newSbrInfo.pvc_mode = 0;
        }
        if (headerStatus != HEADER_ERROR) {
          if (FDKmemcmp(&hSbrHeader->bs_info, &newSbrInfo,
                        sizeof(SBR_HEADER_DATA_BS_INFO))) {
            /* in case of ampResolution and preprocessing change no full reset
             * required    */
            /* HEADER reset would trigger HBE transposer reset which breaks
             * eSbr_3_Eaa.mp4 */
            if ((hSbrHeader->bs_info.pvc_mode != newSbrInfo.pvc_mode) ||
                (hSbrHeader->bs_info.xover_band != newSbrInfo.xover_band)) {
              headerStatus = HEADER_RESET;
            } else {
              headerStatus = HEADER_OK;
            }

            hSbrHeader->bs_info = newSbrInfo;
          } else {
            headerStatus = HEADER_OK;
          }
        }
      }
      if (headerStatus == HEADER_ERROR) {
        /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */
        hSbrHeader->syncState = UPSAMPLING;
        fDoDecodeSbrData = 0;
        sbrHeaderPresent = 0;
      }

      if (sbrHeaderPresent && fDoDecodeSbrData) {
        int useDfltHeader;

        useDfltHeader = FDKreadBit(hBs);

        if (useDfltHeader) {
          sbrHeaderPresent = 0;
          if (FDKmemcmp(&hSbrHeader->bs_data, &hSbrHeader->bs_dflt,
                        sizeof(SBR_HEADER_DATA_BS)) ||
              hSbrHeader->syncState != SBR_ACTIVE) {
            hSbrHeader->bs_data = hSbrHeader->bs_dflt;
            headerStatus = HEADER_RESET;
          }
        }
      }
    } else {
      sbrHeaderPresent = FDKreadBit(hBs);
    }

    if (sbrHeaderPresent) {
      headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 1, 0);
    }

    if (headerStatus == HEADER_RESET) {
      errorStatus = sbrDecoder_HeaderUpdate(
          self, hSbrHeader, headerStatus, pSbrChannel, hSbrElement->nChannels);

      if (errorStatus == SBRDEC_OK) {
        hSbrHeader->syncState = SBR_HEADER;
      } else {
        hSbrHeader->syncState = SBR_NOT_INITIALIZED;
        headerStatus = HEADER_ERROR;
      }
    }

    if (errorStatus != SBRDEC_OK) {
      fDoDecodeSbrData = 0;
    }
  } /* if (fDoDecodeSbrData) */

  /*
    Print debugging output only if state has changed
  */

  /* read frame data */
  if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) {
    int sbrFrameOk;
    /* read the SBR element data */
    if (!stereo && (self->hParametricStereoDec != NULL)) {
      /* update slot index for PS bitstream parsing */
      self->hParametricStereoDec->bsLastSlot =
          self->hParametricStereoDec->bsReadSlot;
      self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot;
    }
    sbrFrameOk = sbrGetChannelElement(
        hSbrHeader, hFrameDataLeft, (stereo) ? hFrameDataRight : NULL,
        &pSbrChannel[0]->prevFrameData,
        pSbrChannel[0]->SbrDec.PvcStaticData.pvc_mode_last, hBs,
        (stereo) ? NULL : self->hParametricStereoDec, self->flags,
        self->pSbrElement[elementIndex]->transposerSettings.overlap);

    if (!sbrFrameOk) {
      fDoDecodeSbrData = 0;
    } else {
      INT valBits;

      if (bsPayLen > 0) {
        valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs));
      } else {
        valBits = (INT)FDKgetValidBits(hBs);
      }

      if (crcFlag) {
        switch (self->coreCodec) {
          case AOT_ER_AAC_ELD: {
            /* late crc check for eld */
            INT payloadbits =
                (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos;
            INT crcLen = payloadbits - 10;
            FDKpushBack(hBs, payloadbits);
            fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen);
            FDKpushFor(hBs, crcLen);
          } break;
          case AOT_DRM_AAC:
          case AOT_DRM_SURROUND:
            /* End CRC region */
            FDKcrcEndReg(&crcInfo, hBs, crcReg);
            /* Check CRC */
            if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) {
              fDoDecodeSbrData = 0;
              if (headerStatus != HEADER_NOT_PRESENT) {
                headerStatus = HEADER_ERROR;
                hSbrHeader->syncState = SBR_NOT_INITIALIZED;
              }
            }
            break;
          default:
            break;
        }
      }

      /* sanity check of remaining bits */
      if (valBits < 0) {
        fDoDecodeSbrData = 0;
      } else {
        switch (self->coreCodec) {
          case AOT_SBR:
          case AOT_PS:
          case AOT_AAC_LC: {
            /* This sanity check is only meaningful with General Audio
             * bitstreams */
            int alignBits = valBits & 0x7;

            if (valBits > alignBits) {
              fDoDecodeSbrData = 0;
            }
          } break;
          default:
            /* No sanity check available */
            break;
        }
      }
    }
  } else {
    /* The returned bit count will not be the actual payload size since we did
       not parse the frame data. Return an error so that the caller can react
       respectively. */
    errorStatus = SBRDEC_PARSE_ERROR;
  }

  if (!fDoDecodeSbrData) {
    /* Set error flag for this slot to trigger concealment */
    setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR);
    /* restore old frameData for concealment */
    FDKmemcpy(hFrameDataLeft, &frameDataLeftCopy, sizeof(SBR_FRAME_DATA));
    if (stereo) {
      FDKmemcpy(hFrameDataRight, &frameDataRightCopy, sizeof(SBR_FRAME_DATA));
    }
    errorStatus = SBRDEC_PARSE_ERROR;
  } else {
    /* Everything seems to be ok so clear the error flag */
    setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_OK);
  }

  if (!stereo) {
    /* Turn coupling off explicitely to avoid access to absent right frame data
       that might occur with corrupt bitstreams. */
    hFrameDataLeft->coupling = COUPLING_OFF;
  }

bail:

  if (self != NULL) {
    if (self->flags & SBRDEC_SYNTAX_DRM) {
      hBs = hBsOriginal;
    }

    if (errorStatus != SBRDEC_NOT_INITIALIZED) {
      int useOldHdr =
          ((headerStatus == HEADER_NOT_PRESENT) ||
           (headerStatus == HEADER_ERROR) ||
           (headerStatus == HEADER_RESET && errorStatus == SBRDEC_PARSE_ERROR))
              ? 1
              : 0;

      if (!useOldHdr && (thisHdrSlot != lastHdrSlot) && (hSbrHeader != NULL)) {
        useOldHdr |=
            (compareSbrHeader(hSbrHeader,
                              &self->sbrHeader[elementIndex][lastHdrSlot]) == 0)
                ? 1
                : 0;
      }

      if (hSbrElement != NULL) {
        if (useOldHdr != 0) {
          /* Use the old header for this frame */
          hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
        } else {
          /* Use the new header for this frame */
          hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot;
        }

        /* Move frame pointer to the next slot which is up to be decoded/applied
         * next */
        hSbrElement->useFrameSlot =
            (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1);
      }
    }
  }

  *count -= startPos - (INT)FDKgetValidBits(hBs);

  return errorStatus;
}

/**
 * \brief Render one SBR element into time domain signal.
 * \param self SBR decoder handle
 * \param timeData pointer to output buffer
 * \param channelMapping pointer to UCHAR array where next 2 channel offsets are
 * stored.
 * \param elementIndex enumerating index of the SBR element to render.
 * \param numInChannels number of channels from core coder.
 * \param numOutChannels pointer to a location to return number of output
 * channels.
 * \param psPossible flag indicating if PS is possible or not.
 * \return SBRDEC_OK if successfull, else error code
 */
static SBR_ERROR sbrDecoder_DecodeElement(
    HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData,
    const int timeDataSize, const FDK_channelMapDescr *const mapDescr,
    const int mapIdx, int channelIndex, const int elementIndex,
    const int numInChannels, int *numOutChannels, const int psPossible) {
  SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex];
  HANDLE_SBR_CHANNEL *pSbrChannel =
      self->pSbrElement[elementIndex]->pSbrChannel;
  HANDLE_SBR_HEADER_DATA hSbrHeader =
      &self->sbrHeader[elementIndex]
                      [hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]];
  HANDLE_PS_DEC h_ps_d = self->hParametricStereoDec;

  /* get memory for frame data from scratch */
  SBR_FRAME_DATA *hFrameDataLeft = NULL;
  SBR_FRAME_DATA *hFrameDataRight = NULL;

  SBR_ERROR errorStatus = SBRDEC_OK;

  INT strideOut, offset0 = 255, offset0_block = 0, offset1 = 255,
                 offset1_block = 0;
  INT codecFrameSize = self->codecFrameSize;

  int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;
  int numElementChannels =
      hSbrElement
          ->nChannels; /* Number of channels of the current SBR element */

  hFrameDataLeft =
      &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
  if (stereo) {
    hFrameDataRight =
        &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
  }

  if (self->flags & SBRDEC_FLUSH) {
    if (self->numFlushedFrames > self->numDelayFrames) {
      int hdrIdx;
      /* No valid SBR payload available, hence switch to upsampling (in all
       * headers) */
      for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) {
        self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING;
      }
    } else {
      /* Move frame pointer to the next slot which is up to be decoded/applied
       * next */
      hSbrElement->useFrameSlot =
          (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1);
      /* Update header and frame data pointer because they have already been set
       */
      hSbrHeader =
          &self->sbrHeader[elementIndex]
                          [hSbrElement
                               ->useHeaderSlot[hSbrElement->useFrameSlot]];
      hFrameDataLeft =
          &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
      if (stereo) {
        hFrameDataRight =
            &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];
      }
    }
  }

  /* Update the header error flag */
  hSbrHeader->frameErrorFlag =
      hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot];

  /*
     Prepare filterbank for upsampling if no valid bit stream data is available.
   */
  if (hSbrHeader->syncState == SBR_NOT_INITIALIZED) {
    errorStatus =
        initHeaderData(hSbrHeader, self->sampleRateIn, self->sampleRateOut,
                       self->downscaleFactor, codecFrameSize, self->flags,
                       1 /* SET_DEFAULT_HDR */
        );

    if (errorStatus != SBRDEC_OK) {
      return errorStatus;
    }

    hSbrHeader->syncState = UPSAMPLING;

    errorStatus = sbrDecoder_HeaderUpdate(self, hSbrHeader, HEADER_NOT_PRESENT,
                                          pSbrChannel, hSbrElement->nChannels);

    if (errorStatus != SBRDEC_OK) {
      hSbrHeader->syncState = SBR_NOT_INITIALIZED;
      return errorStatus;
    }
  }

  /* reset */
  if (hSbrHeader->status & SBRDEC_HDR_STAT_RESET) {
    int ch;
    int applySbrProc = (hSbrHeader->syncState == SBR_ACTIVE ||
                        (hSbrHeader->frameErrorFlag == 0 &&
                         hSbrHeader->syncState == SBR_HEADER));
    for (ch = 0; ch < numElementChannels; ch++) {
      SBR_ERROR errorStatusTmp = SBRDEC_OK;

      errorStatusTmp = resetSbrDec(
          &pSbrChannel[ch]->SbrDec, hSbrHeader, &pSbrChannel[ch]->prevFrameData,
          self->synDownsampleFac, self->flags, pSbrChannel[ch]->frameData);

      if (errorStatusTmp != SBRDEC_OK) {
        hSbrHeader->syncState = UPSAMPLING;
      }
    }
    if (applySbrProc) {
      hSbrHeader->status &= ~SBRDEC_HDR_STAT_RESET;
    }
  }

  /* decoding */
  if ((hSbrHeader->syncState == SBR_ACTIVE) ||
      ((hSbrHeader->syncState == SBR_HEADER) &&
       (hSbrHeader->frameErrorFlag == 0))) {
    errorStatus = SBRDEC_OK;

    decodeSbrData(hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData,
                  (stereo) ? hFrameDataRight : NULL,
                  (stereo) ? &pSbrChannel[1]->prevFrameData : NULL);

    /* Now we have a full parameter set and can do parameter
       based concealment instead of plain upsampling. */
    hSbrHeader->syncState = SBR_ACTIVE;
  }

  if (timeDataSize <
      hSbrHeader->numberTimeSlots * hSbrHeader->timeStep *
          self->pQmfDomain->globalConf.nBandsSynthesis *
          (psPossible ? fMax(2, numInChannels) : numInChannels)) {
    return SBRDEC_OUTPUT_BUFFER_TOO_SMALL;
  }

  {
    self->flags &= ~SBRDEC_PS_DECODED;
    C_ALLOC_SCRATCH_START(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)

    /* decode PS data if available */
    if (h_ps_d != NULL && psPossible && (hSbrHeader->syncState == SBR_ACTIVE)) {
      int applyPs = 1;

      /* define which frame delay line slot to process */
      h_ps_d->processSlot = hSbrElement->useFrameSlot;

      applyPs = DecodePs(h_ps_d, hSbrHeader->frameErrorFlag, pPsScratch);
      self->flags |= (applyPs) ? SBRDEC_PS_DECODED : 0;
    }

    offset0 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex, mapIdx);
    offset0_block = offset0 * codecFrameSize;
    if (stereo || psPossible) {
      /* the value of offset1 only matters if the condition is true, however if
      it is not true channelIndex+1 may exceed the channel map resutling in an
      error, though the value of offset1 is actually meaningless. This is
      prevented here. */
      offset1 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex + 1, mapIdx);
      offset1_block = offset1 * codecFrameSize;
    }
    /* Set strides for reading and writing */
    if (psPossible)
      strideOut = (numInChannels < 2) ? 2 : numInChannels;
    else
      strideOut = numInChannels;

    /* use same buffers for left and right channel and apply PS per timeslot */
    /* Process left channel */
    sbr_dec(&pSbrChannel[0]->SbrDec, input + offset0_block, timeData + offset0,
            (self->flags & SBRDEC_PS_DECODED) ? &pSbrChannel[1]->SbrDec : NULL,
            timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft,
            &pSbrChannel[0]->prevFrameData,
            (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags,
            codecFrameSize);

    if (stereo) {
      /* Process right channel */
      sbr_dec(&pSbrChannel[1]->SbrDec, input + offset1_block,
              timeData + offset1, NULL, NULL, strideOut, hSbrHeader,
              hFrameDataRight, &pSbrChannel[1]->prevFrameData,
              (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags,
              codecFrameSize);
    }

    C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1)
  }

  if (h_ps_d != NULL) {
    /* save PS status for next run */
    h_ps_d->psDecodedPrv = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0;
  }

  if (psPossible && !(self->flags & SBRDEC_SKIP_QMF_SYN)) {
    FDK_ASSERT(strideOut > 1);
    if (!(self->flags & SBRDEC_PS_DECODED)) {
      /* A decoder which is able to decode PS has to produce a stereo output
       * even if no PS data is available. */
      /* So copy left channel to right channel. */
      int copyFrameSize =
          codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels;
      copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels;
      INT_PCM *ptr;
      INT i;
      FDK_ASSERT(strideOut == 2);

      ptr = timeData;
      for (i = copyFrameSize >> 1; i--;) {
        INT_PCM tmp; /* This temporal variable is required because some
                        compilers can't do *ptr++ = *ptr++ correctly. */
        tmp = *ptr++;
        *ptr++ = tmp;
        tmp = *ptr++;
        *ptr++ = tmp;
      }
    }
    *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */
  }

  return errorStatus;
}

SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input,
                           INT_PCM *timeData, const int timeDataSize,
                           int *numChannels, int *sampleRate,
                           const FDK_channelMapDescr *const mapDescr,
                           const int mapIdx, const int coreDecodedOk,
                           UCHAR *psDecoded) {
  SBR_ERROR errorStatus = SBRDEC_OK;

  int psPossible;
  int sbrElementNum;
  int numCoreChannels;
  int numSbrChannels = 0;

  if ((self == NULL) || (timeData == NULL) || (numChannels == NULL) ||
      (sampleRate == NULL) || (psDecoded == NULL) ||
      !FDK_chMapDescr_isValid(mapDescr)) {
    return SBRDEC_INVALID_ARGUMENT;
  }

  psPossible = *psDecoded;
  numCoreChannels = *numChannels;
  if (numCoreChannels <= 0) {
    return SBRDEC_INVALID_ARGUMENT;
  }

  if (self->numSbrElements < 1) {
    /* exit immediately to avoid access violations */
    return SBRDEC_NOT_INITIALIZED;
  }

  /* Sanity check of allocated SBR elements. */
  for (sbrElementNum = 0; sbrElementNum < self->numSbrElements;
       sbrElementNum++) {
    if (self->pSbrElement[sbrElementNum] == NULL) {
      return SBRDEC_NOT_INITIALIZED;
    }
  }

  if (self->numSbrElements != 1 || self->pSbrElement[0]->elementID != ID_SCE) {
    psPossible = 0;
  }

  /* Make sure that even if no SBR data was found/parsed *psDecoded is returned
   * 1 if psPossible was 0. */
  if (psPossible == 0) {
    self->flags &= ~SBRDEC_PS_DECODED;
  }

  /* replaces channel based reset inside sbr_dec() */
  if (((self->flags & SBRDEC_LOW_POWER) ? 1 : 0) !=
      ((self->pQmfDomain->globalConf.flags & QMF_FLAG_LP) ? 1 : 0)) {
    if (self->flags & SBRDEC_LOW_POWER) {
      self->pQmfDomain->globalConf.flags |= QMF_FLAG_LP;
      self->pQmfDomain->globalConf.flags_requested |= QMF_FLAG_LP;
    } else {
      self->pQmfDomain->globalConf.flags &= ~QMF_FLAG_LP;
      self->pQmfDomain->globalConf.flags_requested &= ~QMF_FLAG_LP;
    }
    if (FDK_QmfDomain_InitFilterBank(self->pQmfDomain, QMF_FLAG_KEEP_STATES)) {
      return SBRDEC_UNSUPPORTED_CONFIG;
    }
  }
  if (self->numSbrChannels > self->pQmfDomain->globalConf.nInputChannels) {
    return SBRDEC_UNSUPPORTED_CONFIG;
  }

  if (self->flags & SBRDEC_FLUSH) {
    /* flushing is signalized, hence increment the flush frame counter */
    self->numFlushedFrames++;
  } else {
    /* no flushing is signalized, hence reset the flush frame counter */
    self->numFlushedFrames = 0;
  }

  /* Loop over SBR elements */
  for (sbrElementNum = 0; sbrElementNum < self->numSbrElements;
       sbrElementNum++) {
    int numElementChan;

    if (psPossible &&
        self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) {
      /* Disable PS and try decoding SBR mono. */
      psPossible = 0;
    }

    numElementChan =
        (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1;

    /* If core signal is bad then force upsampling */
    if (!coreDecodedOk) {
      setFrameErrorFlag(self->pSbrElement[sbrElementNum], FRAME_ERROR_ALLSLOTS);
    }

    errorStatus = sbrDecoder_DecodeElement(
        self, input, timeData, timeDataSize, mapDescr, mapIdx, numSbrChannels,
        sbrElementNum,
        numCoreChannels, /* is correct even for USC SCI==2 case */
        &numElementChan, psPossible);

    if (errorStatus != SBRDEC_OK) {
      goto bail;
    }

    numSbrChannels += numElementChan;

    if (numSbrChannels >= numCoreChannels) {
      break;
    }
  }

  /* Update numChannels and samplerate */
  /* Do not mess with output channels in case of USAC. numSbrChannels !=
   * numChannels for stereoConfigIndex == 2 */
  if (!(self->flags & SBRDEC_SYNTAX_USAC)) {
    *numChannels = numSbrChannels;
  }
  *sampleRate = self->sampleRateOut;
  *psDecoded = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0;

  /* Clear reset and flush flag because everything seems to be done
   * successfully. */
  self->flags &= ~SBRDEC_FORCE_RESET;
  self->flags &= ~SBRDEC_FLUSH;

bail:

  return errorStatus;
}

SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *pSelf) {
  HANDLE_SBRDECODER self = *pSelf;
  int i;

  if (self != NULL) {
    if (self->hParametricStereoDec != NULL) {
      DeletePsDec(&self->hParametricStereoDec);
    }

    for (i = 0; i < (8); i++) {
      sbrDecoder_DestroyElement(self, i);
    }

    FreeRam_SbrDecoder(pSelf);
  }

  return SBRDEC_OK;
}

INT sbrDecoder_GetLibInfo(LIB_INFO *info) {
  int i;

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

  /* 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_SBRDEC;
  info->version =
      LIB_VERSION(SBRDECODER_LIB_VL0, SBRDECODER_LIB_VL1, SBRDECODER_LIB_VL2);
  LIB_VERSION_STRING(info);
  info->build_date = SBRDECODER_LIB_BUILD_DATE;
  info->build_time = SBRDECODER_LIB_BUILD_TIME;
  info->title = SBRDECODER_LIB_TITLE;

  /* Set flags */
  info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG |
                CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC |
                CAPF_SBR_ELD_DOWNSCALE | CAPF_SBR_HBEHQ;
  /* End of flags */

  return 0;
}

UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self) {
  UINT outputDelay = 0;

  if (self != NULL) {
    UINT flags = self->flags;

    /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */

    /* Are we initialized? */
    if ((self->numSbrChannels > 0) && (self->numSbrElements > 0)) {
      /* Add QMF synthesis delay */
      if ((flags & SBRDEC_ELD_GRID) && IS_LOWDELAY(self->coreCodec)) {
        /* Low delay SBR: */
        if (!(flags & SBRDEC_SKIP_QMF_SYN)) {
          outputDelay +=
              (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */
          if (flags & SBRDEC_LD_MPS_QMF) {
            outputDelay += 32;
          }
        }
      } else if (!IS_USAC(self->coreCodec)) {
        /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...)
         * branch: */
        outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962;
        if (flags & SBRDEC_SKIP_QMF_SYN) {
          outputDelay -= 257; /* QMF synthesis */
        }
      }
    }
  }

  return (outputDelay);
}
