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

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

    /* 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 + elChannels) > (8) + (1)) {
      self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels;
      sbrError = SBRDEC_PARSE_ERROR;
      goto bail;
    }

    /* Save element ID for sanity checks and to have a fallback for concealment.
     */
    self->pSbrElement[elementIndex]->elementID = elementID;
    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 {
          hSbrHeader->syncState = SBR_NOT_INITIALIZED;
          hSbrHeader->status = HEADER_ERROR;
        }
      }
    }
  }
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);
}
