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

© Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/**************************** AAC decoder library ******************************

   Author(s):   Christian Griebel

   Description: Dynamic range control (DRC) decoder tool for AAC

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

#include "aacdec_drc.h"

#include "channelinfo.h"
#include "aac_rom.h"

#include "sbrdecoder.h"

/*
 * Dynamic Range Control
 */

/* For parameter conversion */
#define DRC_PARAMETER_BITS (7)
#define DRC_MAX_QUANT_STEPS (1 << DRC_PARAMETER_BITS)
#define DRC_MAX_QUANT_FACTOR (DRC_MAX_QUANT_STEPS - 1)
#define DRC_PARAM_QUANT_STEP \
  (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR))
#define DRC_PARAM_SCALE (1)
#define DRC_SCALING_MAX \
  ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127))

#define DRC_BLOCK_LEN (1024)
#define DRC_BAND_MULT (4)
#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT)

#define MAX_REFERENCE_LEVEL (127)

#define DRC_HEAVY_THRESHOLD_DB (10)

#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */

#define OFF 0
#define ON 1

static INT convert_drcParam(FIXP_DBL param_dbl) {
  /* converts an internal DRC boost/cut scaling factor in FIXP_DBL
     (which is downscaled by DRC_PARAM_SCALE)
     back to an integer value between 0 and 127. */
  LONG param_long;

  param_long = (LONG)param_dbl >> 7;
  param_long = param_long * (INT)DRC_MAX_QUANT_FACTOR;
  param_long >>= 31 - 7 - DRC_PARAM_SCALE - 1;
  param_long += 1; /* for rounding */
  param_long >>= 1;

  return (INT)param_long;
}

/*!
  \brief Initialize DRC information

  \self Handle of DRC info

  \return none
*/
void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
  CDrcParams *pParams;

  if (self == NULL) {
    return;
  }

  /* init control fields */
  self->enable = OFF;
  self->numThreads = 0;

  /* init params */
  pParams = &self->params;
  pParams->bsDelayEnable = 0;
  pParams->cut = FL2FXCONST_DBL(0.0f);
  pParams->usrCut = FL2FXCONST_DBL(0.0f);
  pParams->boost = FL2FXCONST_DBL(0.0f);
  pParams->usrBoost = FL2FXCONST_DBL(0.0f);
  pParams->targetRefLevel = 96;
  pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
  pParams->applyDigitalNorm = ON;
  pParams->applyHeavyCompression = OFF;
  pParams->usrApplyHeavyCompression = OFF;

  pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING;
  pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */

  self->update = 1;
  self->numOutChannels = 0;
  self->prevAacNumChannels = 0;

  /* initial program ref level = target ref level */
  self->progRefLevel = pParams->targetRefLevel;
  self->progRefLevelPresent = 0;
  self->presMode = -1;
  self->uniDrcPrecedence = 0;
}

/*!
  \brief Initialize DRC control data for one channel

  \self Handle of DRC info

  \return none
*/
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
  if (pDrcChData != NULL) {
    pDrcChData->expiryCount = 0;
    pDrcChData->numBands = 1;
    pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
    pDrcChData->drcValue[0] = 0;
    pDrcChData->drcInterpolationScheme = 0;
    pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
  }
}

/*!
  \brief  Set one single DRC parameter

  \self   Handle of DRC info.
  \param  Parameter to be set.
  \value  Value to be set.

  \return an error code.
*/
AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
                                         AACDEC_DRC_PARAM param, INT value) {
  AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;

  switch (param) {
    case DRC_CUT_SCALE:
      /* set attenuation scale factor */
      if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.usrCut = (FIXP_DBL)(
          (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
      self->update = 1;
      break;
    case DRC_BOOST_SCALE:
      /* set boost factor */
      if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.usrBoost = (FIXP_DBL)(
          (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
      self->update = 1;
      break;
    case TARGET_REF_LEVEL:
      if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      if (value < 0) {
        self->params.applyDigitalNorm = OFF;
        self->params.targetRefLevel = -1;
      } else {
        /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
        self->params.applyDigitalNorm = ON;
        if (self->params.targetRefLevel != (SCHAR)value) {
          self->params.targetRefLevel = (SCHAR)value;
          self->progRefLevel = (SCHAR)value; /* Always set the program reference
                                                level equal to the target level
                                                according to 4.5.2.7.3 of
                                                ISO/IEC 14496-3. */
        }
        self->update = 1;
      }
      break;
    case APPLY_NORMALIZATION:
      if ((value != OFF) && (value != ON)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      /* Store new parameter value */
      self->params.applyDigitalNorm = (UCHAR)value;
      break;
    case APPLY_HEAVY_COMPRESSION:
      if ((value != OFF) && (value != ON)) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      /* Store new parameter value */
      self->params.usrApplyHeavyCompression = (UCHAR)value;
      self->update = 1;
      break;
    case DEFAULT_PRESENTATION_MODE:
      if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED ||
          value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.defaultPresentationMode =
          (AACDEC_DRC_PARAMETER_HANDLING)value;
      self->update = 1;
      break;
    case ENCODER_TARGET_LEVEL:
      if (value > MAX_REFERENCE_LEVEL || value < 0) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.encoderTargetLevel = (UCHAR)value;
      self->update = 1;
      break;
    case DRC_BS_DELAY:
      if (value < 0 || value > 1) {
        return AAC_DEC_SET_PARAM_FAIL;
      }
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.bsDelayEnable = value;
      break;
    case DRC_DATA_EXPIRY_FRAME:
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
      break;
    case MAX_OUTPUT_CHANNELS:
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->numOutChannels = (INT)value;
      self->update = 1;
      break;
    case UNIDRC_PRECEDENCE:
      if (self == NULL) {
        return AAC_DEC_INVALID_HANDLE;
      }
      self->uniDrcPrecedence = (UCHAR)value;
      break;
    default:
      return AAC_DEC_SET_PARAM_FAIL;
  } /* switch(param) */

  return ErrorStatus;
}

static int parseExcludedChannels(UINT *excludedChnsMask,
                                 HANDLE_FDK_BITSTREAM bs) {
  UINT excludeMask = 0;
  UINT i, j;
  int bitCnt = 9;

  for (i = 0, j = 1; i < 7; i++, j <<= 1) {
    if (FDKreadBits(bs, 1)) {
      excludeMask |= j;
    }
  }

  /* additional_excluded_chns */
  while (FDKreadBits(bs, 1)) {
    for (i = 0; i < 7; i++, j <<= 1) {
      if (FDKreadBits(bs, 1)) {
        excludeMask |= j;
      }
    }
    bitCnt += 9;
    FDK_ASSERT(j < (UINT)-1);
  }

  *excludedChnsMask = excludeMask;

  return (bitCnt);
}

/*!
  \brief Save DRC payload bitstream position

  \self Handle of DRC info
  \bs Handle of FDK bitstream

  \return The number of DRC payload bits
*/
int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs,
                              AACDEC_DRC_PAYLOAD_TYPE type) {
  UINT bsStartPos;
  int i, numBands = 1, bitCnt = 0;

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

  bsStartPos = FDKgetValidBits(bs);

  switch (type) {
    case MPEG_DRC_EXT_DATA: {
      bitCnt = 4;

      if (FDKreadBits(bs, 1)) { /* pce_tag_present */
        FDKreadBits(bs, 8);     /* pce_instance_tag + drc_tag_reserved_bits */
        bitCnt += 8;
      }

      if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
        FDKreadBits(bs, 7);     /* exclude mask [0..7] */
        bitCnt += 8;
        while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
          FDKreadBits(bs, 7);        /* exclude mask [x..y] */
          bitCnt += 8;
        }
      }

      if (FDKreadBits(bs, 1)) {         /* drc_bands_present */
        numBands += FDKreadBits(bs, 4); /* drc_band_incr */
        FDKreadBits(bs, 4);             /* reserved */
        bitCnt += 8;
        for (i = 0; i < numBands; i++) {
          FDKreadBits(bs, 8); /* drc_band_top[i] */
          bitCnt += 8;
        }
      }

      if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
        FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
        bitCnt += 8;
      }

      for (i = 0; i < numBands; i++) {
        FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
        bitCnt += 8;
      }

      if ((self->numPayloads < MAX_DRC_THREADS) &&
          ((INT)FDKgetValidBits(bs) >= 0)) {
        self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
      }
    } break;

    case DVB_DRC_ANC_DATA:
      bitCnt += 8;
      /* check sync word */
      if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
        int dmxLevelsPresent, compressionPresent;
        int coarseGrainTcPresent, fineGrainTcPresent;

        /* bs_info field */
        FDKreadBits(
            bs,
            8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
        bitCnt += 8;

        /* Evaluate ancillary_data_status */
        FDKreadBits(bs, 3); /* reserved, set to 0 */
        dmxLevelsPresent =
            FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
        FDKreadBits(bs, 1);     /* reserved, set to 0 */
        compressionPresent =
            FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
        coarseGrainTcPresent =
            FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
        fineGrainTcPresent =
            FDKreadBits(bs, 1); /* fine_grain_timecode_status */
        bitCnt += 8;

        /* MPEG4 downmixing levels */
        if (dmxLevelsPresent) {
          FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
          bitCnt += 8;
        }
        /* audio coding mode and compression status */
        if (compressionPresent) {
          FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
          bitCnt += 16;
        }
        /* coarse grain timecode */
        if (coarseGrainTcPresent) {
          FDKreadBits(bs, 16); /* coarse_grain_timecode */
          bitCnt += 16;
        }
        /* fine grain timecode */
        if (fineGrainTcPresent) {
          FDKreadBits(bs, 16); /* fine_grain_timecode */
          bitCnt += 16;
        }
        if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
          self->dvbAncDataPosition = bsStartPos;
          self->dvbAncDataAvailable = 1;
        }
      }
      break;

    default:
      break;
  }

  return (bitCnt);
}

/*!
  \brief Parse DRC parameters from bitstream

  \bs Handle of FDK bitstream (in)
  \pDrcBs Pointer to DRC payload data container (out)
  \payloadPosition Bitstream position of MPEG DRC data chunk (in)

  \return Flag telling whether new DRC data has been found or not.
*/
static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs,
                               UINT payloadPosition) {
  int i, numBands;

  /* Move to the beginning of the DRC payload field */
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);

  /* pce_tag_present */
  if (FDKreadBits(bs, 1)) {
    pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
    /* only one program supported */
    FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
  } else {
    pDrcBs->pceInstanceTag = -1; /* not present */
  }

  if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
    /* get excluded_chn_mask */
    parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
  } else {
    pDrcBs->excludedChnsMask = 0;
  }

  numBands = 1;
  if (FDKreadBits(bs, 1)) /* drc_bands_present */
  {
    /* get band_incr */
    numBands += FDKreadBits(bs, 4); /* drc_band_incr */
    pDrcBs->channelData.drcInterpolationScheme =
        FDKreadBits(bs, 4); /* drc_interpolation_scheme */
    /* band_top */
    for (i = 0; i < numBands; i++) {
      pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
    }
  } else {
    pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
                                     1; /* ... comprising the whole spectrum. */
    ;
  }

  pDrcBs->channelData.numBands = numBands;

  if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
  {
    pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
    FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
  } else {
    pDrcBs->progRefLevel = -1;
  }

  for (i = 0; i < numBands; i++) {
    pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
                                      << 7; /* dyn_rng_sgn[i] */
    pDrcBs->channelData.drcValue[i] |=
        FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
  }

  /* Set DRC payload type */
  pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;

  return (1);
}

/*!
  \brief Parse heavy compression value transported in DSEs of DVB streams with
  MPEG-4 content.

  \bs Handle of FDK bitstream (in)
  \pDrcBs Pointer to DRC payload data container (out)
  \payloadPosition Bitstream position of DVB ancillary data chunk

  \return Flag telling whether new DRC data has been found or not.
*/
#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */

static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
                                         CDrcPayload *pDrcBs,
                                         UINT payloadPosition) {
  int foundDrcData = 0;
  int dmxLevelsPresent, compressionPresent;

  /* Move to the beginning of the DRC payload field */
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);

  /* Sanity checks */
  if (FDKgetValidBits(bs) < 24) {
    return 0;
  }

  /* Check sync word */
  if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
    return 0;
  }

  /* Evaluate bs_info field */
  if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
    /* No MPEG-4 audio data */
    return 0;
  }
  FDKreadBits(bs, 2);                    /* dolby_surround_mode */
  pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
  FDKreadBits(bs, 1);                    /* stereo_downmix_mode */
  if (FDKreadBits(bs, 1) != 0) {         /* reserved, set to 0 */
    return 0;
  }

  /* Evaluate ancillary_data_status */
  if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
    return 0;
  }
  dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
  /*extensionPresent =*/FDKreadBits(bs,
                                    1); /* ancillary_data_extension_status; */
  compressionPresent =
      FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
  /*coarseGrainTcPresent =*/FDKreadBits(bs,
                                        1); /* coarse_grain_timecode_status */
  /*fineGrainTcPresent   =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */

  if (dmxLevelsPresent) {
    FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
  }

  /* audio_coding_mode_and_compression_status */
  if (compressionPresent) {
    UCHAR compressionOn, compressionValue;

    /* audio_coding_mode */
    if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
      return 0;
    }
    compressionOn = (UCHAR)FDKreadBits(bs, 1);    /* compression_on */
    compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */

    if (compressionOn) {
      /* A compression value is available so store the data just like MPEG DRC
       * data */
      pDrcBs->channelData.numBands = 1; /* One band ... */
      pDrcBs->channelData.drcValue[0] =
          compressionValue; /* ... with one value ... */
      pDrcBs->channelData.bandTop[0] =
          DRC_BLOCK_LEN_DIV_BAND_MULT -
          1; /* ... comprising the whole spectrum. */
      ;
      pDrcBs->pceInstanceTag = -1; /* Not present */
      pDrcBs->progRefLevel = -1;   /* Not present */
      pDrcBs->channelData.drcDataType =
          DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
      foundDrcData = 1;
    }
  }

  return (foundDrcData);
}

/*
 * Extract DRC payload from bitstream and map it to channels.
 *   Valid return values are:
 *     -1 : An unexpected error occured.
 *      0 : No error and no valid DRC data available.
 *      1 : No error and valid DRC data has been mapped.
 */
static int aacDecoder_drcExtractAndMap(
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
    UCHAR pceInstanceTag,
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
                               canonical channel index */
    int validChannels) {
  CDrcPayload threadBs[MAX_DRC_THREADS];
  CDrcPayload *validThreadBs[MAX_DRC_THREADS];
  CDrcParams *pParams;
  UINT backupBsPosition;
  int result = 0;
  int i, thread, validThreads = 0;

  FDK_ASSERT(self != NULL);
  FDK_ASSERT(hBs != NULL);
  FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);

  pParams = &self->params;

  self->numThreads = 0;
  backupBsPosition = FDKgetValidBits(hBs);

  for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
       i++) {
    /* Init payload data chunk. The memclear is very important because it
       initializes the most values. Without it the module wouldn't work properly
       or crash. */
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
    threadBs[self->numThreads].channelData.bandTop[0] =
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;

    /* Extract payload */
    self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
                                            self->drcPayloadPosition[i]);
  }
  self->numPayloads = 0;

  if (self->dvbAncDataAvailable &&
      self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression
                                               payload thread if available. */

    /* Init payload data chunk. The memclear is very important because it
       initializes the most values. Without it the module wouldn't work properly
       or crash. */
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
    threadBs[self->numThreads].channelData.bandTop[0] =
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;

    /* Extract payload */
    self->numThreads += aacDecoder_drcReadCompression(
        hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
  }
  self->dvbAncDataAvailable = 0;

  /* Reset the bitbufffer */
  FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition);

  /* calculate number of valid bits in excl_chn_mask */

  /* coupling channels not supported */

  /* check for valid threads */
  for (thread = 0; thread < self->numThreads; thread++) {
    CDrcPayload *pThreadBs = &threadBs[thread];
    int numExclChns = 0;

    switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
      default:
        continue;
      case MPEG_DRC_EXT_DATA:
      case DVB_DRC_ANC_DATA:
        break;
    }

    if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
      if (pThreadBs->pceInstanceTag != pceInstanceTag) {
        continue; /* don't accept */
      }
    }

    /* calculate number of excluded channels */
    if (pThreadBs->excludedChnsMask > 0) {
      INT exclMask = pThreadBs->excludedChnsMask;
      int ch;
      for (ch = 0; ch < validChannels; ch++) {
        numExclChns += exclMask & 0x1;
        exclMask >>= 1;
      }
    }
    if (numExclChns < validChannels) {
      validThreadBs[validThreads] = pThreadBs;
      validThreads++;
    }
  }

  /* map DRC bitstream information onto DRC channel information */
  for (thread = 0; thread < validThreads; thread++) {
    CDrcPayload *pThreadBs = validThreadBs[thread];
    INT exclMask = pThreadBs->excludedChnsMask;
    AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
        (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
    int ch;

    /* last progRefLevel transmitted is the one that is used
     * (but it should really only be transmitted once per block!)
     */
    if (pThreadBs->progRefLevel >= 0) {
      self->progRefLevel = pThreadBs->progRefLevel;
      self->progRefLevelPresent = 1;
      self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
    }

    if (drcPayloadType == DVB_DRC_ANC_DATA) {
      /* Announce the presentation mode of this valid thread. */
      self->presMode = pThreadBs->presMode;
    }

    /* SCE, CPE and LFE */
    for (ch = 0; ch < validChannels; ch++) {
      AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
      int mapedChannel = channelMapping[ch];

      if ((mapedChannel >= validChannels) ||
          ((exclMask & (1 << mapedChannel)) != 0))
        continue;

      if ((pParams->expiryFrame <= 0) ||
          (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
           pParams->expiryFrame)) {
        prvPayloadType =
            (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
                ->drcData.drcDataType;
      }
      if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
           (prvPayloadType != DVB_DRC_ANC_DATA)) ||
          ((drcPayloadType == DVB_DRC_ANC_DATA) &&
           (pParams->applyHeavyCompression ==
            ON))) { /* copy thread to channel */
        pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
        result = 1;
      }
    }
    /* CCEs not supported by now */
  }

  /* Increment and check expiry counter for the program reference level: */
  if ((pParams->expiryFrame > 0) &&
      (self->prlExpiryCount++ >
       pParams->expiryFrame)) { /* The program reference level is too old, so
                                   set it back to the target level. */
    self->progRefLevelPresent = 0;
    self->progRefLevel = pParams->targetRefLevel;
    self->prlExpiryCount = 0;
  }

  return result;
}

void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
                         CAacDecoderChannelInfo *pAacDecoderChannelInfo,
                         CDrcChannelData *pDrcChData, FIXP_DBL *extGain,
                         int ch, /* needed only for SBR */
                         int aacFrameSize, int bSbrPresent) {
  int band, bin, numBands;
  int bottom = 0;
  int modifyBins = 0;

  FIXP_DBL max_mantissa;
  INT max_exponent;

  FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
  INT norm_exponent = 1;

  FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
  INT fact_exponent[MAX_DRC_BANDS];

  CDrcParams *pParams = &self->params;

  FIXP_DBL *pSpectralCoefficient =
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
  SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;

  int winSeq = pIcsInfo->WindowSequence;

  /* Increment and check expiry counter */
  if ((pParams->expiryFrame > 0) &&
      (++pDrcChData->expiryCount >
       pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */
    aacDecoder_drcInitChannelData(pDrcChData);
  }

  if (self->enable != ON) {
    sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
    if (extGain != NULL) {
      INT gainScale = (INT)*extGain;
      /* The gain scaling must be passed to the function in the buffer pointed
       * on by extGain. */
      if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
        *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
      } else {
        FDK_ASSERT(0);
      }
    }
    return;
  }

  numBands = pDrcChData->numBands;

  /* If program reference normalization is done in the digital domain,
  modify factor to perform normalization.  prog_ref_level can
  alternatively be passed to the system for modification of the level in
  the analog domain.  Analog level modification avoids problems with
  reduced DAC SNR (if signal is attenuated) or clipping (if signal is
  boosted) */

  if (pParams->targetRefLevel >= 0) {
    /* 0.5^((targetRefLevel - progRefLevel)/24) */
    norm_mantissa =
        fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
               0,
               (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
                          (INT)(pParams->targetRefLevel - self->progRefLevel)),
               3, &norm_exponent);
  }
  /* Always export the normalization gain (if possible). */
  if (extGain != NULL) {
    INT gainScale = (INT)*extGain;
    /* The gain scaling must be passed to the function in the buffer pointed on
     * by extGain. */
    if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
      *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
    } else {
      FDK_ASSERT(0);
    }
  }
  if (self->params.applyDigitalNorm == OFF) {
    /* Reset normalization gain since this module must not apply it */
    norm_mantissa = FL2FXCONST_DBL(0.5f);
    norm_exponent = 1;
  }

  /* calc scale factors */
  for (band = 0; band < numBands; band++) {
    UCHAR drcVal = pDrcChData->drcValue[band];

    fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
    fact_exponent[band] = 1;

    if ((pParams->applyHeavyCompression == ON) &&
        ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
         DVB_DRC_ANC_DATA)) {
      INT compressionFactorVal_e;
      int valX, valY;

      valX = drcVal >> 4;
      valY = drcVal & 0x0F;

      /* calculate the unscaled heavy compression factor.
         compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
         range: -48.166 dB to 48.164 dB */
      if (drcVal != 0x7F) {
        fact_mantissa[band] = fPowInt(
            FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
            0, valY, &compressionFactorVal_e);

        /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
        fact_mantissa[band] =
            fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);

        fact_exponent[band] =
            DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
      }
    } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
               MPEG_DRC_EXT_DATA) {
      /* apply the scaled dynamic range control words to factor.
       * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
       * then there is no dynamic range compression
       *
       * if pDrcChData->drcSgn[band] is
       *  1 then gain is < 1 :  factor = 2^(-self->cut   *
       * pDrcChData->drcMag[band] / 24) 0 then gain is > 1 :  factor = 2^(
       * self->boost * pDrcChData->drcMag[band] / 24)
       */

      if ((drcVal & 0x7F) > 0) {
        FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;

        fact_mantissa[band] = f2Pow(
            (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
                       (drcVal & 0x7F)),
            3 + DRC_PARAM_SCALE, &fact_exponent[band]);
      }
    }

    fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
    fact_exponent[band] += norm_exponent;

  } /* end loop over bands */

  /* normalizations */
  {
    int res;

    max_mantissa = FL2FXCONST_DBL(0.0f);
    max_exponent = 0;
    for (band = 0; band < numBands; band++) {
      max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
      max_exponent = fixMax(max_exponent, fact_exponent[band]);
    }

    /* left shift factors to gain accurancy */
    res = CntLeadingZeros(max_mantissa) - 1;

    /* above topmost DRC band gain factor is 1 */
    if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
      res = 0;

    if (res > 0) {
      res = fixMin(res, max_exponent);
      max_exponent -= res;

      for (band = 0; band < numBands; band++) {
        fact_mantissa[band] <<= res;
        fact_exponent[band] -= res;
      }
    }

    /* normalize magnitudes to one scale factor */
    for (band = 0; band < numBands; band++) {
      if (fact_exponent[band] < max_exponent) {
        fact_mantissa[band] >>= max_exponent - fact_exponent[band];
      }
      if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
        modifyBins = 1;
      }
    }
    if (max_exponent != 1) {
      modifyBins = 1;
    }
  }

  /*  apply factor to spectral lines
   *  short blocks must take care that bands fall on
   *  block boundaries!
   */
  if (!bSbrPresent) {
    bottom = 0;

    if (!modifyBins) {
      /* We don't have to modify the spectral bins because the fractional part
         of all factors is 0.5. In order to keep accurancy we don't apply the
         factor but decrease the exponent instead. */
      max_exponent -= 1;
    } else {
      for (band = 0; band < numBands; band++) {
        int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
                         aacFrameSize); /* ... * DRC_BAND_MULT; */

        for (bin = bottom; bin < top; bin++) {
          pSpectralCoefficient[bin] =
              fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
        }

        bottom = top;
      }
    }

    /* above topmost DRC band gain factor is 1 */
    if (max_exponent > 0) {
      for (bin = bottom; bin < aacFrameSize; bin += 1) {
        pSpectralCoefficient[bin] >>= max_exponent;
      }
    }

    /* adjust scaling */
    pSpecScale[0] += max_exponent;

    if (winSeq == BLOCK_SHORT) {
      int win;
      for (win = 1; win < 8; win++) {
        pSpecScale[win] += max_exponent;
      }
    }
  } else {
    HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
    numBands = pDrcChData->numBands;

    /* feed factors into SBR decoder for application in QMF domain. */
    sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
                              max_exponent, pDrcChData->drcInterpolationScheme,
                              winSeq, pDrcChData->bandTop);
  }

  return;
}

/*
 * DRC parameter and presentation mode handling
 */
static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,
                                            INT aacNumChannels,
                                            SCHAR prevDrcProgRefLevel,
                                            SCHAR prevDrcPresMode) {
  int isDownmix, isMonoDownmix, isStereoDownmix;
  int dDmx, dHr;
  AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
  CDrcParams *p;

  FDK_ASSERT(self != NULL);

  p = &self->params;

  if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;

  if (self->presMode != prevDrcPresMode) self->update = 1;

  if (self->prevAacNumChannels != aacNumChannels) self->update = 1;

  /* return if no relevant parameter has changed */
  if (!self->update) {
    return;
  }

  /* derive downmix property. aacNumChannels: number of channels in aac stream,
   * numOutChannels: number of output channels */
  isDownmix = (aacNumChannels > self->numOutChannels);
  isDownmix = (isDownmix && (self->numOutChannels > 0));
  isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
  isStereoDownmix = (isDownmix && (self->numOutChannels == 2));

  if ((self->presMode == 1) || (self->presMode == 2)) {
    drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
  } else { /* no presentation mode -> use parameter handling specified by
              AAC_DRC_DEFAULT_PRESENTATION_MODE */
    drcParameterHandling = p->defaultPresentationMode;
  }

  /* by default, do as desired */
  p->cut = p->usrCut;
  p->boost = p->usrBoost;
  p->applyHeavyCompression = p->usrApplyHeavyCompression;

  switch (drcParameterHandling) {
    case DISABLED_PARAMETER_HANDLING:
    default:
      /* use drc parameters as requested */
      break;

    case ENABLED_PARAMETER_HANDLING:
      /* dDmx: estimated headroom reduction due to downmix, format: -1/4*dB
         dDmx = floor(-4*20*log10(aacNumChannels/numOutChannels)) */
      if (isDownmix) {
        FIXP_DBL dmxTmp;
        int e_log, e_mult;
        dmxTmp = fDivNorm(self->numOutChannels,
                          aacNumChannels); /* inverse division ->
                                              negative sign after
                                              logarithm */
        dmxTmp = fLog2(dmxTmp, 0, &e_log);
        dmxTmp = fMultNorm(
            dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)),
            &e_mult); /* e = e_log + e_mult + 5 */
        dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1));
      } else {
        dDmx = 0;
      }

      /* dHr: Full estimated (decoder) headroom reduction due to loudness
       * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */
      if (p->targetRefLevel >= 0) { /* if target level is provided */
        dHr = p->targetRefLevel + dDmx - self->progRefLevel;
      } else {
        dHr = dDmx;
      }

      if (dHr < 0) { /* if headroom is reduced */
        /* Use compression, but as little as possible. */
        /* eHr: Headroom provided by encoder, format: -1/4 dB */
        int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0);
        if (eHr <
            dHr) { /* if encoder provides more headroom than decoder needs */
          /* derive scaling of light DRC */
          FIXP_DBL calcFactor_norm;
          INT calcFactor; /* fraction of DRC gains that is minimally needed for
                             clipping prevention */
          calcFactor_norm =
              fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */
          calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE;
          /* quantize to 128 steps */
          calcFactor = convert_drcParam(
              calcFactor_norm); /* convert to integer value between 0 and 127 */
          calcFactor_norm = (FIXP_DBL)(
              (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor);
          p->cut = (calcFactor_norm > p->cut)
                       ? calcFactor_norm
                       : p->cut; /* use calcFactor_norm as lower limit */
        } else {
          /* encoder provides equal or less headroom than decoder needs */
          /* the time domain limiter must always be active in this case. It is
           * assumed that the framework activates it by default */
          p->cut = DRC_SCALING_MAX;
          if ((dHr - eHr) <=
              -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if
                                                headroom deficit is equal or
                                                higher than
                                                DRC_HEAVY_THRESHOLD_DB */
            p->applyHeavyCompression = ON;
          }
        }
      } else { /* dHr >= 0 */
        /* no restrictions required, as headroom is not reduced. */
        /* p->cut = p->usrCut; */
      }
      break;

      /* presentation mode 1 and 2 according to ETSI TS 101 154:
         Digital Video Broadcasting (DVB); Specification for the use of Video
         and Audio Coding in Broadcasting Applications based on the MPEG-2
         Transport Stream, section C.5.4., "Decoding", and Table C.33. Also
         according to amendment 4 to ISO/IEC 14496-3, section 4.5.2.14.2.4, and
         Table AMD4.11. ISO DRC            -> applyHeavyCompression = OFF (Use
         light compression, MPEG-style) Compression_value  ->
         applyHeavyCompression = ON  (Use heavy compression, DVB-style) scaling
         restricted -> p->cut = DRC_SCALING_MAX */

    case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
      if ((p->targetRefLevel >= 0) &&
          (p->targetRefLevel <
           124)) { /* if target level is provided and > -31 dB */
        /* playback up to -23 dB */
        p->applyHeavyCompression = ON;
      } else { /* target level <= -31 dB or not provided */
        /* playback -31 dB */
        if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
          p->cut = DRC_SCALING_MAX;
        }
      }
      break;

    case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
      if ((p->targetRefLevel >= 0) &&
          (p->targetRefLevel <
           124)) { /* if target level is provided and > -31 dB */
        /* playback up to -23 dB */
        if (isMonoDownmix) { /* if mono downmix */
          p->applyHeavyCompression = ON;
        } else {
          p->applyHeavyCompression = OFF;
          p->cut = DRC_SCALING_MAX;
        }
      } else { /* target level <= -31 dB or not provided */
        /* playback -31 dB */
        p->applyHeavyCompression = OFF;
        if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
          p->cut = DRC_SCALING_MAX;
        }
      }
      break;
  } /*  switch (drcParameterHandling) */

  /* With heavy compression, there is no scaling.
     Scaling factors are set for notification only. */
  if (p->applyHeavyCompression == ON) {
    p->boost = DRC_SCALING_MAX;
    p->cut = DRC_SCALING_MAX;
  }

  /* switch on/off processing */
  self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
                  (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
  self->enable = (self->enable && !self->uniDrcPrecedence);

  self->prevAacNumChannels = aacNumChannels;
  self->update = 0;
}

/*
 * Prepare DRC processing
 *   Valid return values are:
 *     -1 : An unexpected error occured.
 *      0 : No error and no valid DRC data available.
 *      1 : No error and valid DRC data has been mapped.
 */
int aacDecoder_drcProlog(
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
    UCHAR pceInstanceTag,
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
                               canonical channel index */
    int validChannels) {
  int result = 0;

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

  if (!self->params.bsDelayEnable) {
    /* keep previous progRefLevel and presMode for update flag in
     * drcParameterHandling */
    INT prevPRL, prevPM = 0;
    prevPRL = self->progRefLevel;
    prevPM = self->presMode;

    result = aacDecoder_drcExtractAndMap(
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
        validChannels);

    if (result < 0) {
      return result;
    }

    /* Drc parameter handling */
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
  }

  return result;
}

/*
 * Finalize DRC processing
 *   Valid return values are:
 *     -1 : An unexpected error occured.
 *      0 : No error and no valid DRC data available.
 *      1 : No error and valid DRC data has been mapped.
 */
int aacDecoder_drcEpilog(
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
    UCHAR pceInstanceTag,
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
                               canonical channel index */
    int validChannels) {
  int result = 0;

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

  if (self->params.bsDelayEnable) {
    /* keep previous progRefLevel and presMode for update flag in
     * drcParameterHandling */
    INT prevPRL, prevPM = 0;
    prevPRL = self->progRefLevel;
    prevPM = self->presMode;

    result = aacDecoder_drcExtractAndMap(
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
        validChannels);

    if (result < 0) {
      return result;
    }

    /* Drc parameter handling */
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
  }

  return result;
}

/*
 * Export relevant metadata info from bitstream payload.
 */
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
                           SCHAR *pProgRefLevel) {
  if (self != NULL) {
    if (pPresMode != NULL) {
      *pPresMode = self->presMode;
    }
    if (pProgRefLevel != NULL) {
      if (self->progRefLevelPresent) {
        *pProgRefLevel = self->progRefLevel;
      } else {
        *pProgRefLevel = -1;
      }
    }
  }
}
