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

/**************************** AAC encoder library ******************************

   Author(s):   M. Werner

   Description: Bitstream encoder

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

#include "bitenc.h"
#include "bit_cnt.h"
#include "dyn_bits.h"
#include "qc_data.h"
#include "interface.h"
#include "aacEnc_ram.h"

#include "tpenc_lib.h"

#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */

static const int globalGainOffset = 100;
static const int icsReservedBit = 0;
static const int noiseOffset = 90;

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

    functionname: FDKaacEnc_encodeSpectralData
    description:  encode spectral data
    returns:      the number of written bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset,
                                        SECTION_DATA *sectionData,
                                        SHORT *quantSpectrum,
                                        HANDLE_FDK_BITSTREAM hBitStream) {
  INT i, sfb;
  INT dbgVal = FDKgetValidBits(hBitStream);

  for (i = 0; i < sectionData->noOfSections; i++) {
    if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) {
      /* huffencode spectral data for this huffsection */
      INT tmp = sectionData->huffsection[i].sfbStart +
                sectionData->huffsection[i].sfbCnt;
      for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) {
        FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb],
                             sfbOffset[sfb + 1] - sfbOffset[sfb],
                             sectionData->huffsection[i].codeBook, hBitStream);
      }
    }
  }
  return (FDKgetValidBits(hBitStream) - dbgVal);
}

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

    functionname:FDKaacEnc_encodeGlobalGain
    description: encodes Global Gain (common scale factor)
    returns:     the number of static bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac,
                                      HANDLE_FDK_BITSTREAM hBitStream,
                                      INT mdctScale) {
  if (hBitStream != NULL) {
    FDKwriteBits(hBitStream,
                 globalGain - scalefac + globalGainOffset -
                     4 * (LOG_NORM_PCM - mdctScale),
                 8);
  }
  return (8);
}

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

    functionname:FDKaacEnc_encodeIcsInfo
    description: encodes Ics Info
    returns:     the number of static bits
    input:
    output:

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

static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape,
                                   INT groupingMask, INT maxSfbPerGroup,
                                   HANDLE_FDK_BITSTREAM hBitStream,
                                   UINT syntaxFlags) {
  INT statBits;

  if (blockType == SHORT_WINDOW) {
    statBits = 8 + TRANS_FAC - 1;
  } else {
    if (syntaxFlags & AC_ELD) {
      statBits = 6;
    } else {
      statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
    }
  }

  if (hBitStream != NULL) {
    if (!(syntaxFlags & AC_ELD)) {
      FDKwriteBits(hBitStream, icsReservedBit, 1);
      FDKwriteBits(hBitStream, blockType, 2);
      FDKwriteBits(hBitStream,
                   (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1);
    }

    switch (blockType) {
      case LONG_WINDOW:
      case START_WINDOW:
      case STOP_WINDOW:
        FDKwriteBits(hBitStream, maxSfbPerGroup, 6);

        if (!(syntaxFlags &
              (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */
          /* No predictor data present */
          FDKwriteBits(hBitStream, 0, 1);
        }
        break;

      case SHORT_WINDOW:
        FDKwriteBits(hBitStream, maxSfbPerGroup, 4);

        /* Write grouping bits */
        FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1);
        break;
    }
  }

  return (statBits);
}

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

    functionname: FDKaacEnc_encodeSectionData
    description:  encode section data (common Huffman codebooks for adjacent
                  SFB's)
    returns:      none
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
                                       HANDLE_FDK_BITSTREAM hBitStream,
                                       UINT useVCB11) {
  if (hBitStream != NULL) {
    INT sectEscapeVal = 0, sectLenBits = 0;
    INT sectLen;
    INT i;
    INT dbgVal = FDKgetValidBits(hBitStream);
    INT sectCbBits = 4;

    switch (sectionData->blockType) {
      case LONG_WINDOW:
      case START_WINDOW:
      case STOP_WINDOW:
        sectEscapeVal = SECT_ESC_VAL_LONG;
        sectLenBits = SECT_BITS_LONG;
        break;

      case SHORT_WINDOW:
        sectEscapeVal = SECT_ESC_VAL_SHORT;
        sectLenBits = SECT_BITS_SHORT;
        break;
    }

    for (i = 0; i < sectionData->noOfSections; i++) {
      INT codeBook = sectionData->huffsection[i].codeBook;

      FDKwriteBits(hBitStream, codeBook, sectCbBits);

      {
        sectLen = sectionData->huffsection[i].sfbCnt;

        while (sectLen >= sectEscapeVal) {
          FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits);
          sectLen -= sectEscapeVal;
        }
        FDKwriteBits(hBitStream, sectLen, sectLenBits);
      }
    }
    return (FDKgetValidBits(hBitStream) - dbgVal);
  }
  return (0);
}

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

    functionname: FDKaacEnc_encodeScaleFactorData
    description:  encode DPCM coded scale factors
    returns:      none
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb,
                                           SECTION_DATA *sectionData,
                                           INT *scalefac,
                                           HANDLE_FDK_BITSTREAM hBitStream,
                                           INT *RESTRICT noiseNrg,
                                           const INT *isScale, INT globalGain) {
  if (hBitStream != NULL) {
    INT i, j, lastValScf, deltaScf;
    INT deltaPns;
    INT lastValPns = 0;
    INT noisePCMFlag = TRUE;
    INT lastValIs;

    INT dbgVal = FDKgetValidBits(hBitStream);

    lastValScf = scalefac[sectionData->firstScf];
    lastValPns = globalGain - scalefac[sectionData->firstScf] +
                 globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset;
    lastValIs = 0;

    for (i = 0; i < sectionData->noOfSections; i++) {
      if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
        if ((sectionData->huffsection[i].codeBook ==
             CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
            (sectionData->huffsection[i].codeBook ==
             CODE_BOOK_IS_IN_PHASE_NO)) {
          INT sfbStart = sectionData->huffsection[i].sfbStart;
          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
          for (j = sfbStart; j < tmp; j++) {
            INT deltaIs = isScale[j] - lastValIs;
            lastValIs = isScale[j];
            if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) {
              return (1);
            }
          } /* sfb */
        } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
          INT sfbStart = sectionData->huffsection[i].sfbStart;
          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
          for (j = sfbStart; j < tmp; j++) {
            deltaPns = noiseNrg[j] - lastValPns;
            lastValPns = noiseNrg[j];

            if (noisePCMFlag) {
              FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)),
                           PNS_PCM_BITS);
              noisePCMFlag = FALSE;
            } else {
              if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) {
                return (1);
              }
            }
          } /* sfb */
        } else {
          INT tmp = sectionData->huffsection[i].sfbStart +
                    sectionData->huffsection[i].sfbCnt;
          for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
            /*
              check if we can repeat the last value to save bits
            */
            if (maxValueInSfb[j] == 0)
              deltaScf = 0;
            else {
              deltaScf = -(scalefac[j] - lastValScf);
              lastValScf = scalefac[j];
            }
            if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) {
              return (1);
            }
          } /* sfb */
        }   /* code scalefactor */
      }     /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
    }       /* section loop */

    return (FDKgetValidBits(hBitStream) - dbgVal);
  } /* if (hBitStream != NULL) */

  return (0);
}

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

    functionname:encodeMsInfo
    description: encodes MS-Stereo Info
    returns:     the number of static bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb,
                                  INT msDigest, INT *jsFlags,
                                  HANDLE_FDK_BITSTREAM hBitStream) {
  INT sfb, sfbOff, msBits = 0;

  if (hBitStream != NULL) {
    switch (msDigest) {
      case MS_NONE:
        FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2);
        msBits += 2;
        break;

      case MS_ALL:
        FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2);
        msBits += 2;
        break;

      case MS_SOME:
        FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2);
        msBits += 2;
        for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
          for (sfb = 0; sfb < maxSfb; sfb++) {
            if (jsFlags[sfbOff + sfb] & MS_ON) {
              FDKwriteBits(hBitStream, 1, 1);
            } else {
              FDKwriteBits(hBitStream, 0, 1);
            }
            msBits += 1;
          }
        }
        break;
    }
  } else {
    msBits += 2;
    if (msDigest == MS_SOME) {
      for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
        for (sfb = 0; sfb < maxSfb; sfb++) {
          msBits += 1;
        }
      }
    }
  }
  return (msBits);
}

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

    functionname: FDKaacEnc_encodeTnsDataPresent
    description:  encode TNS data (filter order, coeffs, ..)
    returns:      the number of static bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType,
                                          HANDLE_FDK_BITSTREAM hBitStream) {
  if ((hBitStream != NULL) && (tnsInfo != NULL)) {
    INT i, tnsPresent = 0;
    INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);

    for (i = 0; i < numOfWindows; i++) {
      if (tnsInfo->numOfFilters[i] != 0) {
        tnsPresent = 1;
        break;
      }
    }

    if (tnsPresent == 0) {
      FDKwriteBits(hBitStream, 0, 1);
    } else {
      FDKwriteBits(hBitStream, 1, 1);
    }
  }
  return (1);
}

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

    functionname: FDKaacEnc_encodeTnsData
    description:  encode TNS data (filter order, coeffs, ..)
    returns:      the number of static bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType,
                                   HANDLE_FDK_BITSTREAM hBitStream) {
  INT tnsBits = 0;

  if (tnsInfo != NULL) {
    INT i, j, k;
    INT tnsPresent = 0;
    INT coefBits;
    INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);

    for (i = 0; i < numOfWindows; i++) {
      if (tnsInfo->numOfFilters[i] != 0) {
        tnsPresent = 1;
      }
    }

    if (hBitStream != NULL) {
      if (tnsPresent == 1) { /* there is data to be written*/
        for (i = 0; i < numOfWindows; i++) {
          FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i],
                       (blockType == SHORT_WINDOW ? 1 : 2));
          tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
          if (tnsInfo->numOfFilters[i]) {
            FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1);
            tnsBits += 1;
          }
          for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
            FDKwriteBits(hBitStream, tnsInfo->length[i][j],
                         (blockType == SHORT_WINDOW ? 4 : 6));
            tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
            FDK_ASSERT(tnsInfo->order[i][j] <= 12);
            FDKwriteBits(hBitStream, tnsInfo->order[i][j],
                         (blockType == SHORT_WINDOW ? 3 : 5));
            tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
            if (tnsInfo->order[i][j]) {
              FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1);
              tnsBits += 1; /*direction*/
              if (tnsInfo->coefRes[i] == 4) {
                coefBits = 3;
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
                  if (tnsInfo->coef[i][j][k] > 3 ||
                      tnsInfo->coef[i][j][k] < -4) {
                    coefBits = 4;
                    break;
                  }
                }
              } else {
                coefBits = 2;
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
                  if (tnsInfo->coef[i][j][k] > 1 ||
                      tnsInfo->coef[i][j][k] < -2) {
                    coefBits = 3;
                    break;
                  }
                }
              }
              FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]),
                           1); /*coef_compres*/
              tnsBits += 1;    /*coef_compression */
              for (k = 0; k < tnsInfo->order[i][j]; k++) {
                static const INT rmask[] = {0, 1, 3, 7, 15};
                FDKwriteBits(hBitStream,
                             tnsInfo->coef[i][j][k] & rmask[coefBits],
                             coefBits);
                tnsBits += coefBits;
              }
            }
          }
        }
      }
    } else {
      if (tnsPresent != 0) {
        for (i = 0; i < numOfWindows; i++) {
          tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
          if (tnsInfo->numOfFilters[i]) {
            tnsBits += 1;
            for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
              tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
              tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
              if (tnsInfo->order[i][j]) {
                tnsBits += 1; /*direction*/
                tnsBits += 1; /*coef_compression */
                if (tnsInfo->coefRes[i] == 4) {
                  coefBits = 3;
                  for (k = 0; k < tnsInfo->order[i][j]; k++) {
                    if (tnsInfo->coef[i][j][k] > 3 ||
                        tnsInfo->coef[i][j][k] < -4) {
                      coefBits = 4;
                      break;
                    }
                  }
                } else {
                  coefBits = 2;
                  for (k = 0; k < tnsInfo->order[i][j]; k++) {
                    if (tnsInfo->coef[i][j][k] > 1 ||
                        tnsInfo->coef[i][j][k] < -2) {
                      coefBits = 3;
                      break;
                    }
                  }
                }
                for (k = 0; k < tnsInfo->order[i][j]; k++) {
                  tnsBits += coefBits;
                }
              }
            }
          }
        }
      }
    }
  } /* (tnsInfo!=NULL) */

  return (tnsBits);
}

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

    functionname: FDKaacEnc_encodeGainControlData
    description:  unsupported
    returns:      none
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) {
  if (hBitStream != NULL) {
    FDKwriteBits(hBitStream, 0, 1);
  }
  return (1);
}

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

    functionname: FDKaacEnc_encodePulseData
    description:  not supported yet (dummy)
    returns:      none
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) {
  if (hBitStream != NULL) {
    FDKwriteBits(hBitStream, 0, 1);
  }
  return (1);
}

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

    functionname: FDKaacEnc_writeExtensionPayload
    description:  write extension payload to bitstream
    returns:      number of written bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,
                                           EXT_PAYLOAD_TYPE extPayloadType,
                                           const UCHAR *extPayloadData,
                                           INT extPayloadBits) {
#define EXT_TYPE_BITS (4)
#define DATA_EL_VERSION_BITS (4)
#define FILL_NIBBLE_BITS (4)

  INT extBitsUsed = 0;

  if (extPayloadBits >= EXT_TYPE_BITS) {
    UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */

    if (hBitStream != NULL) {
      FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
    }
    extBitsUsed += EXT_TYPE_BITS;

    switch (extPayloadType) {
      /* case EXT_SAC_DATA: */
      case EXT_LDSAC_DATA:
        if (hBitStream != NULL) {
          FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */
        }
        extBitsUsed += 4;
      case EXT_DYNAMIC_RANGE:
      case EXT_SBR_DATA:
      case EXT_SBR_DATA_CRC:
        if (hBitStream != NULL) {
          int i, writeBits = extPayloadBits;
          for (i = 0; writeBits >= 8; i++) {
            FDKwriteBits(hBitStream, *extPayloadData++, 8);
            writeBits -= 8;
          }
          if (writeBits > 0) {
            FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
                         writeBits);
          }
        }
        extBitsUsed += extPayloadBits;
        break;

      case EXT_DATA_ELEMENT: {
        INT dataElementLength = (extPayloadBits + 7) >> 3;
        INT cnt = dataElementLength;
        int loopCounter = 1;

        while (dataElementLength >= 255) {
          loopCounter++;
          dataElementLength -= 255;
        }

        if (hBitStream != NULL) {
          int i;
          FDKwriteBits(
              hBitStream, 0x00,
              DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */

          for (i = 1; i < loopCounter; i++) {
            FDKwriteBits(hBitStream, 255, 8);
          }
          FDKwriteBits(hBitStream, dataElementLength, 8);

          for (i = 0; i < cnt; i++) {
            FDKwriteBits(hBitStream, extPayloadData[i], 8);
          }
        }
        extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
      } break;

      case EXT_FILL_DATA:
        fillByte = 0xA5;
      case EXT_FIL:
      default:
        if (hBitStream != NULL) {
          int writeBits = extPayloadBits;
          FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
          writeBits -=
              8; /* acount for the extension type and the fill nibble */
          while (writeBits >= 8) {
            FDKwriteBits(hBitStream, fillByte, 8);
            writeBits -= 8;
          }
        }
        extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
        break;
    }
  }

  return (extBitsUsed);
}

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

    functionname: FDKaacEnc_writeDataStreamElement
    description:  write data stream elements like ancillary data ...
    returns:      the amount of used bits
    input:
    output:

******************************************************************************/
static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
                                            INT elementInstanceTag,
                                            INT dataPayloadBytes,
                                            UCHAR *dataBuffer,
                                            UINT alignAnchor) {
#define DATA_BYTE_ALIGN_FLAG (0)

#define EL_INSTANCE_TAG_BITS (4)
#define DATA_BYTE_ALIGN_FLAG_BITS (1)
#define DATA_LEN_COUNT_BITS (8)
#define DATA_LEN_ESC_COUNT_BITS (8)

#define MAX_DATA_ALIGN_BITS (7)
#define MAX_DSE_DATA_BYTES (510)

  INT dseBitsUsed = 0;

  while (dataPayloadBytes > 0) {
    int esc_count = -1;
    int cnt = 0;
    INT crcReg = -1;

    dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
                   DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;

    if (DATA_BYTE_ALIGN_FLAG) {
      dseBitsUsed += MAX_DATA_ALIGN_BITS;
    }

    cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
    if (cnt >= 255) {
      esc_count = cnt - 255;
      dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
    }

    dataPayloadBytes -= cnt;
    dseBitsUsed += cnt * 8;

    if (hTpEnc != NULL) {
      HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
      int i;

      FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);

      crcReg = transportEnc_CrcStartReg(hTpEnc, 0);

      FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
      FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);

      /* write length field(s) */
      if (esc_count >= 0) {
        FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
        FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
      } else {
        FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
      }

      if (DATA_BYTE_ALIGN_FLAG) {
        INT tmp = (INT)FDKgetValidBits(hBitStream);
        FDKbyteAlign(hBitStream, alignAnchor);
        /* count actual bits */
        dseBitsUsed +=
            (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
      }

      /* write payload */
      for (i = 0; i < cnt; i++) {
        FDKwriteBits(hBitStream, dataBuffer[i], 8);
      }
      transportEnc_CrcEndReg(hTpEnc, crcReg);
    }
  }

  return (dseBitsUsed);
}

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

    functionname: FDKaacEnc_writeExtensionData
    description:  write extension payload to bitstream
    returns:      number of written bits
    input:
    output:

*****************************************************************************/
INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
                                 QC_OUT_EXTENSION *pExtension,
                                 INT elInstanceTag, /* for DSE only */
                                 UINT alignAnchor,  /* for DSE only */
                                 UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
                                 SCHAR epConfig) {
#define FILL_EL_COUNT_BITS (4)
#define FILL_EL_ESC_COUNT_BITS (8)
#define MAX_FILL_DATA_BYTES (269)

  HANDLE_FDK_BITSTREAM hBitStream = NULL;
  INT payloadBits = pExtension->nPayloadBits;
  INT extBitsUsed = 0;

  if (hTpEnc != NULL) {
    hBitStream = transportEnc_GetBitstream(hTpEnc);
  }

  if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
    {
      if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
                                     (pExtension->type == EXT_SBR_DATA_CRC))) {
        if (hBitStream != NULL) {
          int i, writeBits = payloadBits;
          UCHAR *extPayloadData = pExtension->pPayload;

          for (i = 0; writeBits >= 8; i++) {
            FDKwriteBits(hBitStream, extPayloadData[i], 8);
            writeBits -= 8;
          }
          if (writeBits > 0) {
            FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
                         writeBits);
          }
        }
        extBitsUsed += payloadBits;
      } else {
        /* ER or scalable syntax -> write extension en bloc */
        extBitsUsed += FDKaacEnc_writeExtensionPayload(
            hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
      }
    }
  } else {
    /* We have normal GA bitstream payload (AOT 2,5,29) so pack
       the data into a fill elements or DSEs */

    if (pExtension->type == EXT_DATA_ELEMENT) {
      extBitsUsed += FDKaacEnc_writeDataStreamElement(
          hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
          pExtension->pPayload, alignAnchor);
    } else {
      while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
        INT cnt, esc_count = -1, alignBits = 7;

        if ((pExtension->type == EXT_FILL_DATA) ||
            (pExtension->type == EXT_FIL)) {
          payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
          if (payloadBits >= 15 * 8) {
            payloadBits -= FILL_EL_ESC_COUNT_BITS;
            esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
          }
          alignBits = 0;
        }

        cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);

        if (cnt >= 15) {
          esc_count = cnt - 15 + 1;
        }

        if (hBitStream != NULL) {
          /* write bitstream */
          FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
          if (esc_count >= 0) {
            FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
            FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
          } else {
            FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
          }
        }

        extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
                       ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);

        cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
        extBitsUsed += FDKaacEnc_writeExtensionPayload(
            hBitStream, pExtension->type, pExtension->pPayload, cnt);
        payloadBits -= cnt;
      }
    }
  }

  return (extBitsUsed);
}

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

    functionname: FDKaacEnc_ByteAlignment
    description:
    returns:
    input:
    output:

*****************************************************************************/
static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
                                    int alignBits) {
  FDKwriteBits(hBitStream, 0, alignBits);
}

AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
    HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
    QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
    PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
    AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
  AAC_ENCODER_ERROR error = AAC_ENC_OK;
  HANDLE_FDK_BITSTREAM hBitStream = NULL;
  INT bitDemand = 0;
  const element_list_t *list;
  int i, ch, decision_bit;
  INT crcReg1 = -1, crcReg2 = -1;
  UCHAR numberOfChannels;

  if (hTpEnc != NULL) {
    /* Get bitstream handle */
    hBitStream = transportEnc_GetBitstream(hTpEnc);
  }

  if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
    numberOfChannels = 1;
  } else {
    numberOfChannels = 2;
  }

  /* Get channel element sequence table */
  list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
  if (list == NULL) {
    error = AAC_ENC_UNSUPPORTED_AOT;
    goto bail;
  }

  if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
    if (hBitStream != NULL) {
      FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
    }
    bitDemand += EL_ID_BITS;
  }

  /* Iterate through sequence table */
  i = 0;
  ch = 0;
  decision_bit = 0;
  do {
    /* some tmp values */
    SECTION_DATA *pChSectionData = NULL;
    INT *pChScf = NULL;
    UINT *pChMaxValueInSfb = NULL;
    TNS_INFO *pTnsInfo = NULL;
    INT chGlobalGain = 0;
    INT chBlockType = 0;
    INT chMaxSfbPerGrp = 0;
    INT chSfbPerGrp = 0;
    INT chSfbCnt = 0;
    INT chFirstScf = 0;

    if (minCnt == 0) {
      if (qcOutChannel != NULL) {
        pChSectionData = &(qcOutChannel[ch]->sectionData);
        pChScf = qcOutChannel[ch]->scf;
        chGlobalGain = qcOutChannel[ch]->globalGain;
        pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
        chBlockType = pChSectionData->blockType;
        chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
        chSfbPerGrp = pChSectionData->sfbPerGroup;
        chSfbCnt = pChSectionData->sfbCnt;
        chFirstScf = pChScf[pChSectionData->firstScf];
      } else {
        /* get values from PSY */
        chSfbCnt = psyOutChannel[ch]->sfbCnt;
        chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
        chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
      }
      pTnsInfo = &psyOutChannel[ch]->tnsInfo;
    } /* minCnt==0 */

    if (qcOutChannel == NULL) {
      chBlockType = psyOutChannel[ch]->lastWindowSequence;
    }

    switch (list->id[i]) {
      case element_instance_tag:
        /* Write element instance tag */
        if (hBitStream != NULL) {
          FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
        }
        bitDemand += 4;
        break;

      case common_window:
        /* Write common window flag */
        decision_bit = psyOutElement->commonWindow;
        if (hBitStream != NULL) {
          FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
        }
        bitDemand += 1;
        break;

      case ics_info:
        /* Write individual channel info */
        bitDemand +=
            FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
                                    psyOutChannel[ch]->groupingMask,
                                    chMaxSfbPerGrp, hBitStream, syntaxFlags);
        break;

      case ltp_data_present:
        /* Write LTP data present flag */
        if (hBitStream != NULL) {
          FDKwriteBits(hBitStream, 0, 1);
        }
        bitDemand += 1;
        break;

      case ltp_data:
        /* Predictor data not supported.
           Nothing to do here. */
        break;

      case ms:
        /* Write MS info */
        bitDemand += FDKaacEnc_encodeMSInfo(
            chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
            (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
            psyOutElement->toolsInfo.msMask, hBitStream);
        break;

      case global_gain:
        bitDemand += FDKaacEnc_encodeGlobalGain(
            chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
        break;

      case section_data: {
        INT siBits = FDKaacEnc_encodeSectionData(
            pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
        if (hBitStream != NULL) {
          if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
            error = AAC_ENC_WRITE_SEC_ERROR;
          }
        }
        bitDemand += siBits;
      } break;

      case scale_factor_data: {
        INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
            pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
            psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
            chGlobalGain);
        if ((hBitStream != NULL) &&
            (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
                            qcOutChannel[ch]->sectionData.noiseNrgBits))) {
          error = AAC_ENC_WRITE_SCAL_ERROR;
        }
        bitDemand += sfDataBits;
      } break;

      case esc2_rvlc:
        if (syntaxFlags & AC_ER_RVLC) {
          /* write RVLC data into bitstream (error sens. cat. 2) */
          error = AAC_ENC_UNSUPPORTED_AOT;
        }
        break;

      case pulse:
        /* Write pulse data */
        bitDemand += FDKaacEnc_encodePulseData(hBitStream);
        break;

      case tns_data_present:
        /* Write TNS data present flag */
        bitDemand +=
            FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
        break;
      case tns_data:
        /* Write TNS data */
        bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
        break;

      case gain_control_data:
        /* Nothing to do here */
        break;

      case gain_control_data_present:
        bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
        break;

      case esc1_hcr:
        if (syntaxFlags & AC_ER_HCR) {
          error = AAC_ENC_UNKNOWN;
        }
        break;

      case spectral_data:
        if (hBitStream != NULL) {
          INT spectralBits = 0;

          spectralBits = FDKaacEnc_encodeSpectralData(
              psyOutChannel[ch]->sfbOffsets, pChSectionData,
              qcOutChannel[ch]->quantSpec, hBitStream);

          if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
            return AAC_ENC_WRITE_SPEC_ERROR;
          }
          bitDemand += spectralBits;
        }
        break;

        /* Non data cases */
      case adtscrc_start_reg1:
        if (hTpEnc != NULL) {
          crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
        }
        break;
      case adtscrc_start_reg2:
        if (hTpEnc != NULL) {
          crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
        }
        break;
      case adtscrc_end_reg1:
      case drmcrc_end_reg:
        if (hTpEnc != NULL) {
          transportEnc_CrcEndReg(hTpEnc, crcReg1);
        }
        break;
      case adtscrc_end_reg2:
        if (hTpEnc != NULL) {
          transportEnc_CrcEndReg(hTpEnc, crcReg2);
        }
        break;
      case drmcrc_start_reg:
        if (hTpEnc != NULL) {
          crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
        }
        break;
      case next_channel:
        ch = (ch + 1) % numberOfChannels;
        break;
      case link_sequence:
        list = list->next[decision_bit];
        i = -1;
        break;

      default:
        error = AAC_ENC_UNKNOWN;
        break;
    }

    if (error != AAC_ENC_OK) {
      return error;
    }

    i++;

  } while (list->id[i] != end_of_sequence);

bail:
  if (pBitDemand != NULL) {
    *pBitDemand = bitDemand;
  }

  return error;
}

//-----------------------------------------------------------------------------------------------

AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
                                           CHANNEL_MAPPING *channelMapping,
                                           QC_OUT *qcOut, PSY_OUT *psyOut,
                                           QC_STATE *qcKernel,
                                           AUDIO_OBJECT_TYPE aot,
                                           UINT syntaxFlags, SCHAR epConfig) {
  HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
  int i, n, doByteAlign = 1;
  INT bitMarkUp;
  INT frameBits;
  /* Get first bit of raw data block.
     In case of ADTS+PCE, AU would start at PCE.
     This is okay because PCE assures alignment. */
  UINT alignAnchor = FDKgetValidBits(hBs);

  frameBits = bitMarkUp = alignAnchor;

  /* Channel element loop */
  for (i = 0; i < channelMapping->nElements; i++) {
    ELEMENT_INFO elInfo = channelMapping->elInfo[i];
    INT elementUsedBits = 0;

    switch (elInfo.elType) {
      case ID_SCE: /* single channel */
      case ID_CPE: /* channel pair */
      case ID_LFE: /* low freq effects channel */
      {
        if (AAC_ENC_OK !=
            (ErrorStatus = FDKaacEnc_ChannelElementWrite(
                 hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
                 psyOut->psyOutElement[i],
                 psyOut->psyOutElement[i]->psyOutChannel,
                 syntaxFlags, /* syntaxFlags (ER tools ...) */
                 aot,         /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
                 epConfig,    /* epConfig -1, 0, 1 */
                 NULL, 0))) {
          return ErrorStatus;
        }

        if (!(syntaxFlags & AC_ER)) {
          /* Write associated extension payload */
          for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
            FDKaacEnc_writeExtensionData(
                hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
                syntaxFlags, aot, epConfig);
          }
        }
      } break;

      /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
      default:
        return AAC_ENC_INVALID_ELEMENTINFO_TYPE;

    } /* switch */

    if (elInfo.elType != ID_DSE) {
      elementUsedBits -= bitMarkUp;
      bitMarkUp = FDKgetValidBits(hBs);
      elementUsedBits += bitMarkUp;
      frameBits += elementUsedBits;
    }

  } /* for (i=0; i<channelMapping.nElements; i++) */

  if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
    UCHAR channelElementExtensionWritten[((8))][(
        1)]; /* 0: extension not touched, 1: extension already written */

    FDKmemclear(channelElementExtensionWritten,
                sizeof(channelElementExtensionWritten));

    if (syntaxFlags & AC_ELD) {
      for (i = 0; i < channelMapping->nElements; i++) {
        for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
          if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
              (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
            /* Write sbr extension payload */
            FDKaacEnc_writeExtensionData(
                hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
                syntaxFlags, aot, epConfig);

            channelElementExtensionWritten[i][n] = 1;
          } /* SBR */
        }   /* n */
      }     /* i */
    }       /* AC_ELD */

    for (i = 0; i < channelMapping->nElements; i++) {
      for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
        if (channelElementExtensionWritten[i][n] == 0) {
          /* Write all ramaining extension payloads in element */
          FDKaacEnc_writeExtensionData(hTpEnc,
                                       &qcOut->qcElement[i]->extension[n], 0,
                                       alignAnchor, syntaxFlags, aot, epConfig);
        }
      } /* n */
    }   /* i */
  }     /* if AC_ER */

  /* Extend global extension payload table with fill bits */
  n = qcOut->nExtensions;

  /* Add fill data / stuffing bits */
  qcOut->extension[n].type = EXT_FILL_DATA;
  qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
  qcOut->nExtensions++;

  /* Write global extension payload and fill data */
  for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) {
    FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor,
                                 syntaxFlags, aot, epConfig);

    /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
     */
  }

  if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
    FDKwriteBits(hBs, ID_END, EL_ID_BITS);
  }

  if (doByteAlign) {
    /* Assure byte alignment*/
    if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
      return AAC_ENC_WRITTEN_BITS_ERROR;
    }

    FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
  }

  frameBits -= bitMarkUp;
  frameBits += FDKgetValidBits(hBs);

  transportEnc_EndAccessUnit(hTpEnc, &frameBits);

  if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) {
    return AAC_ENC_WRITTEN_BITS_ERROR;
  }

  return ErrorStatus;
}
