summaryrefslogtreecommitdiffstats
path: root/libAACenc/src/bitenc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libAACenc/src/bitenc.cpp')
-rw-r--r--libAACenc/src/bitenc.cpp1508
1 files changed, 0 insertions, 1508 deletions
diff --git a/libAACenc/src/bitenc.cpp b/libAACenc/src/bitenc.cpp
deleted file mode 100644
index 4552457..0000000
--- a/libAACenc/src/bitenc.cpp
+++ /dev/null
@@ -1,1508 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 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 Audio Encoder **************************
-
- Initial author: M. Werner
- contents/description: Bitstream encoder
-
-******************************************************************************/
-#include <stdio.h>
-#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;
- //fprintf(stderr, "FDKaacEnc_writeExtensionPayload() extPayloadType=%d\n", extPayloadType);
- 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_DYNAMIC_RANGE:
- /* case EXT_SAC_DATA: */
- 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[i], 8);
- writeBits -= 8;
- }
- if (writeBits > 0) {
- FDKwriteBits(hBitStream, extPayloadData[i]>>(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;
- //fprintf(stderr, "FDKaacEnc_writeDataStreamElement() dataPayloadBytes=%d\n", dataPayloadBytes);
- 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);
- }
-
- //fprintf(stderr, "FDKaacEnc_writeExtensionData() pExtension->type=%d\n", pExtension->type);
- if (syntaxFlags & (AC_SCALABLE|AC_ER))
- {
- if ( syntaxFlags & AC_DRM )
- { /* CAUTION: The caller has to assure that fill
- data is written before the SBR payload. */
- UCHAR *extPayloadData = pExtension->pPayload;
-
- switch (pExtension->type)
- {
- case EXT_SBR_DATA:
- case EXT_SBR_DATA_CRC:
- /* SBR payload is written in reverse */
- if (hBitStream != NULL) {
- int i, writeBits = payloadBits;
-
- FDKpushFor(hBitStream, payloadBits-1); /* Does a cache sync internally */
-
- for (i=0; writeBits >= 8; i++) {
- FDKwriteBitsBwd(hBitStream, extPayloadData[i], 8);
- writeBits -= 8;
- }
- if (writeBits > 0) {
- FDKwriteBitsBwd(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
- }
-
- FDKsyncCacheBwd (hBitStream);
- FDKpushFor (hBitStream, payloadBits+1);
- }
- extBitsUsed += payloadBits;
- break;
-
- case EXT_FILL_DATA:
- case EXT_FIL:
- default:
- if (hBitStream != NULL) {
- int writeBits = payloadBits;
- while (writeBits >= 8) {
- FDKwriteBits(hBitStream, 0x00, 8);
- writeBits -= 8;
- }
- FDKwriteBits(hBitStream, 0x00, writeBits);
- }
- extBitsUsed += payloadBits;
- break;
- }
- }
- else {
- 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);
- 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:
- //TODO: DRM!
- 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;
-
-
- /* Write DSEs first in case of DAB */
- for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
- {
- if ( (syntaxFlags & AC_DAB) &&
- (qcOut->extension[n].type == EXT_DATA_ELEMENT) ) {
- 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 */
- }
-
- /* 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 remaining 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 */
- if ( syntaxFlags & AC_DRM )
- {
- /* Exception for Drm */
- for (n = 0; n < qcOut->nExtensions; n++) {
- if ( (qcOut->extension[n].type == EXT_SBR_DATA)
- || (qcOut->extension[n].type == EXT_SBR_DATA_CRC) ) {
- /* SBR data must be the last extension! */
- FDKmemcpy(&qcOut->extension[qcOut->nExtensions], &qcOut->extension[n], sizeof(QC_OUT_EXTENSION));
- break;
- }
- }
- /* Do byte alignment after AAC (+ MPS) payload.
- Assure that MPS has been written as channel assigned extension payload! */
- if (((FDKgetValidBits(hBs)-alignAnchor+(UINT)qcOut->totFillBits)&0x7)!=(UINT)qcOut->alignBits) {
- return AAC_ENC_WRITTEN_BITS_ERROR;
- }
- FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
- doByteAlign = 0;
-
- } /* AC_DRM */
-
- /* Add fill data / stuffing bits */
- n = qcOut->nExtensions;
-
-// if (!(syntaxFlags & AC_DAB)) {
- qcOut->extension[n].type = EXT_FILL_DATA;
- qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
- qcOut->nExtensions++;
-// } else {
-// doByteAlign = 0;
-// }
- if (syntaxFlags & AC_DAB)
- doByteAlign = 0;
-
- /* Write global extension payload and fill data */
- for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
- {
- if ( !(syntaxFlags & AC_DAB) ||
- ( (syntaxFlags & AC_DAB) &&
- (qcOut->extension[n].type != EXT_DATA_ELEMENT)
- )
- ) {
- 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|AC_DAB))) {
- FDKwriteBits(hBs, ID_END, EL_ID_BITS);
- }
-
- if (doByteAlign) {
- /* Assure byte alignment*/
- if (((alignAnchor-FDKgetValidBits(hBs))&0x7)!=(UINT)qcOut->alignBits) {
- 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){
- fprintf(stderr, "frameBits != qcOut->totalBits + qcKernel->globHdrBits: %d != %d + %d", frameBits, qcOut->totalBits, qcKernel->globHdrBits);
- return AAC_ENC_WRITTEN_BITS_ERROR;
- }
-
- //fprintf(stderr, "ErrorStatus=%d", ErrorStatus);
- return ErrorStatus;
-}
-