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

/******************* MPEG transport format decoder library *********************

   Author(s):   Daniel Homm

   Description:

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

#include "tpdec_lib.h"
#include "tp_data.h"

#include "FDK_crc.h"

#include "common_fix.h"

/**
 * The following arrays provide the IDs of the consecutive elements for each
 * channel configuration. Every channel_configuration has to be finalized with
 * ID_NONE.
 */
static const MP4_ELEMENT_ID channel_configuration_0[] = {ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_1[] = {ID_SCE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_2[] = {ID_CPE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_3[] = {ID_SCE, ID_CPE,
                                                         ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_4[] = {ID_SCE, ID_CPE, ID_SCE,
                                                         ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_5[] = {ID_SCE, ID_CPE, ID_CPE,
                                                         ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_6[] = {ID_SCE, ID_CPE, ID_CPE,
                                                         ID_LFE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_7[] = {
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_8[] = {
    ID_NONE}; /* reserved */
static const MP4_ELEMENT_ID channel_configuration_9[] = {
    ID_NONE}; /* reserved */
static const MP4_ELEMENT_ID channel_configuration_10[] = {
    ID_NONE}; /* reserved */
static const MP4_ELEMENT_ID channel_configuration_11[] = {
    ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_12[] = {
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_13[] = {
    ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_LFE, ID_SCE,
    ID_CPE, ID_CPE, ID_SCE, ID_CPE, ID_SCE, ID_SCE, ID_CPE, ID_NONE};
static const MP4_ELEMENT_ID channel_configuration_14[] = {
    ID_SCE, ID_CPE, ID_CPE, ID_LAST, ID_CPE, ID_NONE};

static const MP4_ELEMENT_ID *channel_configuration_array[] = {
    channel_configuration_0,  channel_configuration_1,
    channel_configuration_2,  channel_configuration_3,
    channel_configuration_4,  channel_configuration_5,
    channel_configuration_6,  channel_configuration_7,
    channel_configuration_8,  channel_configuration_9,
    channel_configuration_10, channel_configuration_11,
    channel_configuration_12, channel_configuration_13,
    channel_configuration_14};

#define TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX (13)
#define SC_CHANNEL_CONFIG_TAB_SIZE (TP_USAC_MAX_CHANNEL_CONFIGURATION_INDEX + 1)

/* channel config structure used for sanity check */
typedef struct {
  SCHAR nCh;  /* number of channels */
  SCHAR nSCE; /* number of SCE's */
  SCHAR nCPE; /* number of CPE's */
  SCHAR nLFE; /* number of LFE's */
} SC_CHANNEL_CONFIG;

static const SC_CHANNEL_CONFIG sc_chan_config_tab[SC_CHANNEL_CONFIG_TAB_SIZE] =
    {
        /* nCh, nSCE, nCPE, nLFE,     cci */
        {0, 0, 0, 0}, /*  0 */
        {1, 1, 0, 0}, /*  1 */
        {2, 0, 1, 0}, /*  2 */
        {3, 1, 1, 0}, /*  3 */
        {4, 2, 1, 0}, /*  4 */
        {5, 1, 2, 0}, /*  5 */
        {6, 1, 2, 1}, /*  6 */
        {8, 1, 3, 1}, /*  7 */
        {2, 2, 0, 0}, /*  8 */
        {3, 1, 1, 0}, /*  9 */
        {4, 0, 2, 0}, /* 10 */
        {7, 2, 2, 1}, /* 11 */
        {8, 1, 3, 1}, /* 12 */
        {24, 6, 8, 2} /* 13 */
};

void CProgramConfig_Reset(CProgramConfig *pPce) { pPce->elCounter = 0; }

void CProgramConfig_Init(CProgramConfig *pPce) {
  FDKmemclear(pPce, sizeof(CProgramConfig));
  pPce->SamplingFrequencyIndex = 0xf;
}

int CProgramConfig_IsValid(const CProgramConfig *pPce) {
  return ((pPce->isValid) ? 1 : 0);
}

#define PCE_HEIGHT_EXT_SYNC (0xAC)

/*
 * Read the extension for height info.
 * return 0 if successfull,
 *       -1 if the CRC failed,
 *       -2 if invalid HeightInfo.
 */
static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce,
                                        HANDLE_FDK_BITSTREAM bs,
                                        int *const bytesAvailable,
                                        const UINT alignmentAnchor) {
  int err = 0;
  FDK_CRCINFO crcInfo; /* CRC state info */
  INT crcReg;
  FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
  crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
  UINT startAnchor = FDKgetValidBits(bs);

  FDK_ASSERT(pPce != NULL);
  FDK_ASSERT(bs != NULL);
  FDK_ASSERT(bytesAvailable != NULL);

  if ((startAnchor >= 24) && (*bytesAvailable >= 3) &&
      (FDKreadBits(bs, 8) == PCE_HEIGHT_EXT_SYNC)) {
    int i;

    for (i = 0; i < pPce->NumFrontChannelElements; i++) {
      if ((pPce->FrontElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
          PC_NUM_HEIGHT_LAYER) {
        err = -2; /* height information is out of the valid range */
      }
    }
    for (i = 0; i < pPce->NumSideChannelElements; i++) {
      if ((pPce->SideElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
          PC_NUM_HEIGHT_LAYER) {
        err = -2; /* height information is out of the valid range */
      }
    }
    for (i = 0; i < pPce->NumBackChannelElements; i++) {
      if ((pPce->BackElementHeightInfo[i] = (UCHAR)FDKreadBits(bs, 2)) >=
          PC_NUM_HEIGHT_LAYER) {
        err = -2; /* height information is out of the valid range */
      }
    }
    FDKbyteAlign(bs, alignmentAnchor);

    FDKcrcEndReg(&crcInfo, bs, crcReg);
    if ((USHORT)FDKreadBits(bs, 8) != FDKcrcGetCRC(&crcInfo)) {
      /* CRC failed */
      err = -1;
    }
    if (err != 0) {
      /* Reset whole height information in case an error occured during parsing.
         The return value ensures that pPce->isValid is set to 0 and implicit
         channel mapping is used. */
      FDKmemclear(pPce->FrontElementHeightInfo,
                  sizeof(pPce->FrontElementHeightInfo));
      FDKmemclear(pPce->SideElementHeightInfo,
                  sizeof(pPce->SideElementHeightInfo));
      FDKmemclear(pPce->BackElementHeightInfo,
                  sizeof(pPce->BackElementHeightInfo));
    }
  } else {
    /* No valid extension data found -> restore the initial bitbuffer state */
    FDKpushBack(bs, (INT)startAnchor - (INT)FDKgetValidBits(bs));
  }

  /* Always report the bytes read. */
  *bytesAvailable -= ((INT)startAnchor - (INT)FDKgetValidBits(bs)) >> 3;

  return (err);
}

void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs,
                         UINT alignmentAnchor) {
  int i, err = 0;
  int commentBytes;

  pPce->NumEffectiveChannels = 0;
  pPce->NumChannels = 0;
  pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4);
  pPce->Profile = (UCHAR)FDKreadBits(bs, 2);
  pPce->SamplingFrequencyIndex = (UCHAR)FDKreadBits(bs, 4);
  pPce->NumFrontChannelElements = (UCHAR)FDKreadBits(bs, 4);
  pPce->NumSideChannelElements = (UCHAR)FDKreadBits(bs, 4);
  pPce->NumBackChannelElements = (UCHAR)FDKreadBits(bs, 4);
  pPce->NumLfeChannelElements = (UCHAR)FDKreadBits(bs, 2);
  pPce->NumAssocDataElements = (UCHAR)FDKreadBits(bs, 3);
  pPce->NumValidCcElements = (UCHAR)FDKreadBits(bs, 4);

  if ((pPce->MonoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
    pPce->MonoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
  }

  if ((pPce->StereoMixdownPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
    pPce->StereoMixdownElementNumber = (UCHAR)FDKreadBits(bs, 4);
  }

  if ((pPce->MatrixMixdownIndexPresent = (UCHAR)FDKreadBits(bs, 1)) != 0) {
    pPce->MatrixMixdownIndex = (UCHAR)FDKreadBits(bs, 2);
    pPce->PseudoSurroundEnable = (UCHAR)FDKreadBits(bs, 1);
  }

  for (i = 0; i < pPce->NumFrontChannelElements; i++) {
    pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
    pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
    pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1;
  }

  for (i = 0; i < pPce->NumSideChannelElements; i++) {
    pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
    pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
    pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1;
  }

  for (i = 0; i < pPce->NumBackChannelElements; i++) {
    pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1);
    pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
    pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1;
  }

  pPce->NumEffectiveChannels = pPce->NumChannels;

  for (i = 0; i < pPce->NumLfeChannelElements; i++) {
    pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
    pPce->NumChannels += 1;
  }

  for (i = 0; i < pPce->NumAssocDataElements; i++) {
    pPce->AssocDataElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
  }

  for (i = 0; i < pPce->NumValidCcElements; i++) {
    pPce->CcElementIsIndSw[i] = (UCHAR)FDKreadBits(bs, 1);
    pPce->ValidCcElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4);
  }

  FDKbyteAlign(bs, alignmentAnchor);

  pPce->CommentFieldBytes = (UCHAR)FDKreadBits(bs, 8);
  commentBytes = pPce->CommentFieldBytes;

  /* Search for height info extension and read it if available */
  err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor);

  for (i = 0; i < commentBytes; i++) {
    UCHAR text;

    text = (UCHAR)FDKreadBits(bs, 8);

    if (i < PC_COMMENTLENGTH) {
      pPce->Comment[i] = text;
    }
  }

  pPce->isValid = (err) ? 0 : 1;
}

/*
 * Compare two program configurations.
 * Returns the result of the comparison:
 *  -1 - completely different
 *   0 - completely equal
 *   1 - different but same channel configuration
 *   2 - different channel configuration but same number of channels
 */
int CProgramConfig_Compare(const CProgramConfig *const pPce1,
                           const CProgramConfig *const pPce2) {
  int result = 0; /* Innocent until proven false. */

  if (FDKmemcmp(pPce1, pPce2, sizeof(CProgramConfig)) !=
      0) { /* Configurations are not completely equal.
              So look into details and analyse the channel configurations: */
    result = -1;

    if (pPce1->NumChannels ==
        pPce2->NumChannels) { /* Now the logic changes. We first assume to have
                                 the same channel configuration and then prove
                                 if this assumption is true. */
      result = 1;

      /* Front channels */
      if (pPce1->NumFrontChannelElements != pPce2->NumFrontChannelElements) {
        result = 2; /* different number of front channel elements */
      } else {
        int el, numCh1 = 0, numCh2 = 0;
        for (el = 0; el < pPce1->NumFrontChannelElements; el += 1) {
          if (pPce1->FrontElementHeightInfo[el] !=
              pPce2->FrontElementHeightInfo[el]) {
            result = 2; /* different height info */
            break;
          }
          numCh1 += pPce1->FrontElementIsCpe[el] ? 2 : 1;
          numCh2 += pPce2->FrontElementIsCpe[el] ? 2 : 1;
        }
        if (numCh1 != numCh2) {
          result = 2; /* different number of front channels */
        }
      }
      /* Side channels */
      if (pPce1->NumSideChannelElements != pPce2->NumSideChannelElements) {
        result = 2; /* different number of side channel elements */
      } else {
        int el, numCh1 = 0, numCh2 = 0;
        for (el = 0; el < pPce1->NumSideChannelElements; el += 1) {
          if (pPce1->SideElementHeightInfo[el] !=
              pPce2->SideElementHeightInfo[el]) {
            result = 2; /* different height info */
            break;
          }
          numCh1 += pPce1->SideElementIsCpe[el] ? 2 : 1;
          numCh2 += pPce2->SideElementIsCpe[el] ? 2 : 1;
        }
        if (numCh1 != numCh2) {
          result = 2; /* different number of side channels */
        }
      }
      /* Back channels */
      if (pPce1->NumBackChannelElements != pPce2->NumBackChannelElements) {
        result = 2; /* different number of back channel elements */
      } else {
        int el, numCh1 = 0, numCh2 = 0;
        for (el = 0; el < pPce1->NumBackChannelElements; el += 1) {
          if (pPce1->BackElementHeightInfo[el] !=
              pPce2->BackElementHeightInfo[el]) {
            result = 2; /* different height info */
            break;
          }
          numCh1 += pPce1->BackElementIsCpe[el] ? 2 : 1;
          numCh2 += pPce2->BackElementIsCpe[el] ? 2 : 1;
        }
        if (numCh1 != numCh2) {
          result = 2; /* different number of back channels */
        }
      }
      /* LFE channels */
      if (pPce1->NumLfeChannelElements != pPce2->NumLfeChannelElements) {
        result = 2; /* different number of lfe channels */
      }
      /* LFEs are always SCEs so we don't need to count the channels. */
    }
  }

  return result;
}

void CProgramConfig_GetDefault(CProgramConfig *pPce, const UINT channelConfig) {
  FDK_ASSERT(pPce != NULL);

  /* Init PCE */
  CProgramConfig_Init(pPce);
  pPce->Profile =
      1; /* Set AAC LC because it is the only supported object type. */

  switch (channelConfig) {
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    case 32: /* 7.1 side channel configuration as defined in FDK_audio.h */
      pPce->NumFrontChannelElements = 2;
      pPce->FrontElementIsCpe[0] = 0;
      pPce->FrontElementIsCpe[1] = 1;
      pPce->NumSideChannelElements = 1;
      pPce->SideElementIsCpe[0] = 1;
      pPce->NumBackChannelElements = 1;
      pPce->BackElementIsCpe[0] = 1;
      pPce->NumLfeChannelElements = 1;
      pPce->NumChannels = 8;
      pPce->NumEffectiveChannels = 7;
      pPce->isValid = 1;
      break;
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    case 12: /* 3/0/4.1ch surround back */
      pPce->BackElementIsCpe[1] = 1;
      pPce->NumChannels += 1;
      pPce->NumEffectiveChannels += 1;
    case 11: /* 3/0/3.1ch */
      pPce->NumFrontChannelElements += 2;
      pPce->FrontElementIsCpe[0] = 0;
      pPce->FrontElementIsCpe[1] = 1;
      pPce->NumBackChannelElements += 2;
      pPce->BackElementIsCpe[0] = 1;
      pPce->BackElementIsCpe[1] += 0;
      pPce->NumLfeChannelElements += 1;
      pPce->NumChannels += 7;
      pPce->NumEffectiveChannels += 6;
      pPce->isValid = 1;
      break;
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    case 14:                               /* 2/0/0-3/0/2-0.1ch front height */
      pPce->FrontElementHeightInfo[2] = 1; /* Top speaker */
    case 7:                                /* 5/0/2.1ch front */
      pPce->NumFrontChannelElements += 1;
      pPce->FrontElementIsCpe[2] = 1;
      pPce->NumChannels += 2;
      pPce->NumEffectiveChannels += 2;
    case 6: /* 3/0/2.1ch */
      pPce->NumLfeChannelElements += 1;
      pPce->NumChannels += 1;
    case 5: /* 3/0/2.0ch */
    case 4: /* 3/0/1.0ch */
      pPce->NumBackChannelElements += 1;
      pPce->BackElementIsCpe[0] = (channelConfig > 4) ? 1 : 0;
      pPce->NumChannels += (channelConfig > 4) ? 2 : 1;
      pPce->NumEffectiveChannels += (channelConfig > 4) ? 2 : 1;
    case 3: /* 3/0/0.0ch */
      pPce->NumFrontChannelElements += 1;
      pPce->FrontElementIsCpe[1] = 1;
      pPce->NumChannels += 2;
      pPce->NumEffectiveChannels += 2;
    case 1: /* 1/0/0.0ch */
      pPce->NumFrontChannelElements += 1;
      pPce->FrontElementIsCpe[0] = 0;
      pPce->NumChannels += 1;
      pPce->NumEffectiveChannels += 1;
      pPce->isValid = 1;
      break;
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    case 2: /* 2/0/0.ch */
      pPce->NumFrontChannelElements = 1;
      pPce->FrontElementIsCpe[0] = 1;
      pPce->NumChannels += 2;
      pPce->NumEffectiveChannels += 2;
      pPce->isValid = 1;
      break;
    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    default:
      pPce->isValid = 0; /* To be explicit! */
      break;
  }

  if (pPce->isValid) {
    /* Create valid element instance tags */
    int el, elTagSce = 0, elTagCpe = 0;

    for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
      pPce->FrontElementTagSelect[el] =
          (pPce->FrontElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
    }
    for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
      pPce->SideElementTagSelect[el] =
          (pPce->SideElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
    }
    for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
      pPce->BackElementTagSelect[el] =
          (pPce->BackElementIsCpe[el]) ? elTagCpe++ : elTagSce++;
    }
    elTagSce = 0;
    for (el = 0; el < pPce->NumLfeChannelElements; el += 1) {
      pPce->LfeElementTagSelect[el] = elTagSce++;
    }
  }
}

/**
 * \brief get implicit audio channel type for given channelConfig and MPEG
 * ordered channel index
 * \param channelConfig MPEG channelConfiguration from 1 upto 14
 * \param index MPEG channel order index
 * \return audio channel type.
 */
static void getImplicitAudioChannelTypeAndIndex(AUDIO_CHANNEL_TYPE *chType,
                                                UCHAR *chIndex,
                                                UINT channelConfig,
                                                UINT index) {
  if (index < 3) {
    *chType = ACT_FRONT;
    *chIndex = index;
  } else {
    switch (channelConfig) {
      case 4: /* SCE, CPE, SCE */
      case 5: /* SCE, CPE, CPE */
      case 6: /* SCE, CPE, CPE, LFE */
        switch (index) {
          case 3:
          case 4:
            *chType = ACT_BACK;
            *chIndex = index - 3;
            break;
          case 5:
            *chType = ACT_LFE;
            *chIndex = 0;
            break;
        }
        break;
      case 7: /* SCE,CPE,CPE,CPE,LFE */
        switch (index) {
          case 3:
          case 4:
            *chType = ACT_FRONT;
            *chIndex = index;
            break;
          case 5:
          case 6:
            *chType = ACT_BACK;
            *chIndex = index - 5;
            break;
          case 7:
            *chType = ACT_LFE;
            *chIndex = 0;
            break;
        }
        break;
      case 11: /* SCE,CPE,CPE,SCE,LFE */
        if (index < 6) {
          *chType = ACT_BACK;
          *chIndex = index - 3;
        } else {
          *chType = ACT_LFE;
          *chIndex = 0;
        }
        break;
      case 12: /* SCE,CPE,CPE,CPE,LFE */
        if (index < 7) {
          *chType = ACT_BACK;
          *chIndex = index - 3;
        } else {
          *chType = ACT_LFE;
          *chIndex = 0;
        }
        break;
      case 14: /* SCE,CPE,CPE,LFE,CPE */
        switch (index) {
          case 3:
          case 4:
            *chType = ACT_BACK;
            *chIndex = index - 3;
            break;
          case 5:
            *chType = ACT_LFE;
            *chIndex = 0;
            break;
          case 6:
          case 7:
            *chType = ACT_FRONT_TOP;
            *chIndex = index - 6; /* handle the top layer independently */
            break;
        }
        break;
      default:
        *chType = ACT_NONE;
        break;
    }
  }
}

int CProgramConfig_LookupElement(CProgramConfig *pPce, UINT channelConfig,
                                 const UINT tag, const UINT channelIdx,
                                 UCHAR chMapping[], AUDIO_CHANNEL_TYPE chType[],
                                 UCHAR chIndex[], const UINT chDescrLen,
                                 UCHAR *elMapping, MP4_ELEMENT_ID elList[],
                                 MP4_ELEMENT_ID elType) {
  if (channelConfig > 0) {
    /* Constant channel mapping must have
       been set during initialization. */
    if (IS_CHANNEL_ELEMENT(elType)) {
      *elMapping = pPce->elCounter;
      if (elList[pPce->elCounter] != elType &&
          !IS_USAC_CHANNEL_ELEMENT(elType)) {
        /* Not in the list */
        if ((channelConfig == 2) &&
            (elType == ID_SCE)) { /* This scenario occurs with HE-AAC v2 streams
                                     of buggy encoders. In other decoder
                                     implementations decoding of this kind of
                                     streams is desired. */
          channelConfig = 1;
        } else if ((elList[pPce->elCounter] == ID_LFE) &&
                   (elType ==
                    ID_SCE)) { /* Decode bitstreams which wrongly use ID_SCE
                                  instead of ID_LFE element type. */
          ;
        } else {
          return 0;
        }
      }
      /* Assume all front channels */
      getImplicitAudioChannelTypeAndIndex(
          &chType[channelIdx], &chIndex[channelIdx], channelConfig, channelIdx);
      if (elType == ID_CPE || elType == ID_USAC_CPE) {
        chType[channelIdx + 1] = chType[channelIdx];
        chIndex[channelIdx + 1] = chIndex[channelIdx] + 1;
      }
      pPce->elCounter++;
    }
    /* Accept all non-channel elements, too. */
    return 1;
  } else {
    if ((!pPce->isValid) || (pPce->NumChannels > chDescrLen)) {
      /* Implicit channel mapping. */
      if (IS_USAC_CHANNEL_ELEMENT(elType)) {
        *elMapping = pPce->elCounter++;
      } else if (IS_MP4_CHANNEL_ELEMENT(elType)) {
        /* Store all channel element IDs */
        elList[pPce->elCounter] = elType;
        *elMapping = pPce->elCounter++;
      }
    } else {
      /* Accept the additional channel(s), only if the tag is in the lists */
      int isCpe = 0, i;
      /* Element counter */
      int ec[PC_NUM_HEIGHT_LAYER] = {0};
      /* Channel counters */
      int cc[PC_NUM_HEIGHT_LAYER] = {0};
      int fc[PC_NUM_HEIGHT_LAYER] = {0}; /* front channel counter */
      int sc[PC_NUM_HEIGHT_LAYER] = {0}; /* side channel counter */
      int bc[PC_NUM_HEIGHT_LAYER] = {0}; /* back channel counter */
      int lc = 0;                        /* lfe channel counter */

      /* General MPEG (PCE) composition rules:
         - Over all:
             <normal height channels><top height channels><bottom height
         channels>
         - Within each height layer:
             <front channels><side channels><back channels>
         - Exception:
             The LFE channels have no height info and thus they are arranged at
         the very end of the normal height layer channels.
       */

      switch (elType) {
        case ID_CPE:
          isCpe = 1;
        case ID_SCE:
          /* search in front channels */
          for (i = 0; i < pPce->NumFrontChannelElements; i++) {
            int heightLayer = pPce->FrontElementHeightInfo[i];
            if (isCpe == pPce->FrontElementIsCpe[i] &&
                pPce->FrontElementTagSelect[i] == tag) {
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
              AUDIO_CHANNEL_TYPE aChType =
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_FRONT);
              for (h = heightLayer - 1; h >= 0; h -= 1) {
                int el;
                /* Count front channels/elements */
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
                  if (pPce->FrontElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count side channels/elements */
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
                  if (pPce->SideElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count back channels/elements */
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
                  if (pPce->BackElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                  }
                }
                if (h == 0) { /* normal height */
                  elIdx += pPce->NumLfeChannelElements;
                  chIdx += pPce->NumLfeChannelElements;
                }
              }
              chMapping[chIdx] = channelIdx;
              chType[chIdx] = aChType;
              chIndex[chIdx] = fc[heightLayer];
              if (isCpe) {
                chMapping[chIdx + 1] = channelIdx + 1;
                chType[chIdx + 1] = aChType;
                chIndex[chIdx + 1] = fc[heightLayer] + 1;
              }
              *elMapping = elIdx;
              return 1;
            }
            ec[heightLayer] += 1;
            if (pPce->FrontElementIsCpe[i]) {
              cc[heightLayer] += 2;
              fc[heightLayer] += 2;
            } else {
              cc[heightLayer] += 1;
              fc[heightLayer] += 1;
            }
          }
          /* search in side channels */
          for (i = 0; i < pPce->NumSideChannelElements; i++) {
            int heightLayer = pPce->SideElementHeightInfo[i];
            if (isCpe == pPce->SideElementIsCpe[i] &&
                pPce->SideElementTagSelect[i] == tag) {
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
              AUDIO_CHANNEL_TYPE aChType =
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_SIDE);
              for (h = heightLayer - 1; h >= 0; h -= 1) {
                int el;
                /* Count front channels/elements */
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
                  if (pPce->FrontElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count side channels/elements */
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
                  if (pPce->SideElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count back channels/elements */
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
                  if (pPce->BackElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                  }
                }
                if (h ==
                    0) { /* LFE channels belong to the normal height layer */
                  elIdx += pPce->NumLfeChannelElements;
                  chIdx += pPce->NumLfeChannelElements;
                }
              }
              chMapping[chIdx] = channelIdx;
              chType[chIdx] = aChType;
              chIndex[chIdx] = sc[heightLayer];
              if (isCpe) {
                chMapping[chIdx + 1] = channelIdx + 1;
                chType[chIdx + 1] = aChType;
                chIndex[chIdx + 1] = sc[heightLayer] + 1;
              }
              *elMapping = elIdx;
              return 1;
            }
            ec[heightLayer] += 1;
            if (pPce->SideElementIsCpe[i]) {
              cc[heightLayer] += 2;
              sc[heightLayer] += 2;
            } else {
              cc[heightLayer] += 1;
              sc[heightLayer] += 1;
            }
          }
          /* search in back channels */
          for (i = 0; i < pPce->NumBackChannelElements; i++) {
            int heightLayer = pPce->BackElementHeightInfo[i];
            if (isCpe == pPce->BackElementIsCpe[i] &&
                pPce->BackElementTagSelect[i] == tag) {
              int h, elIdx = ec[heightLayer], chIdx = cc[heightLayer];
              AUDIO_CHANNEL_TYPE aChType =
                  (AUDIO_CHANNEL_TYPE)((heightLayer << 4) | ACT_BACK);
              for (h = heightLayer - 1; h >= 0; h -= 1) {
                int el;
                /* Count front channels/elements */
                for (el = 0; el < pPce->NumFrontChannelElements; el += 1) {
                  if (pPce->FrontElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->FrontElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count side channels/elements */
                for (el = 0; el < pPce->NumSideChannelElements; el += 1) {
                  if (pPce->SideElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->SideElementIsCpe[el]) ? 2 : 1;
                  }
                }
                /* Count back channels/elements */
                for (el = 0; el < pPce->NumBackChannelElements; el += 1) {
                  if (pPce->BackElementHeightInfo[el] == h) {
                    elIdx += 1;
                    chIdx += (pPce->BackElementIsCpe[el]) ? 2 : 1;
                  }
                }
                if (h == 0) { /* normal height */
                  elIdx += pPce->NumLfeChannelElements;
                  chIdx += pPce->NumLfeChannelElements;
                }
              }
              chMapping[chIdx] = channelIdx;
              chType[chIdx] = aChType;
              chIndex[chIdx] = bc[heightLayer];
              if (isCpe) {
                chMapping[chIdx + 1] = channelIdx + 1;
                chType[chIdx + 1] = aChType;
                chIndex[chIdx + 1] = bc[heightLayer] + 1;
              }
              *elMapping = elIdx;
              return 1;
            }
            ec[heightLayer] += 1;
            if (pPce->BackElementIsCpe[i]) {
              cc[heightLayer] += 2;
              bc[heightLayer] += 2;
            } else {
              cc[heightLayer] += 1;
              bc[heightLayer] += 1;
            }
          }
          break;

        case ID_LFE: { /* Unfortunately we have to go through all normal height
                          layer elements to get the position of the LFE
                          channels. Start with counting the front
                          channels/elements at normal height */
          for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
            int heightLayer = pPce->FrontElementHeightInfo[i];
            ec[heightLayer] += 1;
            cc[heightLayer] += (pPce->FrontElementIsCpe[i]) ? 2 : 1;
          }
          /* Count side channels/elements at normal height */
          for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
            int heightLayer = pPce->SideElementHeightInfo[i];
            ec[heightLayer] += 1;
            cc[heightLayer] += (pPce->SideElementIsCpe[i]) ? 2 : 1;
          }
          /* Count back channels/elements at normal height */
          for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
            int heightLayer = pPce->BackElementHeightInfo[i];
            ec[heightLayer] += 1;
            cc[heightLayer] += (pPce->BackElementIsCpe[i]) ? 2 : 1;
          }

          /* search in lfe channels */
          for (i = 0; i < pPce->NumLfeChannelElements; i++) {
            int elIdx =
                ec[0]; /* LFE channels belong to the normal height layer */
            int chIdx = cc[0];
            if (pPce->LfeElementTagSelect[i] == tag) {
              chMapping[chIdx] = channelIdx;
              *elMapping = elIdx;
              chType[chIdx] = ACT_LFE;
              chIndex[chIdx] = lc;
              return 1;
            }
            ec[0] += 1;
            cc[0] += 1;
            lc += 1;
          }
        } break;

        /* Non audio elements */
        case ID_CCE:
          /* search in cce channels */
          for (i = 0; i < pPce->NumValidCcElements; i++) {
            if (pPce->ValidCcElementTagSelect[i] == tag) {
              return 1;
            }
          }
          break;
        case ID_DSE:
          /* search associated data elements */
          for (i = 0; i < pPce->NumAssocDataElements; i++) {
            if (pPce->AssocDataElementTagSelect[i] == tag) {
              return 1;
            }
          }
          break;
        default:
          return 0;
      }
      return 0; /* not found in any list */
    }
  }

  return 1;
}

#define SPEAKER_PLANE_NORMAL 0
#define SPEAKER_PLANE_TOP 1
#define SPEAKER_PLANE_BOTTOM 2

void CProgramConfig_GetChannelDescription(const UINT chConfig,
                                          const CProgramConfig *pPce,
                                          AUDIO_CHANNEL_TYPE chType[],
                                          UCHAR chIndex[]) {
  FDK_ASSERT(chType != NULL);
  FDK_ASSERT(chIndex != NULL);

  if ((chConfig == 0) && (pPce != NULL)) {
    if (pPce->isValid) {
      int spkPlane, chIdx = 0;
      for (spkPlane = SPEAKER_PLANE_NORMAL; spkPlane <= SPEAKER_PLANE_BOTTOM;
           spkPlane += 1) {
        int elIdx, grpChIdx = 0;
        for (elIdx = 0; elIdx < pPce->NumFrontChannelElements; elIdx += 1) {
          if (pPce->FrontElementHeightInfo[elIdx] == spkPlane) {
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
            chIndex[chIdx++] = grpChIdx++;
            if (pPce->FrontElementIsCpe[elIdx]) {
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_FRONT);
              chIndex[chIdx++] = grpChIdx++;
            }
          }
        }
        grpChIdx = 0;
        for (elIdx = 0; elIdx < pPce->NumSideChannelElements; elIdx += 1) {
          if (pPce->SideElementHeightInfo[elIdx] == spkPlane) {
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
            chIndex[chIdx++] = grpChIdx++;
            if (pPce->SideElementIsCpe[elIdx]) {
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_SIDE);
              chIndex[chIdx++] = grpChIdx++;
            }
          }
        }
        grpChIdx = 0;
        for (elIdx = 0; elIdx < pPce->NumBackChannelElements; elIdx += 1) {
          if (pPce->BackElementHeightInfo[elIdx] == spkPlane) {
            chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
            chIndex[chIdx++] = grpChIdx++;
            if (pPce->BackElementIsCpe[elIdx]) {
              chType[chIdx] = (AUDIO_CHANNEL_TYPE)((spkPlane << 4) | ACT_BACK);
              chIndex[chIdx++] = grpChIdx++;
            }
          }
        }
        grpChIdx = 0;
        if (spkPlane == SPEAKER_PLANE_NORMAL) {
          for (elIdx = 0; elIdx < pPce->NumLfeChannelElements; elIdx += 1) {
            chType[chIdx] = ACT_LFE;
            chIndex[chIdx++] = grpChIdx++;
          }
        }
      }
    }
  } else {
    int chIdx;
    for (chIdx = 0; chIdx < getNumberOfTotalChannels(chConfig); chIdx += 1) {
      getImplicitAudioChannelTypeAndIndex(&chType[chIdx], &chIndex[chIdx],
                                          chConfig, chIdx);
    }
  }
}

int CProgramConfig_GetPceChMap(const CProgramConfig *pPce, UCHAR pceChMap[],
                               const UINT pceChMapLen) {
  const UCHAR *nElements = &pPce->NumFrontChannelElements;
  const UCHAR *elHeight[3], *elIsCpe[3];
  unsigned chIdx, plane, grp, offset, totCh[3], numCh[3][4];

  FDK_ASSERT(pPce != NULL);
  FDK_ASSERT(pceChMap != NULL);

  /* Init counter: */
  FDKmemclear(totCh, 3 * sizeof(unsigned));
  FDKmemclear(numCh, 3 * 4 * sizeof(unsigned));

  /* Analyse PCE: */
  elHeight[0] = pPce->FrontElementHeightInfo;
  elIsCpe[0] = pPce->FrontElementIsCpe;
  elHeight[1] = pPce->SideElementHeightInfo;
  elIsCpe[1] = pPce->SideElementIsCpe;
  elHeight[2] = pPce->BackElementHeightInfo;
  elIsCpe[2] = pPce->BackElementIsCpe;

  for (plane = 0; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
    for (grp = 0; grp < 3; grp += 1) { /* front, side, back */
      unsigned el;
      for (el = 0; el < nElements[grp]; el += 1) {
        if (elHeight[grp][el] == plane) {
          unsigned elCh = elIsCpe[grp][el] ? 2 : 1;
          numCh[plane][grp] += elCh;
          totCh[plane] += elCh;
        }
      }
    }
    if (plane == SPEAKER_PLANE_NORMAL) {
      unsigned elCh = pPce->NumLfeChannelElements;
      numCh[plane][grp] += elCh;
      totCh[plane] += elCh;
    }
  }
  /* Sanity checks: */
  chIdx = totCh[SPEAKER_PLANE_NORMAL] + totCh[SPEAKER_PLANE_TOP] +
          totCh[SPEAKER_PLANE_BOTTOM];
  if (chIdx > pceChMapLen) {
    return -1;
  }

  /* Create map: */
  offset = grp = 0;
  unsigned grpThresh = numCh[SPEAKER_PLANE_NORMAL][grp];
  for (chIdx = 0; chIdx < totCh[SPEAKER_PLANE_NORMAL]; chIdx += 1) {
    while ((chIdx >= grpThresh) && (grp < 3)) {
      offset += numCh[1][grp] + numCh[2][grp];
      grp += 1;
      grpThresh += numCh[SPEAKER_PLANE_NORMAL][grp];
    }
    pceChMap[chIdx] = chIdx + offset;
  }
  offset = 0;
  for (grp = 0; grp < 4; grp += 1) { /* front, side, back and lfe */
    offset += numCh[SPEAKER_PLANE_NORMAL][grp];
    for (plane = SPEAKER_PLANE_TOP; plane <= SPEAKER_PLANE_BOTTOM; plane += 1) {
      unsigned mapCh;
      for (mapCh = 0; mapCh < numCh[plane][grp]; mapCh += 1) {
        pceChMap[chIdx++] = offset;
        offset += 1;
      }
    }
  }
  return 0;
}

int CProgramConfig_GetElementTable(const CProgramConfig *pPce,
                                   MP4_ELEMENT_ID elList[],
                                   const INT elListSize, UCHAR *pChMapIdx) {
  int i, el = 0;

  FDK_ASSERT(elList != NULL);
  FDK_ASSERT(pChMapIdx != NULL);
  FDK_ASSERT(pPce != NULL);

  *pChMapIdx = 0;

  if ((elListSize <
       pPce->NumFrontChannelElements + pPce->NumSideChannelElements +
           pPce->NumBackChannelElements + pPce->NumLfeChannelElements) ||
      (pPce->NumChannels == 0)) {
    return 0;
  }

  for (i = 0; i < pPce->NumFrontChannelElements; i += 1) {
    elList[el++] = (pPce->FrontElementIsCpe[i]) ? ID_CPE : ID_SCE;
  }

  for (i = 0; i < pPce->NumSideChannelElements; i += 1) {
    elList[el++] = (pPce->SideElementIsCpe[i]) ? ID_CPE : ID_SCE;
  }

  for (i = 0; i < pPce->NumBackChannelElements; i += 1) {
    elList[el++] = (pPce->BackElementIsCpe[i]) ? ID_CPE : ID_SCE;
  }

  for (i = 0; i < pPce->NumLfeChannelElements; i += 1) {
    elList[el++] = ID_LFE;
  }

  /* Find an corresponding channel configuration if possible */
  switch (pPce->NumChannels) {
    case 1:
    case 2:
      /* One and two channels have no alternatives. */
      *pChMapIdx = pPce->NumChannels;
      break;
    case 3:
    case 4:
    case 5:
    case 6: { /* Test if the number of channels can be used as channel config:
               */
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
      /* Create a PCE for the config to test ... */
      CProgramConfig_GetDefault(tmpPce, pPce->NumChannels);
      /* ... and compare it with the given one. */
      *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE))
                       ? pPce->NumChannels
                       : 0;
      /* If compare result is 0 or 1 we can be sure that it is channel
       * config 11. */
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
    } break;
    case 7: {
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
      /* Create a PCE for the config to test ... */
      CProgramConfig_GetDefault(tmpPce, 11);
      /* ... and compare it with the given one. */
      *pChMapIdx = (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) ? 11 : 0;
      /* If compare result is 0 or 1 we can be sure that it is channel
       * config 11. */
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
    } break;
    case 8: { /* Try the four possible 7.1ch configurations. One after the
                 other. */
      UCHAR testCfg[4] = {32, 14, 12, 7};
      C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
      for (i = 0; i < 4; i += 1) {
        /* Create a PCE for the config to test ... */
        CProgramConfig_GetDefault(tmpPce, testCfg[i]);
        /* ... and compare it with the given one. */
        if (!(CProgramConfig_Compare(pPce, tmpPce) & 0xE)) {
          /* If the compare result is 0 or 1 than the two channel configurations
           * match. */
          /* Explicit mapping of 7.1 side channel configuration to 7.1 rear
           * channel mapping. */
          *pChMapIdx = (testCfg[i] == 32) ? 12 : testCfg[i];
        }
      }
      C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
    } break;
    default:
      /* The PCE does not match any predefined channel configuration. */
      *pChMapIdx = 0;
      break;
  }

  return el;
}

static AUDIO_OBJECT_TYPE getAOT(HANDLE_FDK_BITSTREAM bs) {
  int tmp = 0;

  tmp = FDKreadBits(bs, 5);
  if (tmp == AOT_ESCAPE) {
    int tmp2 = FDKreadBits(bs, 6);
    tmp = 32 + tmp2;
  }

  return (AUDIO_OBJECT_TYPE)tmp;
}

static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits) {
  INT sampleRate;
  int idx;

  idx = FDKreadBits(bs, nBits);
  if (idx == (1 << nBits) - 1) {
    if (FDKgetValidBits(bs) < 24) {
      return 0;
    }
    sampleRate = FDKreadBits(bs, 24);
  } else {
    sampleRate = SamplingRateTable[idx];
  }

  *index = idx;

  return sampleRate;
}

static TRANSPORTDEC_ERROR GaSpecificConfig_Parse(CSGaSpecificConfig *self,
                                                 CSAudioSpecificConfig *asc,
                                                 HANDLE_FDK_BITSTREAM bs,
                                                 UINT ascStartAnchor) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;

  self->m_frameLengthFlag = FDKreadBits(bs, 1);

  self->m_dependsOnCoreCoder = FDKreadBits(bs, 1);

  if (self->m_dependsOnCoreCoder) self->m_coreCoderDelay = FDKreadBits(bs, 14);

  self->m_extensionFlag = FDKreadBits(bs, 1);

  if (asc->m_channelConfiguration == 0) {
    CProgramConfig_Read(&asc->m_progrConfigElement, bs, ascStartAnchor);
  }

  if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
    self->m_layer = FDKreadBits(bs, 3);
  }

  if (self->m_extensionFlag) {
    if (asc->m_aot == AOT_ER_BSAC) {
      self->m_numOfSubFrame = FDKreadBits(bs, 5);
      self->m_layerLength = FDKreadBits(bs, 11);
    }

    if ((asc->m_aot == AOT_ER_AAC_LC) || (asc->m_aot == AOT_ER_AAC_LTP) ||
        (asc->m_aot == AOT_ER_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_LD)) {
      asc->m_vcb11Flag = FDKreadBits(bs, 1); /* aacSectionDataResilienceFlag */
      asc->m_rvlcFlag =
          FDKreadBits(bs, 1); /* aacScalefactorDataResilienceFlag */
      asc->m_hcrFlag = FDKreadBits(bs, 1); /* aacSpectralDataResilienceFlag */
    }

    self->m_extensionFlag3 = FDKreadBits(bs, 1);
  }
  return (ErrorStatus);
}

static INT skipSbrHeader(HANDLE_FDK_BITSTREAM hBs, int isUsac) {
  /* Dummy parse SbrDfltHeader() */
  INT dflt_header_extra1, dflt_header_extra2, bitsToSkip = 0;

  if (!isUsac) {
    bitsToSkip = 6;
    FDKpushFor(hBs, 6); /* amp res 1, xover freq 3, reserved 2 */
  }
  bitsToSkip += 8;
  FDKpushFor(hBs, 8); /* start / stop freq */
  bitsToSkip += 2;
  dflt_header_extra1 = FDKreadBit(hBs);
  dflt_header_extra2 = FDKreadBit(hBs);
  bitsToSkip += 5 * dflt_header_extra1 + 6 * dflt_header_extra2;
  FDKpushFor(hBs, 5 * dflt_header_extra1 + 6 * dflt_header_extra2);

  return bitsToSkip;
}

static INT ld_sbr_header(CSAudioSpecificConfig *asc, const INT dsFactor,
                         HANDLE_FDK_BITSTREAM hBs, CSTpCallBacks *cb) {
  const int channelConfiguration = asc->m_channelConfiguration;
  int i = 0, j = 0;
  INT error = 0;
  MP4_ELEMENT_ID element = ID_NONE;

  /* check whether the channelConfiguration is defined in
   * channel_configuration_array */
  if (channelConfiguration < 0 ||
      channelConfiguration > (INT)(sizeof(channel_configuration_array) /
                                       sizeof(MP4_ELEMENT_ID **) -
                                   1)) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  /* read elements of the passed channel_configuration until there is ID_NONE */
  while ((element = channel_configuration_array[channelConfiguration][j]) !=
         ID_NONE) {
    if (element == ID_SCE || element == ID_CPE) {
      error |= cb->cbSbr(
          cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor,
          asc->m_extensionSamplingFrequency / dsFactor,
          asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0,
          asc->configMode, &asc->SbrConfigChanged, dsFactor);
      if (error != TRANSPORTDEC_OK) {
        goto bail;
      }
    }
    j++;
  }
bail:
  return error;
}

static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
                                                  HANDLE_FDK_BITSTREAM hBs,
                                                  CSTpCallBacks *cb) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig;
  ASC_ELD_EXT_TYPE eldExtType;
  int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0,
                           sbrIndex;

  unsigned char downscale_fill_nibble;

  FDKmemclear(esc, sizeof(CSEldSpecificConfig));

  esc->m_frameLengthFlag = FDKreadBits(hBs, 1);
  if (esc->m_frameLengthFlag) {
    asc->m_samplesPerFrame = 480;
  } else {
    asc->m_samplesPerFrame = 512;
  }

  asc->m_vcb11Flag = FDKreadBits(hBs, 1);
  asc->m_rvlcFlag = FDKreadBits(hBs, 1);
  asc->m_hcrFlag = FDKreadBits(hBs, 1);

  esc->m_sbrPresentFlag = FDKreadBits(hBs, 1);

  if (esc->m_sbrPresentFlag == 1) {
    esc->m_sbrSamplingRate =
        FDKreadBits(hBs, 1); /* 0: single rate, 1: dual rate */
    esc->m_sbrCrcFlag = FDKreadBits(hBs, 1);

    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency
                                        << esc->m_sbrSamplingRate;

    if (cb->cbSbr != NULL) {
      /* ELD reduced delay mode: LD-SBR initialization has to know the downscale
         information. Postpone LD-SBR initialization and read ELD extension
         information first. */
      switch (asc->m_channelConfiguration) {
        case 1:
        case 2:
          numSbrHeader = 1;
          break;
        case 3:
          numSbrHeader = 2;
          break;
        case 4:
        case 5:
        case 6:
          numSbrHeader = 3;
          break;
        case 7:
        case 11:
        case 12:
        case 14:
          numSbrHeader = 4;
          break;
        default:
          numSbrHeader = 0;
          break;
      }
      for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) {
        ldSbrLen += skipSbrHeader(hBs, 0);
      }
    } else {
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
    }
  }
  esc->m_useLdQmfTimeAlign = 0;

  /* new ELD syntax */
  eldExtLenSum = FDKgetValidBits(hBs);
  esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency;
  /* parse ExtTypeConfigData */
  while (
      ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) &&
      ((INT)FDKgetValidBits(hBs) >= 0)) {
    eldExtLen = len = FDKreadBits(hBs, 4);
    if (len == 0xf) {
      len = FDKreadBits(hBs, 8);
      eldExtLen += len;

      if (len == 0xff) {
        len = FDKreadBits(hBs, 16);
        eldExtLen += len;
      }
    }

    switch (eldExtType) {
      case ELDEXT_LDSAC:
        esc->m_useLdQmfTimeAlign = 1;
        if (cb->cbSsc != NULL) {
          ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
              cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency,
              1,  /* stereoConfigIndex */
              -1, /* nTimeSlots: read from bitstream */
              eldExtLen, asc->configMode, &asc->SacConfigChanged);
          if (ErrorStatus != TRANSPORTDEC_OK) {
            return TRANSPORTDEC_PARSE_ERROR;
          }
          break;
        }

      /* fall-through */
      default:
        for (cnt = 0; cnt < eldExtLen; cnt++) {
          FDKreadBits(hBs, 8);
        }
        break;

      case ELDEXT_DOWNSCALEINFO:
        UCHAR tmpDownscaleFreqIdx;
        esc->m_downscaledSamplingFrequency =
            getSampleRate(hBs, &tmpDownscaleFreqIdx, 4);
        if (esc->m_downscaledSamplingFrequency == 0) {
          return TRANSPORTDEC_PARSE_ERROR;
        }
        downscale_fill_nibble = FDKreadBits(hBs, 4);
        if (downscale_fill_nibble != 0x0) {
          return TRANSPORTDEC_PARSE_ERROR;
        }
        break;
    }
  }

  if ((INT)FDKgetValidBits(hBs) < 0) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  if (esc->m_sbrPresentFlag == 1 && numSbrHeader != 0) {
    INT dsFactor = 1; /* Downscale factor must be 1 or even for SBR */
    if (esc->m_downscaledSamplingFrequency != 0) {
      if (asc->m_samplingFrequency % esc->m_downscaledSamplingFrequency != 0) {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }
      dsFactor = asc->m_samplingFrequency / esc->m_downscaledSamplingFrequency;
      if (dsFactor != 1 && (dsFactor)&1) {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* SBR needs an even downscale
                                                   factor */
      }
      if (dsFactor != 1 && dsFactor != 2 && dsFactor != 4) {
        dsFactor = 1; /* don't apply dsf for not yet supported even dsfs */
      }
      if ((INT)asc->m_samplesPerFrame % dsFactor != 0) {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT; /* frameSize/dsf must be an
                                                   integer number */
      }
    }
    eldExtLenSum = eldExtLenSum - FDKgetValidBits(hBs);
    FDKpushBack(hBs, eldExtLenSum + ldSbrLen);
    if (0 != ld_sbr_header(asc, dsFactor, hBs, cb)) {
      return TRANSPORTDEC_PARSE_ERROR;
    }
    FDKpushFor(hBs, eldExtLenSum);
  }
  return (ErrorStatus);
}

/*
Subroutine to store config in UCHAR buffer. Bit stream position does not change.
*/
static UINT StoreConfigAsBitstream(
    HANDLE_FDK_BITSTREAM hBs, const INT configSize_bits, /* If < 0 (> 0) config
                                                            to read is before
                                                            (after) current bit
                                                            stream position. */
    UCHAR *configTargetBuffer, const USHORT configTargetBufferSize_bytes) {
  FDK_BITSTREAM usacConf;
  UINT const nBits = fAbs(configSize_bits);
  UINT j, tmp;

  if (nBits > 8 * (UINT)configTargetBufferSize_bytes) {
    return 1;
  }
  FDKmemclear(configTargetBuffer, configTargetBufferSize_bytes);

  FDKinitBitStream(&usacConf, configTargetBuffer, configTargetBufferSize_bytes,
                   nBits, BS_WRITER);
  if (configSize_bits < 0) {
    FDKpushBack(hBs, nBits);
  }
  for (j = nBits; j > 31; j -= 32) {
    tmp = FDKreadBits(hBs, 32);
    FDKwriteBits(&usacConf, tmp, 32);
  }
  if (j > 0) {
    tmp = FDKreadBits(hBs, j);
    FDKwriteBits(&usacConf, tmp, j);
  }
  FDKsyncCache(&usacConf);
  if (configSize_bits > 0) {
    FDKpushBack(hBs, nBits);
  }

  return 0;
}

/* maps coreSbrFrameLengthIndex to coreCoderFrameLength */
static const USHORT usacFrameLength[8] = {768, 1024, 2048, 2048, 4096, 0, 0, 0};
/* maps coreSbrFrameLengthIndex to sbrRatioIndex */
static const UCHAR sbrRatioIndex[8] = {0, 0, 2, 3, 1, 0, 0, 0};

/*
  subroutine for parsing extension element configuration:
  UsacExtElementConfig() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 14
  rsv603daExtElementConfig() q.v. ISO/IEC DIS 23008-3 Table 13
*/
static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement,
                                           HANDLE_FDK_BITSTREAM hBs,
                                           const CSTpCallBacks *cb,
                                           const UCHAR numSignalsInGroup,
                                           const UINT coreFrameLength,
                                           const int subStreamIndex,
                                           const AUDIO_OBJECT_TYPE aot) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;

  USAC_EXT_ELEMENT_TYPE usacExtElementType =
      (USAC_EXT_ELEMENT_TYPE)escapedValue(hBs, 4, 8, 16);

  /* recurve extension elements which are invalid for USAC */
  if (aot == AOT_USAC) {
    switch (usacExtElementType) {
      case ID_EXT_ELE_FILL:
      case ID_EXT_ELE_MPEGS:
      case ID_EXT_ELE_SAOC:
      case ID_EXT_ELE_AUDIOPREROLL:
      case ID_EXT_ELE_UNI_DRC:
        break;
      default:
        usacExtElementType = ID_EXT_ELE_UNKNOWN;
        break;
    }
  }

  extElement->usacExtElementType = usacExtElementType;
  int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16);
  extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength;
  INT bsAnchor;

  if (FDKreadBit(hBs)) /* usacExtElementDefaultLengthPresent */
    extElement->usacExtElementDefaultLength = escapedValue(hBs, 8, 16, 0) + 1;
  else
    extElement->usacExtElementDefaultLength = 0;

  extElement->usacExtElementPayloadFrag = FDKreadBit(hBs);

  bsAnchor = (INT)FDKgetValidBits(hBs);

  switch (usacExtElementType) {
    case ID_EXT_ELE_UNKNOWN:
    case ID_EXT_ELE_FILL:
      break;
    case ID_EXT_ELE_AUDIOPREROLL:
      /* No configuration element */
      extElement->usacExtElementHasAudioPreRoll = 1;
      break;
    case ID_EXT_ELE_UNI_DRC: {
      if (cb->cbUniDrc != NULL) {
        ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
            cb->cbUniDrcData, hBs, usacExtElementConfigLength,
            0, /* uniDrcConfig */
            subStreamIndex, 0, aot);
        if (ErrorStatus != TRANSPORTDEC_OK) {
          return ErrorStatus;
        }
      }
    } break;
    default:
      break;
  }

  /* Adjust bit stream position. This is required because of byte alignment and
   * unhandled extensions. */
  {
    INT left_bits = (usacExtElementConfigLength << 3) -
                    (bsAnchor - (INT)FDKgetValidBits(hBs));
    if (left_bits >= 0) {
      FDKpushFor(hBs, left_bits);
    } else {
      /* parsed too many bits */
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
    }
  }

  return ErrorStatus;
}

/*
  subroutine for parsing the USAC / RSVD60 configuration extension:
  UsacConfigExtension() q.v. ISO/IEC FDIS 23003-3:2011(E) Table 15
  rsv603daConfigExtension() q.v. ISO/IEC DIS 23008-3 Table 14
*/
static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc,
                                          HANDLE_FDK_BITSTREAM hBs,
                                          const CSTpCallBacks *cb) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;

  int numConfigExtensions;
  CONFIG_EXT_ID usacConfigExtType;
  int usacConfigExtLength;

  numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1;
  for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) {
    INT nbits;
    int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs);
    usacConfigExtType = (CONFIG_EXT_ID)escapedValue(hBs, 4, 8, 16);
    usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16);

    /* Start bit position of config extension */
    nbits = (INT)FDKgetValidBits(hBs);

    /* Return an error in case the bitbuffer fill level is too low. */
    if (nbits < usacConfigExtLength * 8) {
      return TRANSPORTDEC_PARSE_ERROR;
    }

    switch (usacConfigExtType) {
      case ID_CONFIG_EXT_FILL:
        for (int i = 0; i < usacConfigExtLength; i++) {
          if (FDKreadBits(hBs, 8) != 0xa5) {
            return TRANSPORTDEC_PARSE_ERROR;
          }
        }
        break;
      case ID_CONFIG_EXT_LOUDNESS_INFO: {
        if (cb->cbUniDrc != NULL) {
          ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc(
              cb->cbUniDrcData, hBs, usacConfigExtLength,
              1, /* loudnessInfoSet */
              0, loudnessInfoSetConfigExtensionPosition, AOT_USAC);
          if (ErrorStatus != TRANSPORTDEC_OK) {
            return ErrorStatus;
          }
        }
      } break;
      default:
        break;
    }

    /* Skip remaining bits. If too many bits were parsed, assume error. */
    usacConfigExtLength =
        8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs));
    if (usacConfigExtLength < 0) {
      return TRANSPORTDEC_PARSE_ERROR;
    }
    FDKpushFor(hBs, usacConfigExtLength);
  }

  return ErrorStatus;
}

/* This function unifies decoder config parsing of USAC and RSV60:
   rsv603daDecoderConfig() ISO/IEC DIS 23008-3   Table 8
   UsacDecoderConfig()     ISO/IEC FDIS 23003-3  Table 6
  */
static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs,
    const CSTpCallBacks *cb) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
  int i, numberOfElements;
  int channelElementIdx =
      0; /* index for elements which contain audio channels (sce, cpe, lfe) */
  SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0};

  numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1;
  usc->m_usacNumElements = numberOfElements;
  if (numberOfElements > TP_USAC_MAX_ELEMENTS) {
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }
  usc->m_nUsacChannels = 0;
  usc->m_channelConfigurationIndex = asc->m_channelConfiguration;

  if (asc->m_aot == AOT_USAC) {
    sc_chan_config = sc_chan_config_tab[usc->m_channelConfigurationIndex];

    if (sc_chan_config.nCh > (SCHAR)TP_USAC_MAX_SPEAKERS) {
      return TRANSPORTDEC_PARSE_ERROR;
    }
  }

  for (i = 0; i < numberOfElements; i++) {
    MP4_ELEMENT_ID usacElementType = (MP4_ELEMENT_ID)(
        FDKreadBits(hBs, 2) | USAC_ID_BIT); /* set USAC_ID_BIT to map
                                               usacElementType to
                                               MP4_ELEMENT_ID enum */
    usc->element[i].usacElementType = usacElementType;

    /* sanity check: update element counter */
    if (asc->m_aot == AOT_USAC) {
      switch (usacElementType) {
        case ID_USAC_SCE:
          sc_chan_config.nSCE--;
          break;
        case ID_USAC_CPE:
          sc_chan_config.nCPE--;
          break;
        case ID_USAC_LFE:
          sc_chan_config.nLFE--;
          break;
        default:
          break;
      }
      if (usc->m_channelConfigurationIndex) {
        /* sanity check: no element counter may be smaller zero */
        if (sc_chan_config.nCPE < 0 || sc_chan_config.nSCE < 0 ||
            sc_chan_config.nLFE < 0) {
          return TRANSPORTDEC_PARSE_ERROR;
        }
      }
    }

    switch (usacElementType) {
      case ID_USAC_SCE:
        /* UsacCoreConfig() ISO/IEC FDIS 23003-3  Table 10 */
        if (FDKreadBit(hBs)) { /* tw_mdct */
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
        }
        usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
        /* end of UsacCoreConfig() */
        if (usc->m_sbrRatioIndex > 0) {
          if (cb->cbSbr == NULL) {
            return TRANSPORTDEC_UNKOWN_ERROR;
          }
          /* SbrConfig() ISO/IEC FDIS 23003-3  Table 11 */
          usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
          usc->element[i].m_interTes = FDKreadBit(hBs);
          usc->element[i].m_pvc = FDKreadBit(hBs);
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
                        asc->m_extensionSamplingFrequency,
                        asc->m_samplesPerFrame, asc->m_aot, ID_SCE,
                        channelElementIdx, usc->element[i].m_harmonicSBR,
                        usc->element[i].m_stereoConfigIndex, asc->configMode,
                        &asc->SbrConfigChanged, 1)) {
            return TRANSPORTDEC_PARSE_ERROR;
          }
          /* end of SbrConfig() */
        }
        usc->m_nUsacChannels += 1;
        channelElementIdx++;
        break;

      case ID_USAC_CPE:
        /* UsacCoreConfig() ISO/IEC FDIS 23003-3  Table 10 */
        if (FDKreadBit(hBs)) { /* tw_mdct */
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
        }
        usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1);
        /* end of UsacCoreConfig() */
        if (usc->m_sbrRatioIndex > 0) {
          if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR;
          /* SbrConfig() ISO/IEC FDIS 23003-3 */
          usc->element[i].m_harmonicSBR = FDKreadBit(hBs);
          usc->element[i].m_interTes = FDKreadBit(hBs);
          usc->element[i].m_pvc = FDKreadBit(hBs);
          {
            INT bitsToSkip = skipSbrHeader(hBs, 1);
            /* read stereoConfigIndex */
            usc->element[i].m_stereoConfigIndex = FDKreadBits(hBs, 2);
            /* rewind */
            FDKpushBack(hBs, bitsToSkip + 2);
          }
          {
            MP4_ELEMENT_ID el_type =
                (usc->element[i].m_stereoConfigIndex == 1 ||
                 usc->element[i].m_stereoConfigIndex == 2)
                    ? ID_SCE
                    : ID_CPE;
            if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
                          asc->m_extensionSamplingFrequency,
                          asc->m_samplesPerFrame, asc->m_aot, el_type,
                          channelElementIdx, usc->element[i].m_harmonicSBR,
                          usc->element[i].m_stereoConfigIndex, asc->configMode,
                          &asc->SbrConfigChanged, 1)) {
              return TRANSPORTDEC_PARSE_ERROR;
            }
          }
          /* end of SbrConfig() */

          usc->element[i].m_stereoConfigIndex =
              FDKreadBits(hBs, 2); /* Needed in RM5 syntax */

          if (usc->element[i].m_stereoConfigIndex > 0) {
            if (cb->cbSsc != NULL) {
              /* Mps212Config() ISO/IEC FDIS 23003-3 */
              if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
                            asc->m_extensionSamplingFrequency,
                            usc->element[i].m_stereoConfigIndex,
                            usc->m_coreSbrFrameLengthIndex,
                            0, /* don't know the length */
                            asc->configMode, &asc->SacConfigChanged)) {
                return TRANSPORTDEC_PARSE_ERROR;
              }
              /* end of Mps212Config() */
            } else {
              return TRANSPORTDEC_UNKOWN_ERROR;
            }
          }
        } else {
          usc->element[i].m_stereoConfigIndex = 0;
        }
        usc->m_nUsacChannels += 2;

        channelElementIdx++;
        break;

      case ID_USAC_LFE:
        usc->element[i].m_noiseFilling = 0;
        usc->m_nUsacChannels += 1;
        if (usc->m_sbrRatioIndex > 0) {
          /* Use SBR for upsampling */
          if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
          usc->element[i].m_harmonicSBR = (UCHAR)0;
          usc->element[i].m_interTes = (UCHAR)0;
          usc->element[i].m_pvc = (UCHAR)0;
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
                        asc->m_extensionSamplingFrequency,
                        asc->m_samplesPerFrame, asc->m_aot, ID_LFE,
                        channelElementIdx, usc->element[i].m_harmonicSBR,
                        usc->element[i].m_stereoConfigIndex, asc->configMode,
                        &asc->SbrConfigChanged, 1)) {
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
          }
        }
        channelElementIdx++;
        break;

      case ID_USAC_EXT:
        ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0,
                                       asc->m_samplesPerFrame, 0, asc->m_aot);

        if (ErrorStatus) {
          return ErrorStatus;
        }
        break;

      default:
        /* non USAC-element encountered */
        return TRANSPORTDEC_PARSE_ERROR;
    }
  }

  if (asc->m_aot == AOT_USAC) {
    if (usc->m_channelConfigurationIndex) {
      /* sanity check: all element counter must be zero */
      if (sc_chan_config.nCPE | sc_chan_config.nSCE | sc_chan_config.nLFE) {
        return TRANSPORTDEC_PARSE_ERROR;
      }
    } else {
      /* sanity check: number of audio channels shall be equal to or smaller
       * than the accumulated sum of all channels */
      if ((INT)(-2 * sc_chan_config.nCPE - sc_chan_config.nSCE -
                sc_chan_config.nLFE) < (INT)usc->numAudioChannels) {
        return TRANSPORTDEC_PARSE_ERROR;
      }
    }
  }

  return ErrorStatus;
}

/* Mapping of coreSbrFrameLengthIndex defined by Table 70 in ISO/IEC 23003-3 */
static TRANSPORTDEC_ERROR UsacConfig_SetCoreSbrFrameLengthIndex(
    CSAudioSpecificConfig *asc, int coreSbrFrameLengthIndex) {
  int sbrRatioIndex_val;

  if (coreSbrFrameLengthIndex > 4) {
    return TRANSPORTDEC_PARSE_ERROR; /* reserved values */
  }
  asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex = coreSbrFrameLengthIndex;
  asc->m_samplesPerFrame = usacFrameLength[coreSbrFrameLengthIndex];
  sbrRatioIndex_val = sbrRatioIndex[coreSbrFrameLengthIndex];
  asc->m_sc.m_usacConfig.m_sbrRatioIndex = sbrRatioIndex_val;

  if (sbrRatioIndex_val > 0) {
    asc->m_sbrPresentFlag = 1;
    asc->m_extensionSamplingFrequency = asc->m_samplingFrequency;
    asc->m_extensionSamplingFrequencyIndex = asc->m_samplingFrequencyIndex;
    switch (sbrRatioIndex_val) {
      case 1: /* sbrRatio = 4:1 */
        asc->m_samplingFrequency >>= 2;
        asc->m_samplesPerFrame >>= 2;
        break;
      case 2: /* sbrRatio = 8:3 */
        asc->m_samplingFrequency = (asc->m_samplingFrequency * 3) / 8;
        asc->m_samplesPerFrame = (asc->m_samplesPerFrame * 3) / 8;
        break;
      case 3: /* sbrRatio = 2:1 */
        asc->m_samplingFrequency >>= 1;
        asc->m_samplesPerFrame >>= 1;
        break;
      default:
        return TRANSPORTDEC_PARSE_ERROR;
    }
    asc->m_samplingFrequencyIndex =
        getSamplingRateIndex(asc->m_samplingFrequency, 4);
  }

  return TRANSPORTDEC_OK;
}

static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc,
                                           HANDLE_FDK_BITSTREAM hBs,
                                           CSTpCallBacks *cb) {
  int usacSamplingFrequency, channelConfigurationIndex, coreSbrFrameLengthIndex;
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  /* Start bit position of usacConfig */
  INT nbits = (INT)FDKgetValidBits(hBs);

  usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5);
  asc->m_samplingFrequency = (UINT)usacSamplingFrequency;

  coreSbrFrameLengthIndex = FDKreadBits(hBs, 3);
  if (UsacConfig_SetCoreSbrFrameLengthIndex(asc, coreSbrFrameLengthIndex) !=
      TRANSPORTDEC_OK) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  channelConfigurationIndex = FDKreadBits(hBs, 5);
  if (channelConfigurationIndex > 2) {
    return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
                                        are supported */
  }

  if (channelConfigurationIndex == 0) {
    return TRANSPORTDEC_PARSE_ERROR; /* only channelConfigurationIndex = [1,2]
                                        are supported */
  }
  asc->m_channelConfiguration = channelConfigurationIndex;

  err = UsacRsv60DecoderConfig_Parse(asc, hBs, cb);
  if (err != TRANSPORTDEC_OK) {
    return err;
  }

  if (FDKreadBits(hBs, 1)) { /* usacConfigExtensionPresent */
    err = configExtension(&asc->m_sc.m_usacConfig, hBs, cb);
    if (err != TRANSPORTDEC_OK) {
      return err;
    }
  }

  /* sanity check whether number of channels signaled in UsacDecoderConfig()
     matches the number of channels required by channelConfigurationIndex */
  if ((channelConfigurationIndex > 0) &&
      (sc_chan_config_tab[channelConfigurationIndex].nCh !=
       asc->m_sc.m_usacConfig.m_nUsacChannels)) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */
  INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits;
  StoreConfigAsBitstream(hBs, configSize_bits,
                         asc->m_sc.m_usacConfig.UsacConfig,
                         TP_USAC_MAX_CONFIG_LEN);
  asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits);

  return err;
}

static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb) {
  TP_ASC_EXTENSION_ID lastAscExt, ascExtId = ASCEXT_UNKOWN;
  INT bitsAvailable = (INT)FDKgetValidBits(bs);

  while (bitsAvailable >= 11) {
    lastAscExt = ascExtId;
    ascExtId = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
    bitsAvailable -= 11;

    switch (ascExtId) {
      case ASCEXT_SBR: /* 0x2b7 */
        if ((self->m_extensionAudioObjectType != AOT_SBR) &&
            (bitsAvailable >= 5)) {
          self->m_extensionAudioObjectType = getAOT(bs);

          if ((self->m_extensionAudioObjectType == AOT_SBR) ||
              (self->m_extensionAudioObjectType ==
               AOT_ER_BSAC)) { /* Get SBR extension configuration */
            self->m_sbrPresentFlag = FDKreadBits(bs, 1);
            if (self->m_aot == AOT_USAC && self->m_sbrPresentFlag > 0 &&
                self->m_sc.m_usacConfig.m_sbrRatioIndex == 0) {
              return TRANSPORTDEC_PARSE_ERROR;
            }

            if (self->m_sbrPresentFlag == 1) {
              self->m_extensionSamplingFrequency = getSampleRate(
                  bs, &self->m_extensionSamplingFrequencyIndex, 4);

              if ((INT)self->m_extensionSamplingFrequency <= 0) {
                return TRANSPORTDEC_PARSE_ERROR;
              }
            }
            if (self->m_extensionAudioObjectType == AOT_ER_BSAC) {
              self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
            }
          }
          /* Update counter because of variable length fields (AOT and sampling
           * rate) */
          bitsAvailable = (INT)FDKgetValidBits(bs);
        }
        break;
      case ASCEXT_PS: /* 0x548 */
        if ((lastAscExt == ASCEXT_SBR) &&
            (self->m_extensionAudioObjectType == AOT_SBR) &&
            (bitsAvailable > 0)) { /* Get PS extension configuration */
          self->m_psPresentFlag = FDKreadBits(bs, 1);
          bitsAvailable -= 1;
        }
        break;
      case ASCEXT_MPS: /* 0x76a */
        if (self->m_extensionAudioObjectType == AOT_MPEGS) break;
      case ASCEXT_LDMPS: /* 0x7cc */
        if ((ascExtId == ASCEXT_LDMPS) &&
            (self->m_extensionAudioObjectType == AOT_LD_MPEGS))
          break;
        if (bitsAvailable >= 1) {
          bitsAvailable -= 1;
          if (FDKreadBits(bs, 1)) { /* self->m_mpsPresentFlag */
            int sscLen = FDKreadBits(bs, 8);
            bitsAvailable -= 8;
            if (sscLen == 0xFF) {
              sscLen += FDKreadBits(bs, 16);
              bitsAvailable -= 16;
            }
            FDKpushFor(bs, sscLen); /* Skip SSC to be able to read the next
                                       extension if there is one. */

            bitsAvailable -= sscLen * 8;
          }
        }
        break;
      case ASCEXT_SAOC:
        if ((ascExtId == ASCEXT_SAOC) &&
            (self->m_extensionAudioObjectType == AOT_SAOC))
          break;
        if (FDKreadBits(bs, 1)) { /* saocPresent */
          int saocscLen = FDKreadBits(bs, 8);
          bitsAvailable -= 8;
          if (saocscLen == 0xFF) {
            saocscLen += FDKreadBits(bs, 16);
            bitsAvailable -= 16;
          }
          FDKpushFor(bs, saocscLen);
          bitsAvailable -= saocscLen * 8;
        }
        break;
      default:
        /* Just ignore anything. */
        return TRANSPORTDEC_OK;
    }
  }

  return TRANSPORTDEC_OK;
}

/*
 * API Functions
 */

void AudioSpecificConfig_Init(CSAudioSpecificConfig *asc) {
  FDKmemclear(asc, sizeof(CSAudioSpecificConfig));

  /* Init all values that should not be zero. */
  asc->m_aot = AOT_NONE;
  asc->m_samplingFrequencyIndex = 0xf;
  asc->m_epConfig = -1;
  asc->m_extensionAudioObjectType = AOT_NULL_OBJECT;
  CProgramConfig_Init(&asc->m_progrConfigElement);
}

TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
    int fExplicitBackwardCompatible, CSTpCallBacks *cb, UCHAR configMode,
    UCHAR configChanged, AUDIO_OBJECT_TYPE m_aot) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  UINT ascStartAnchor = FDKgetValidBits(bs);
  int frameLengthFlag = -1;

  AudioSpecificConfig_Init(self);

  self->configMode = configMode;
  self->AacConfigChanged = configChanged;
  self->SbrConfigChanged = configChanged;
  self->SacConfigChanged = configChanged;

  if (m_aot != AOT_NULL_OBJECT) {
    self->m_aot = m_aot;
  } else {
    self->m_aot = getAOT(bs);
    self->m_samplingFrequency =
        getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
    if (self->m_samplingFrequency <= 0 ||
        (self->m_samplingFrequency > 96000 && self->m_aot != 39) ||
        self->m_samplingFrequency > 4 * 96000) {
      return TRANSPORTDEC_PARSE_ERROR;
    }

    self->m_channelConfiguration = FDKreadBits(bs, 4);

    /* SBR extension ( explicit non-backwards compatible mode ) */
    self->m_sbrPresentFlag = 0;
    self->m_psPresentFlag = 0;

    if (self->m_aot == AOT_SBR || self->m_aot == AOT_PS) {
      self->m_extensionAudioObjectType = AOT_SBR;

      self->m_sbrPresentFlag = 1;
      if (self->m_aot == AOT_PS) {
        self->m_psPresentFlag = 1;
      }

      self->m_extensionSamplingFrequency =
          getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
      self->m_aot = getAOT(bs);

      switch (self->m_aot) {
        case AOT_AAC_LC:
          break;
        case AOT_ER_BSAC:
          break;
        default:
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }

      if (self->m_aot == AOT_ER_BSAC) {
        self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
      }
    } else {
      self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
    }
  }

  /* Parse whatever specific configs */
  switch (self->m_aot) {
    case AOT_AAC_LC:
    case AOT_AAC_SCAL:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_BSAC:
      if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig,
                                                self, bs, ascStartAnchor)) !=
          TRANSPORTDEC_OK) {
        return (ErrorStatus);
      }
      frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
      break;
    case AOT_MPEGS:
      if (cb->cbSsc != NULL) {
        if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
                      1, -1, /* nTimeSlots: read from bitstream */
                      0,     /* don't know the length */
                      self->configMode, &self->SacConfigChanged)) {
          return TRANSPORTDEC_UNSUPPORTED_FORMAT;
        }
      } else {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }
      break;
    case AOT_ER_AAC_ELD:
      if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) !=
          TRANSPORTDEC_OK) {
        return (ErrorStatus);
      }
      frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
      self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
      self->m_extensionSamplingFrequency =
          (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate + 1) *
          self->m_samplingFrequency;
      break;
    case AOT_USAC:
      if ((ErrorStatus = UsacConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK) {
        return (ErrorStatus);
      }
      break;

    default:
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }

  /* Frame length */
  switch (self->m_aot) {
    case AOT_AAC_LC:
    case AOT_AAC_SCAL:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_BSAC:
      /*case AOT_USAC:*/
      if (!frameLengthFlag)
        self->m_samplesPerFrame = 1024;
      else
        self->m_samplesPerFrame = 960;
      break;
    case AOT_ER_AAC_LD:
      if (!frameLengthFlag)
        self->m_samplesPerFrame = 512;
      else
        self->m_samplesPerFrame = 480;
      break;
    default:
      break;
  }

  switch (self->m_aot) {
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_ELD:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_CELP:
    case AOT_ER_HVXC:
    case AOT_ER_BSAC:
      self->m_epConfig = FDKreadBits(bs, 2);

      if (self->m_epConfig > 1) {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;  // EPCONFIG;
      }
      break;
    default:
      break;
  }

  if (fExplicitBackwardCompatible &&
      (self->m_aot == AOT_AAC_LC || self->m_aot == AOT_ER_AAC_LD ||
       self->m_aot == AOT_ER_BSAC)) {
    ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
  }

  /* Copy config() to asc->config[] buffer. */
  if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) {
    INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor;
    StoreConfigAsBitstream(bs, configSize_bits, self->config,
                           TP_USAC_MAX_CONFIG_LEN);
    self->configBits = fAbs(configSize_bits);
  }

  return (ErrorStatus);
}

static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM hBs, int audioMode,
    CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  CSUsacConfig *usc = &asc->m_sc.m_usacConfig;
  int elemIdx = 0;

  usc->element[elemIdx].m_stereoConfigIndex = 0;

  usc->m_usacNumElements = 1; /* Currently all extension elements are skipped
                                 -> only one SCE or CPE. */

  switch (audioMode) {
    case 0: /* mono: ID_USAC_SCE */
      usc->element[elemIdx].usacElementType = ID_USAC_SCE;
      usc->m_nUsacChannels = 1;
      usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
      if (usc->m_sbrRatioIndex > 0) {
        if (cb == NULL) {
          return ErrorStatus;
        }
        if (cb->cbSbr != NULL) {
          usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
          usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
          usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
                        asc->m_extensionSamplingFrequency,
                        asc->m_samplesPerFrame, asc->m_aot, ID_SCE, elemIdx,
                        usc->element[elemIdx].m_harmonicSBR,
                        usc->element[elemIdx].m_stereoConfigIndex,
                        asc->configMode, &asc->SbrConfigChanged, 1)) {
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
          }
        }
      }
      break;
    case 2: /* stereo: ID_USAC_CPE */
      usc->element[elemIdx].usacElementType = ID_USAC_CPE;
      usc->m_nUsacChannels = 2;
      usc->element[elemIdx].m_noiseFilling = FDKreadBits(hBs, 1);
      if (usc->m_sbrRatioIndex > 0) {
        usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs);
        usc->element[elemIdx].m_interTes = FDKreadBit(hBs);
        usc->element[elemIdx].m_pvc = FDKreadBit(hBs);
        {
          INT bitsToSkip = skipSbrHeader(hBs, 1);
          /* read stereoConfigIndex */
          usc->element[elemIdx].m_stereoConfigIndex = FDKreadBits(hBs, 2);
          /* rewind */
          FDKpushBack(hBs, bitsToSkip + 2);
        }
        /*
        The application of the following tools is mutually exclusive per audio
        stream configuration (see clause 5.3.2, xHE-AAC codec configuration):
        - MPS212 parametric stereo tool with residual coding
        (stereoConfigIndex>1); and
        - QMF based Harmonic Transposer (harmonicSBR==1).
        */
        if ((usc->element[elemIdx].m_stereoConfigIndex > 1) &&
            usc->element[elemIdx].m_harmonicSBR) {
          return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
        }
        /*
        The 4:1 sbrRatio (sbrRatioIndex==1 in [11]) may only be employed:
        - in mono operation; or
        - in stereo operation if parametric stereo (MPS212) without residual
        coding is applied, i.e. if stereoConfigIndex==1 (see clause 5.3.2,
        xHE-AAC codec configuration).
        */
        if ((usc->m_sbrRatioIndex == 1) &&
            (usc->element[elemIdx].m_stereoConfigIndex != 1)) {
          return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
        }
        if (cb == NULL) {
          return ErrorStatus;
        }
        {
          MP4_ELEMENT_ID el_type =
              (usc->element[elemIdx].m_stereoConfigIndex == 1 ||
               usc->element[elemIdx].m_stereoConfigIndex == 2)
                  ? ID_SCE
                  : ID_CPE;
          if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR;
          if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency,
                        asc->m_extensionSamplingFrequency,
                        asc->m_samplesPerFrame, asc->m_aot, el_type, elemIdx,
                        usc->element[elemIdx].m_harmonicSBR,
                        usc->element[elemIdx].m_stereoConfigIndex,
                        asc->configMode, &asc->SbrConfigChanged, 1)) {
            return ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
          }
        }
        /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
        if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
          if (cb->cbSsc != NULL) {
            ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
                cb->cbSscData, hBs,
                AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
                asc->m_extensionSamplingFrequency,
                usc->element[elemIdx].m_stereoConfigIndex,
                usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
                asc->configMode, &asc->SacConfigChanged);
          } else {
            /* ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; */
          }
        }
      }
      break;
    default:
      return TRANSPORTDEC_PARSE_ERROR;
  }

  return ErrorStatus;
}

TRANSPORTDEC_ERROR Drm_xHEAACStaticConfig(
    CSAudioSpecificConfig *asc, HANDLE_FDK_BITSTREAM bs, int audioMode,
    CSTpCallBacks *cb /* use cb == NULL to signal config check only mode */
) {
  int coreSbrFrameLengthIndexDrm = FDKreadBits(bs, 2);
  if (UsacConfig_SetCoreSbrFrameLengthIndex(
          asc, coreSbrFrameLengthIndexDrm + 1) != TRANSPORTDEC_OK) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  asc->m_channelConfiguration = (audioMode) ? 2 : 1;

  if (Drm_xHEAACDecoderConfig(asc, bs, audioMode, cb) != TRANSPORTDEC_OK) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  return TRANSPORTDEC_OK;
}

/* Mapping of DRM audio sampling rate field to MPEG usacSamplingFrequencyIndex
 */
const UCHAR mapSr2MPEGIdx[8] = {
    0x1b, /*  9.6 kHz */
    0x09, /* 12.0 kHz */
    0x08, /* 16.0 kHz */
    0x17, /* 19.2 kHz */
    0x06, /* 24.0 kHz */
    0x05, /* 32.0 kHz */
    0x12, /* 38.4 kHz */
    0x03  /* 48.0 kHz */
};

TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
    CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs,
    CSTpCallBacks *cb, /* use cb == NULL to signal config check only mode */
    UCHAR configMode, UCHAR configChanged) {
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;

  AudioSpecificConfig_Init(self);

  if ((INT)FDKgetValidBits(bs) < 16) {
    ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
    goto bail;
  } else {
    /* DRM - Audio information data entity - type 9
       - Short Id            2 bits (not part of the config buffer)
       - Stream Id           2 bits (not part of the config buffer)
       - audio coding        2 bits
       - SBR flag            1 bit
       - audio mode          2 bits
       - audio sampling rate 3 bits
       - text flag           1 bit
       - enhancement flag    1 bit
       - coder field         5 bits
       - rfa                 1 bit  */

    int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;

    self->configMode = configMode;
    self->AacConfigChanged = configChanged;
    self->SbrConfigChanged = configChanged;
    self->SacConfigChanged = configChanged;

    /* Read the SDC field */
    audioCoding = FDKreadBits(bs, 2);
    sbrFlag = FDKreadBits(bs, 1);
    audioMode = FDKreadBits(bs, 2);
    cSamplingFreq = FDKreadBits(bs, 3); /* audio sampling rate */

    FDKreadBits(bs, 2); /* Text and enhancement flag */
    coderField = FDKreadBits(bs, 5);
    FDKreadBits(bs, 1); /* rfa */

    /* Evaluate configuration and fill the ASC */
    if (audioCoding == 3) {
      sfIdx = (int)mapSr2MPEGIdx[cSamplingFreq];
      sbrFlag = 0; /* rfa */
    } else {
      switch (cSamplingFreq) {
        case 0: /*  8 kHz */
          sfIdx = 11;
          break;
        case 1: /* 12 kHz */
          sfIdx = 9;
          break;
        case 2: /* 16 kHz */
          sfIdx = 8;
          break;
        case 3: /* 24 kHz */
          sfIdx = 6;
          break;
        case 5: /* 48 kHz */
          sfIdx = 3;
          break;
        case 4: /* reserved */
        case 6: /* reserved */
        case 7: /* reserved */
        default:
          ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
          goto bail;
      }
    }

    self->m_samplingFrequencyIndex = sfIdx;
    self->m_samplingFrequency = SamplingRateTable[sfIdx];

    if (sbrFlag) {
      UINT i;
      int tmp = -1;
      self->m_sbrPresentFlag = 1;
      self->m_extensionAudioObjectType = AOT_SBR;
      self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
      for (i = 0;
           i < (sizeof(SamplingRateTable) / sizeof(SamplingRateTable[0]));
           i++) {
        if (SamplingRateTable[i] == self->m_extensionSamplingFrequency) {
          tmp = i;
          break;
        }
      }
      self->m_extensionSamplingFrequencyIndex = tmp;
    }

    switch (audioCoding) {
      case 0: /* AAC */
        if ((coderField >> 2) && (audioMode != 1)) {
          self->m_aot = AOT_DRM_SURROUND; /* Set pseudo AOT for Drm Surround */
        } else {
          self->m_aot = AOT_DRM_AAC; /* Set pseudo AOT for Drm AAC */
        }
        switch (audioMode) {
          case 1: /* parametric stereo */
            self->m_psPresentFlag = 1;
          case 0: /* mono */
            self->m_channelConfiguration = 1;
            break;
          case 2: /* stereo */
            self->m_channelConfiguration = 2;
            break;
          default:
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
            goto bail;
        }
        self->m_vcb11Flag = 1;
        self->m_hcrFlag = 1;
        self->m_samplesPerFrame = 960;
        self->m_epConfig = 1;
        break;
      case 1: /* CELP */
        self->m_aot = AOT_ER_CELP;
        self->m_channelConfiguration = 1;
        break;
      case 2: /* HVXC */
        self->m_aot = AOT_ER_HVXC;
        self->m_channelConfiguration = 1;
        break;
      case 3: /* xHE-AAC */
      {
        /* payload is MPEG conform -> no pseudo DRM AOT needed */
        self->m_aot = AOT_USAC;
      }
        switch (audioMode) {
          case 0: /* mono */
          case 2: /* stereo */
            /* codec specific config 8n bits */
            ErrorStatus = Drm_xHEAACStaticConfig(self, bs, audioMode, cb);
            break;
          default:
            ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
            goto bail;
        }
        break;
      default:
        ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
        self->m_aot = AOT_NONE;
        break;
    }

    if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
      goto bail;
    }
  }

bail:
  return (ErrorStatus);
}
