1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and the date of any change. For modified versions of the FDK AAC Codec, the term
50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84 /******************************** MPEG Audio Encoder **************************
85
86   Initial author:       M. Werner
87   contents/description: Bitstream encoder
88
89******************************************************************************/
90
91#include "bitenc.h"
92#include "bit_cnt.h"
93#include "dyn_bits.h"
94#include "qc_data.h"
95#include "interface.h"
96#include "aacEnc_ram.h"
97
98
99#include "tpenc_lib.h"
100
101#include "FDK_tools_rom.h"  /* needed for the bitstream syntax tables */
102
103static const int globalGainOffset = 100;
104static const int icsReservedBit   = 0;
105static const int noiseOffset      = 90;
106
107/*****************************************************************************
108
109    functionname: FDKaacEnc_encodeSpectralData
110    description:  encode spectral data
111    returns:      the number of written bits
112    input:
113    output:
114
115*****************************************************************************/
116static INT FDKaacEnc_encodeSpectralData(INT                    *sfbOffset,
117                                        SECTION_DATA           *sectionData,
118                                        SHORT                  *quantSpectrum,
119                                        HANDLE_FDK_BITSTREAM    hBitStream)
120{
121  INT i,sfb;
122  INT dbgVal = FDKgetValidBits(hBitStream);
123
124  for(i=0;i<sectionData->noOfSections;i++)
125  {
126    if(sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)
127    {
128      /* huffencode spectral data for this huffsection */
129      INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt;
130      for(sfb=sectionData->huffsection[i].sfbStart; sfb<tmp; sfb++)
131      {
132        FDKaacEnc_codeValues(quantSpectrum+sfbOffset[sfb],
133                             sfbOffset[sfb+1]-sfbOffset[sfb],
134                             sectionData->huffsection[i].codeBook,
135                             hBitStream);
136      }
137    }
138  }
139  return(FDKgetValidBits(hBitStream)-dbgVal);
140}
141
142/*****************************************************************************
143
144    functionname:FDKaacEnc_encodeGlobalGain
145    description: encodes Global Gain (common scale factor)
146    returns:     the number of static bits
147    input:
148    output:
149
150*****************************************************************************/
151static INT FDKaacEnc_encodeGlobalGain(INT globalGain,
152                                      INT scalefac,
153                                      HANDLE_FDK_BITSTREAM hBitStream,
154                                      INT mdctScale)
155{
156  if (hBitStream != NULL) {
157    FDKwriteBits(hBitStream,globalGain - scalefac + globalGainOffset-4*(LOG_NORM_PCM-mdctScale),8);
158  }
159  return (8);
160}
161
162
163/*****************************************************************************
164
165    functionname:FDKaacEnc_encodeIcsInfo
166    description: encodes Ics Info
167    returns:     the number of static bits
168    input:
169    output:
170
171*****************************************************************************/
172
173static INT FDKaacEnc_encodeIcsInfo(INT blockType,
174                                   INT windowShape,
175                                   INT groupingMask,
176                                   INT maxSfbPerGroup,
177                                   HANDLE_FDK_BITSTREAM  hBitStream,
178                                   UINT syntaxFlags)
179{
180  INT statBits;
181
182  if (blockType == SHORT_WINDOW) {
183    statBits = 8 + TRANS_FAC - 1;
184  } else {
185    if (syntaxFlags & AC_ELD) {
186      statBits = 6;
187    } else
188    {
189      statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
190    }
191  }
192
193  if (hBitStream != NULL) {
194
195    if (!(syntaxFlags & AC_ELD)){
196      FDKwriteBits(hBitStream,icsReservedBit,1);
197      FDKwriteBits(hBitStream,blockType,2);
198      FDKwriteBits(hBitStream, (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape,1);
199    }
200
201    switch(blockType){
202    case LONG_WINDOW:
203    case START_WINDOW:
204    case STOP_WINDOW:
205      FDKwriteBits(hBitStream,maxSfbPerGroup,6);
206
207      if (!(syntaxFlags & (AC_SCALABLE|AC_ELD)) ) { /* If not scalable syntax then ... */
208        /* No predictor data present */
209        FDKwriteBits(hBitStream, 0, 1);
210      }
211      break;
212
213    case SHORT_WINDOW:
214      FDKwriteBits(hBitStream,maxSfbPerGroup,4);
215
216      /* Write grouping bits */
217      FDKwriteBits(hBitStream,groupingMask,TRANS_FAC-1);
218      break;
219    }
220  }
221
222  return (statBits);
223}
224
225/*****************************************************************************
226
227    functionname: FDKaacEnc_encodeSectionData
228    description:  encode section data (common Huffman codebooks for adjacent
229                  SFB's)
230    returns:      none
231    input:
232    output:
233
234*****************************************************************************/
235static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
236                                       HANDLE_FDK_BITSTREAM hBitStream,
237                                       UINT useVCB11)
238{
239  if (hBitStream != NULL) {
240    INT sectEscapeVal=0,sectLenBits=0;
241    INT sectLen;
242    INT i;
243    INT dbgVal=FDKgetValidBits(hBitStream);
244    INT sectCbBits = 4;
245
246    switch(sectionData->blockType)
247    {
248    case LONG_WINDOW:
249    case START_WINDOW:
250    case STOP_WINDOW:
251      sectEscapeVal = SECT_ESC_VAL_LONG;
252      sectLenBits   = SECT_BITS_LONG;
253      break;
254
255    case SHORT_WINDOW:
256      sectEscapeVal = SECT_ESC_VAL_SHORT;
257      sectLenBits   = SECT_BITS_SHORT;
258      break;
259    }
260
261    for(i=0;i<sectionData->noOfSections;i++)
262    {
263      INT codeBook = sectionData->huffsection[i].codeBook;
264
265      FDKwriteBits(hBitStream,codeBook,sectCbBits);
266
267      {
268        sectLen = sectionData->huffsection[i].sfbCnt;
269
270        while(sectLen >= sectEscapeVal)
271        {
272          FDKwriteBits(hBitStream,sectEscapeVal,sectLenBits);
273          sectLen-=sectEscapeVal;
274        }
275        FDKwriteBits(hBitStream,sectLen,sectLenBits);
276      }
277    }
278    return(FDKgetValidBits(hBitStream)-dbgVal);
279  }
280  return (0);
281}
282
283/*****************************************************************************
284
285    functionname: FDKaacEnc_encodeScaleFactorData
286    description:  encode DPCM coded scale factors
287    returns:      none
288    input:
289    output:
290
291*****************************************************************************/
292static INT FDKaacEnc_encodeScaleFactorData(UINT                  *maxValueInSfb,
293                                           SECTION_DATA          *sectionData,
294                                           INT                   *scalefac,
295                                           HANDLE_FDK_BITSTREAM   hBitStream,
296                                           INT                   *RESTRICT noiseNrg,
297                                           const INT             *isScale,
298                                           INT                    globalGain)
299{
300  if (hBitStream != NULL) {
301    INT i,j,lastValScf,deltaScf;
302    INT deltaPns;
303    INT lastValPns = 0;
304    INT noisePCMFlag = TRUE;
305    INT lastValIs;
306
307    INT dbgVal = FDKgetValidBits(hBitStream);
308
309    lastValScf=scalefac[sectionData->firstScf];
310    lastValPns = globalGain-scalefac[sectionData->firstScf]+globalGainOffset-4*LOG_NORM_PCM-noiseOffset;
311    lastValIs  = 0;
312
313    for(i=0; i<sectionData->noOfSections; i++){
314      if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
315
316        if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
317            (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO))
318        {
319          INT sfbStart = sectionData->huffsection[i].sfbStart;
320          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
321          for(j=sfbStart; j<tmp; j++) {
322            INT deltaIs   = isScale[j]-lastValIs;
323            lastValIs = isScale[j];
324            if(FDKaacEnc_codeScalefactorDelta(deltaIs,hBitStream)) {
325                return(1);
326            }
327          } /* sfb */
328        }
329        else if(sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
330          INT sfbStart = sectionData->huffsection[i].sfbStart;
331          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
332          for(j=sfbStart; j<tmp; j++) {
333            deltaPns   = noiseNrg[j]-lastValPns;
334            lastValPns = noiseNrg[j];
335
336            if(noisePCMFlag){
337              FDKwriteBits(hBitStream,deltaPns+(1<<(PNS_PCM_BITS-1)),PNS_PCM_BITS);
338              noisePCMFlag = FALSE;
339            }
340            else {
341              if(FDKaacEnc_codeScalefactorDelta(deltaPns,hBitStream)) {
342                return(1);
343              }
344            }
345          } /* sfb */
346        }
347        else {
348          INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt;
349          for(j=sectionData->huffsection[i].sfbStart; j<tmp; j++){
350            /*
351              check if we can repeat the last value to save bits
352            */
353            if(maxValueInSfb[j] == 0)
354              deltaScf = 0;
355            else{
356              deltaScf = -(scalefac[j]-lastValScf);
357              lastValScf = scalefac[j];
358            }
359            if(FDKaacEnc_codeScalefactorDelta(deltaScf,hBitStream)){
360              return(1);
361            }
362          } /* sfb */
363        } /* code scalefactor */
364      } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
365    } /* section loop */
366
367    return(FDKgetValidBits(hBitStream)-dbgVal);
368  } /* if (hBitStream != NULL) */
369
370  return (0);
371}
372
373/*****************************************************************************
374
375    functionname:encodeMsInfo
376    description: encodes MS-Stereo Info
377    returns:     the number of static bits
378    input:
379    output:
380
381*****************************************************************************/
382static INT FDKaacEnc_encodeMSInfo(INT            sfbCnt,
383                                  INT            grpSfb,
384                                  INT            maxSfb,
385                                  INT            msDigest,
386                                  INT           *jsFlags,
387                                  HANDLE_FDK_BITSTREAM hBitStream)
388{
389  INT sfb, sfbOff, msBits = 0;
390
391  if (hBitStream != NULL)
392  {
393    switch(msDigest)
394    {
395    case MS_NONE:
396      FDKwriteBits(hBitStream,SI_MS_MASK_NONE,2);
397      msBits += 2;
398      break;
399
400    case MS_ALL:
401      FDKwriteBits(hBitStream,SI_MS_MASK_ALL,2);
402      msBits += 2;
403      break;
404
405    case MS_SOME:
406      FDKwriteBits(hBitStream,SI_MS_MASK_SOME,2);
407      msBits += 2;
408      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb)
409      {
410        for(sfb=0; sfb<maxSfb; sfb++)
411        {
412          if(jsFlags[sfbOff+sfb] & MS_ON){
413            FDKwriteBits(hBitStream,1,1);
414          }
415          else{
416            FDKwriteBits(hBitStream,0,1);
417          }
418          msBits += 1;
419        }
420      }
421      break;
422    }
423  }
424  else {
425    msBits += 2;
426    if (msDigest == MS_SOME) {
427      for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) {
428        for(sfb=0; sfb<maxSfb; sfb++) {
429          msBits += 1;
430        }
431      }
432    }
433  }
434  return (msBits);
435}
436
437/*****************************************************************************
438
439    functionname: FDKaacEnc_encodeTnsDataPresent
440    description:  encode TNS data (filter order, coeffs, ..)
441    returns:      the number of static bits
442    input:
443    output:
444
445*****************************************************************************/
446static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo,
447                                          INT blockType,
448                                          HANDLE_FDK_BITSTREAM hBitStream)
449{
450  if ( (hBitStream!=NULL) && (tnsInfo!=NULL) )
451  {
452    INT i, tnsPresent = 0;
453    INT numOfWindows = (blockType==SHORT_WINDOW?TRANS_FAC:1);
454
455    for (i=0; i<numOfWindows; i++) {
456      if (tnsInfo->numOfFilters[i]!=0) {
457        tnsPresent=1;
458        break;
459      }
460    }
461
462    if (tnsPresent==0) {
463      FDKwriteBits(hBitStream,0,1);
464    } else {
465      FDKwriteBits(hBitStream,1,1);
466    }
467  }
468  return (1);
469}
470
471/*****************************************************************************
472
473    functionname: FDKaacEnc_encodeTnsData
474    description:  encode TNS data (filter order, coeffs, ..)
475    returns:      the number of static bits
476    input:
477    output:
478
479*****************************************************************************/
480static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo,
481                                   INT blockType,
482                                   HANDLE_FDK_BITSTREAM hBitStream)
483{
484  INT tnsBits = 0;
485
486  if (tnsInfo!=NULL) {
487
488    INT i,j,k;
489    INT tnsPresent = 0;
490    INT coefBits;
491    INT numOfWindows=(blockType==SHORT_WINDOW?TRANS_FAC:1);
492
493    for (i=0; i<numOfWindows; i++) {
494      if (tnsInfo->numOfFilters[i]!=0) {
495        tnsPresent=1;
496      }
497    }
498
499    if (hBitStream != NULL)
500    {
501      if (tnsPresent==1) { /* there is data to be written*/
502        for (i=0; i<numOfWindows; i++) {
503          FDKwriteBits(hBitStream,tnsInfo->numOfFilters[i],(blockType==SHORT_WINDOW?1:2));
504          tnsBits += (blockType==SHORT_WINDOW?1:2);
505          if (tnsInfo->numOfFilters[i]) {
506            FDKwriteBits(hBitStream,(tnsInfo->coefRes[i]==4?1:0),1);
507            tnsBits += 1;
508          }
509          for (j=0; j<tnsInfo->numOfFilters[i]; j++) {
510            FDKwriteBits(hBitStream,tnsInfo->length[i][j],(blockType==SHORT_WINDOW?4:6));
511            tnsBits += (blockType==SHORT_WINDOW?4:6);
512            FDK_ASSERT(tnsInfo->order[i][j] <= 12);
513            FDKwriteBits(hBitStream,tnsInfo->order[i][j],(blockType==SHORT_WINDOW?3:5));
514            tnsBits += (blockType==SHORT_WINDOW?3:5);
515            if (tnsInfo->order[i][j]){
516              FDKwriteBits(hBitStream,tnsInfo->direction[i][j],1);
517              tnsBits +=1; /*direction*/
518              if(tnsInfo->coefRes[i] == 4) {
519                coefBits = 3;
520                for(k=0; k<tnsInfo->order[i][j]; k++) {
521                  if (tnsInfo->coef[i][j][k]> 3 ||
522                    tnsInfo->coef[i][j][k]< -4) {
523                    coefBits = 4;
524                    break;
525                  }
526                }
527              } else {
528                coefBits = 2;
529                for(k=0; k<tnsInfo->order[i][j]; k++) {
530                  if ( tnsInfo->coef[i][j][k]> 1
531                    || tnsInfo->coef[i][j][k]< -2) {
532                    coefBits = 3;
533                    break;
534                  }
535                }
536              }
537              FDKwriteBits(hBitStream,-(coefBits - tnsInfo->coefRes[i]),1); /*coef_compres*/
538              tnsBits +=1; /*coef_compression */
539              for (k=0; k<tnsInfo->order[i][j]; k++ ) {
540                static const INT rmask[] = {0,1,3,7,15};
541                FDKwriteBits(hBitStream,tnsInfo->coef[i][j][k] & rmask[coefBits],coefBits);
542                tnsBits += coefBits;
543              }
544            }
545          }
546        }
547      }
548    }
549    else {
550      if (tnsPresent != 0) {
551        for (i=0; i<numOfWindows; i++) {
552          tnsBits += (blockType==SHORT_WINDOW?1:2);
553          if (tnsInfo->numOfFilters[i]) {
554            tnsBits += 1;
555            for (j=0; j<tnsInfo->numOfFilters[i]; j++) {
556              tnsBits += (blockType==SHORT_WINDOW?4:6);
557              tnsBits += (blockType==SHORT_WINDOW?3:5);
558              if (tnsInfo->order[i][j]) {
559                tnsBits +=1; /*direction*/
560                tnsBits +=1; /*coef_compression */
561                if (tnsInfo->coefRes[i] == 4) {
562                  coefBits=3;
563                  for (k=0; k<tnsInfo->order[i][j]; k++) {
564                    if (tnsInfo->coef[i][j][k]> 3 || tnsInfo->coef[i][j][k]< -4) {
565                      coefBits = 4;
566                      break;
567                    }
568                  }
569                }
570                else {
571                  coefBits = 2;
572                  for (k=0; k<tnsInfo->order[i][j]; k++) {
573                    if (tnsInfo->coef[i][j][k]> 1 || tnsInfo->coef[i][j][k]< -2) {
574                      coefBits = 3;
575                      break;
576                    }
577                  }
578                }
579                for (k=0; k<tnsInfo->order[i][j]; k++) {
580                  tnsBits += coefBits;
581                }
582              }
583            }
584          }
585        }
586      }
587    }
588  } /* (tnsInfo!=NULL) */
589
590  return (tnsBits);
591}
592
593/*****************************************************************************
594
595    functionname: FDKaacEnc_encodeGainControlData
596    description:  unsupported
597    returns:      none
598    input:
599    output:
600
601*****************************************************************************/
602static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream)
603{
604  if (hBitStream != NULL) {
605    FDKwriteBits(hBitStream,0,1);
606  }
607  return (1);
608}
609
610/*****************************************************************************
611
612    functionname: FDKaacEnc_encodePulseData
613    description:  not supported yet (dummy)
614    returns:      none
615    input:
616    output:
617
618*****************************************************************************/
619static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream)
620{
621  if (hBitStream != NULL) {
622    FDKwriteBits(hBitStream,0,1);
623  }
624  return (1);
625}
626
627
628/*****************************************************************************
629
630    functionname: FDKaacEnc_writeExtensionPayload
631    description:  write extension payload to bitstream
632    returns:      number of written bits
633    input:
634    output:
635
636*****************************************************************************/
637static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM  hBitStream,
638                                            EXT_PAYLOAD_TYPE      extPayloadType,
639                                            const UCHAR          *extPayloadData,
640                                            INT                   extPayloadBits
641                                          )
642{
643  #define EXT_TYPE_BITS         ( 4 )
644  #define DATA_EL_VERSION_BITS  ( 4 )
645  #define FILL_NIBBLE_BITS      ( 4 )
646
647  INT  extBitsUsed = 0;
648
649  if (extPayloadBits >= EXT_TYPE_BITS)
650  {
651    UCHAR  fillByte = 0x00;  /* for EXT_FIL and EXT_FILL_DATA */
652
653    if (hBitStream != NULL) {
654      FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
655    }
656    extBitsUsed += EXT_TYPE_BITS;
657
658    switch (extPayloadType) {
659      case EXT_DYNAMIC_RANGE:
660      /* case EXT_SAC_DATA: */
661      case EXT_SBR_DATA:
662      case EXT_SBR_DATA_CRC:
663        if (hBitStream != NULL) {
664          int i, writeBits = extPayloadBits;
665          for (i=0; writeBits >= 8; i++) {
666            FDKwriteBits(hBitStream, extPayloadData[i], 8);
667            writeBits -= 8;
668          }
669          if (writeBits > 0) {
670            FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
671          }
672        }
673        extBitsUsed += extPayloadBits;
674        break;
675
676      case EXT_DATA_ELEMENT:
677        {
678          INT dataElementLength = (extPayloadBits+7)>>3;
679          INT cnt = dataElementLength;
680          int loopCounter = 1;
681
682          while (dataElementLength >= 255) {
683            loopCounter++;
684            dataElementLength -= 255;
685          }
686
687          if (hBitStream != NULL) {
688            int i;
689            FDKwriteBits(hBitStream, 0x00, DATA_EL_VERSION_BITS);  /* data_element_version = ANC_DATA */
690
691            for (i=1; i<loopCounter; i++) {
692              FDKwriteBits(hBitStream, 255, 8);
693            }
694            FDKwriteBits(hBitStream, dataElementLength, 8);
695
696            for (i=0; i<cnt; i++) {
697              FDKwriteBits(hBitStream, extPayloadData[i], 8);
698            }
699          }
700          extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter*8) + (cnt*8);
701        }
702        break;
703
704      case EXT_FILL_DATA:
705        fillByte = 0xA5;
706      case EXT_FIL:
707      default:
708        if (hBitStream != NULL) {
709          int writeBits = extPayloadBits;
710          FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
711          writeBits -= 8;  /* acount for the extension type and the fill nibble */
712          while (writeBits >= 8) {
713            FDKwriteBits(hBitStream, fillByte, 8);
714            writeBits -= 8;
715          }
716        }
717        extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
718        break;
719    }
720  }
721
722  return (extBitsUsed);
723}
724
725
726/*****************************************************************************
727
728    functionname: FDKaacEnc_writeDataStreamElement
729    description:  write data stream elements like ancillary data ...
730    returns:      the amount of used bits
731    input:
732    output:
733
734******************************************************************************/
735static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC  hTpEnc,
736                                             INT    elementInstanceTag,
737                                             INT    dataPayloadBytes,
738                                             UCHAR *dataBuffer,
739                                             UINT   alignAnchor )
740{
741  #define DATA_BYTE_ALIGN_FLAG      ( 0 )
742
743  #define EL_INSTANCE_TAG_BITS      ( 4 )
744  #define DATA_BYTE_ALIGN_FLAG_BITS ( 1 )
745  #define DATA_LEN_COUNT_BITS       ( 8 )
746  #define DATA_LEN_ESC_COUNT_BITS   ( 8 )
747
748  #define MAX_DATA_ALIGN_BITS       ( 7 )
749  #define MAX_DSE_DATA_BYTES        ( 510 )
750
751  INT  dseBitsUsed = 0;
752
753  while (dataPayloadBytes > 0)
754  {
755    int esc_count = -1;
756    int cnt = 0;
757    INT crcReg = -1;
758
759    dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS
760                +  DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
761
762    if (DATA_BYTE_ALIGN_FLAG) {
763      dseBitsUsed += MAX_DATA_ALIGN_BITS;
764    }
765
766    cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
767    if ( cnt >= 255 ) {
768      esc_count = cnt - 255;
769      dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
770    }
771
772    dataPayloadBytes -= cnt;
773    dseBitsUsed += cnt * 8;
774
775    if (hTpEnc != NULL) {
776      HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
777      int i;
778
779      FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
780
781      crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
782
783      FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
784      FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
785
786      /* write length field(s) */
787      if ( esc_count >= 0 ) {
788        FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
789        FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
790      } else {
791        FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
792      }
793
794      if (DATA_BYTE_ALIGN_FLAG) {
795        INT tmp = (INT)FDKgetValidBits(hBitStream);
796        FDKbyteAlign(hBitStream, alignAnchor);
797        /* count actual bits */
798        dseBitsUsed += (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
799      }
800
801      /* write payload */
802      for (i=0; i<cnt; i++) {
803        FDKwriteBits(hBitStream, dataBuffer[i], 8);
804      }
805      transportEnc_CrcEndReg(hTpEnc, crcReg);
806    }
807  }
808
809  return (dseBitsUsed);
810}
811
812
813/*****************************************************************************
814
815    functionname: FDKaacEnc_writeExtensionData
816    description:  write extension payload to bitstream
817    returns:      number of written bits
818    input:
819    output:
820
821*****************************************************************************/
822INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC  hTpEnc,
823                                  QC_OUT_EXTENSION    *pExtension,
824                                  INT                  elInstanceTag, /* for DSE only */
825                                  UINT                 alignAnchor,   /* for DSE only */
826                                  UINT                 syntaxFlags,
827                                  AUDIO_OBJECT_TYPE    aot,
828                                  SCHAR                epConfig
829                                )
830{
831  #define FILL_EL_COUNT_BITS      ( 4 )
832  #define FILL_EL_ESC_COUNT_BITS  ( 8 )
833  #define MAX_FILL_DATA_BYTES     ( 269 )
834
835  HANDLE_FDK_BITSTREAM hBitStream = NULL;
836  INT payloadBits = pExtension->nPayloadBits;
837  INT extBitsUsed = 0;
838
839  if (hTpEnc != NULL) {
840    hBitStream = transportEnc_GetBitstream(hTpEnc);
841  }
842
843  if (syntaxFlags & (AC_SCALABLE|AC_ER))
844  {
845    if ( syntaxFlags & AC_DRM )
846    { /* CAUTION: The caller has to assure that fill
847                  data is written before the SBR payload. */
848      UCHAR *extPayloadData = pExtension->pPayload;
849
850      switch (pExtension->type)
851      {
852        case EXT_SBR_DATA:
853        case EXT_SBR_DATA_CRC:
854          /* SBR payload is written in reverse */
855          if (hBitStream != NULL) {
856            int   i, writeBits = payloadBits;
857
858            FDKpushFor(hBitStream, payloadBits-1);  /* Does a cache sync internally */
859
860            for (i=0; writeBits >= 8; i++) {
861              FDKwriteBitsBwd(hBitStream, extPayloadData[i], 8);
862              writeBits -= 8;
863            }
864            if (writeBits > 0) {
865              FDKwriteBitsBwd(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
866            }
867
868            FDKsyncCacheBwd (hBitStream);
869            FDKpushFor (hBitStream, payloadBits+1);
870          }
871          extBitsUsed += payloadBits;
872          break;
873
874        case EXT_FILL_DATA:
875        case EXT_FIL:
876        default:
877          if (hBitStream != NULL) {
878            int writeBits = payloadBits;
879            while (writeBits >= 8) {
880              FDKwriteBits(hBitStream, 0x00, 8);
881              writeBits -= 8;
882            }
883            FDKwriteBits(hBitStream, 0x00, writeBits);
884          }
885          extBitsUsed += payloadBits;
886          break;
887      }
888    }
889    else {
890      if ( (syntaxFlags & AC_ELD) && ((pExtension->type==EXT_SBR_DATA) || (pExtension->type==EXT_SBR_DATA_CRC)) ) {
891
892        if (hBitStream != NULL) {
893          int i, writeBits = payloadBits;
894          UCHAR *extPayloadData = pExtension->pPayload;
895
896          for (i=0; writeBits >= 8; i++) {
897            FDKwriteBits(hBitStream, extPayloadData[i], 8);
898            writeBits -= 8;
899          }
900          if (writeBits > 0) {
901            FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits);
902          }
903        }
904        extBitsUsed += payloadBits;
905      }
906      else
907      {
908        /* ER or scalable syntax -> write extension en bloc */
909        extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
910                                                        pExtension->type,
911                                                        pExtension->pPayload,
912                                                        payloadBits );
913      }
914    }
915  }
916  else {
917    /* We have normal GA bitstream payload (AOT 2,5,29) so pack
918       the data into a fill elements or DSEs */
919
920    if ( pExtension->type == EXT_DATA_ELEMENT )
921    {
922      extBitsUsed += FDKaacEnc_writeDataStreamElement( hTpEnc,
923                                                       elInstanceTag,
924                                                       pExtension->nPayloadBits>>3,
925                                                       pExtension->pPayload,
926                                                       alignAnchor );
927    }
928    else {
929      while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
930        INT cnt, esc_count=-1, alignBits=7;
931
932        if ( (pExtension->type == EXT_FILL_DATA) || (pExtension->type == EXT_FIL) )
933        {
934          payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
935          if (payloadBits >= 15*8) {
936            payloadBits -= FILL_EL_ESC_COUNT_BITS;
937            esc_count = 0;  /* write esc_count even if cnt becomes smaller 15 */
938          }
939          alignBits = 0;
940        }
941
942        cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3);
943
944        if (cnt >= 15) {
945          esc_count = cnt - 15 + 1;
946        }
947
948        if (hBitStream != NULL) {
949          /* write bitstream */
950          FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
951          if (esc_count >= 0) {
952            FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
953            FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
954          } else {
955            FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
956          }
957        }
958
959        extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0);
960
961        cnt = fixMin(cnt*8, payloadBits);  /* convert back to bits */
962        extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream,
963                                                        pExtension->type,
964                                                        pExtension->pPayload,
965                                                        cnt );
966        payloadBits -= cnt;
967      }
968    }
969  }
970
971  return (extBitsUsed);
972}
973
974
975/*****************************************************************************
976
977    functionname: FDKaacEnc_ByteAlignment
978    description:
979    returns:
980    input:
981    output:
982
983*****************************************************************************/
984static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, int alignBits)
985{
986  FDKwriteBits(hBitStream, 0, alignBits);
987}
988
989AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC  hTpEnc,
990                                                 ELEMENT_INFO        *pElInfo,
991                                                 QC_OUT_CHANNEL      *qcOutChannel[(2)],
992                                                 PSY_OUT_ELEMENT     *psyOutElement,
993                                                 PSY_OUT_CHANNEL     *psyOutChannel[(2)],
994                                                 UINT                 syntaxFlags,
995                                                 AUDIO_OBJECT_TYPE    aot,
996                                                 SCHAR                epConfig,
997                                                 INT                 *pBitDemand,
998                                                 UCHAR                minCnt
999                                               )
1000{
1001  AAC_ENCODER_ERROR error = AAC_ENC_OK;
1002  HANDLE_FDK_BITSTREAM hBitStream = NULL;
1003  INT    bitDemand = 0;
1004  const  element_list_t *list;
1005  int    i, ch, decision_bit;
1006  INT    crcReg1 = -1, crcReg2 = -1;
1007  UCHAR  numberOfChannels;
1008
1009  if (hTpEnc != NULL) {
1010    /* Get bitstream handle */
1011    hBitStream = transportEnc_GetBitstream(hTpEnc);
1012  }
1013
1014  if ( (pElInfo->elType==ID_SCE) || (pElInfo->elType==ID_LFE) ) {
1015    numberOfChannels = 1;
1016  } else {
1017    numberOfChannels = 2;
1018  }
1019
1020  /* Get channel element sequence table */
1021  list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0);
1022  if (list == NULL) {
1023    error = AAC_ENC_UNSUPPORTED_AOT;
1024    goto bail;
1025  }
1026
1027  if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) {
1028    if (hBitStream != NULL) {
1029      FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
1030    }
1031    bitDemand += EL_ID_BITS;
1032  }
1033
1034  /* Iterate through sequence table */
1035  i = 0;
1036  ch = 0;
1037  decision_bit = 0;
1038  do {
1039    /* some tmp values */
1040    SECTION_DATA *pChSectionData = NULL;
1041    INT  *pChScf           = NULL;
1042    UINT *pChMaxValueInSfb = NULL;
1043    TNS_INFO *pTnsInfo     = NULL;
1044    INT   chGlobalGain     = 0;
1045    INT   chBlockType      = 0;
1046    INT   chMaxSfbPerGrp   = 0;
1047    INT   chSfbPerGrp      = 0;
1048    INT   chSfbCnt         = 0;
1049    INT   chFirstScf       = 0;
1050
1051    if (minCnt==0) {
1052      if ( qcOutChannel!=NULL ) {
1053        pChSectionData   = &(qcOutChannel[ch]->sectionData);
1054        pChScf           =  qcOutChannel[ch]->scf;
1055        chGlobalGain     =  qcOutChannel[ch]->globalGain;
1056        pChMaxValueInSfb =  qcOutChannel[ch]->maxValueInSfb;
1057        chBlockType      =  pChSectionData->blockType;
1058        chMaxSfbPerGrp   =  pChSectionData->maxSfbPerGroup;
1059        chSfbPerGrp      =  pChSectionData->sfbPerGroup;
1060        chSfbCnt         =  pChSectionData->sfbCnt;
1061        chFirstScf       =  pChScf[pChSectionData->firstScf];
1062      }
1063      else {
1064        /* get values from PSY */
1065        chSfbCnt       = psyOutChannel[ch]->sfbCnt;
1066        chSfbPerGrp    = psyOutChannel[ch]->sfbPerGroup;
1067        chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
1068      }
1069      pTnsInfo = &psyOutChannel[ch]->tnsInfo;
1070    } /* minCnt==0 */
1071
1072    if ( qcOutChannel==NULL ) {
1073      chBlockType    = psyOutChannel[ch]->lastWindowSequence;
1074    }
1075
1076    switch (list->id[i])
1077    {
1078    case element_instance_tag:
1079      /* Write element instance tag */
1080      if (hBitStream != NULL) {
1081        FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
1082      }
1083      bitDemand += 4;
1084      break;
1085
1086    case common_window:
1087      /* Write common window flag */
1088      decision_bit = psyOutElement->commonWindow;
1089      if (hBitStream != NULL) {
1090        FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
1091      }
1092      bitDemand += 1;
1093      break;
1094
1095    case ics_info:
1096      /* Write individual channel info */
1097      bitDemand += FDKaacEnc_encodeIcsInfo( chBlockType,
1098                                            psyOutChannel[ch]->windowShape,
1099                                            psyOutChannel[ch]->groupingMask,
1100                                            chMaxSfbPerGrp,
1101                                            hBitStream,
1102                                            syntaxFlags);
1103      break;
1104
1105    case ltp_data_present:
1106      /* Write LTP data present flag */
1107      if (hBitStream != NULL) {
1108        FDKwriteBits(hBitStream, 0, 1);
1109      }
1110      bitDemand += 1;
1111      break;
1112
1113    case ltp_data:
1114      /* Predictor data not supported.
1115         Nothing to do here. */
1116      break;
1117
1118    case ms:
1119      /* Write MS info */
1120      bitDemand += FDKaacEnc_encodeMSInfo( chSfbCnt,
1121                                           chSfbPerGrp,
1122                                           chMaxSfbPerGrp,
1123                                           (minCnt==0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
1124                                           psyOutElement->toolsInfo.msMask,
1125                                           hBitStream);
1126      break;
1127
1128    case global_gain:
1129      bitDemand += FDKaacEnc_encodeGlobalGain( chGlobalGain,
1130                                               chFirstScf,
1131                                               hBitStream,
1132                                               psyOutChannel[ch]->mdctScale );
1133      break;
1134
1135    case section_data:
1136      {
1137        INT siBits = FDKaacEnc_encodeSectionData(pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11)?1:0);
1138        if (hBitStream != NULL) {
1139          if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
1140            error = AAC_ENC_WRITE_SEC_ERROR;
1141          }
1142        }
1143        bitDemand += siBits;
1144      }
1145      break;
1146
1147    case scale_factor_data:
1148      {
1149        INT sfDataBits = FDKaacEnc_encodeScaleFactorData( pChMaxValueInSfb,
1150                                                          pChSectionData,
1151                                                          pChScf,
1152                                                          hBitStream,
1153                                                          psyOutChannel[ch]->noiseNrg,
1154                                                          psyOutChannel[ch]->isScale,
1155                                                          chGlobalGain );
1156        if ( (hBitStream != NULL)
1157          && (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + qcOutChannel[ch]->sectionData.noiseNrgBits)) ) {
1158           error = AAC_ENC_WRITE_SCAL_ERROR;
1159        }
1160        bitDemand += sfDataBits;
1161      }
1162      break;
1163
1164    case esc2_rvlc:
1165      if (syntaxFlags & AC_ER_RVLC) {
1166        /* write RVLC data into bitstream (error sens. cat. 2) */
1167        error = AAC_ENC_UNSUPPORTED_AOT;
1168      }
1169      break;
1170
1171    case pulse:
1172      /* Write pulse data */
1173      bitDemand += FDKaacEnc_encodePulseData(hBitStream);
1174      break;
1175
1176    case tns_data_present:
1177      /* Write TNS data present flag */
1178      bitDemand += FDKaacEnc_encodeTnsDataPresent(pTnsInfo,
1179                                                  chBlockType,
1180                                                  hBitStream);
1181      break;
1182    case tns_data:
1183      /* Write TNS data */
1184      bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo,
1185                                           chBlockType,
1186                                           hBitStream);
1187      break;
1188
1189    case gain_control_data:
1190      /* Nothing to do here */
1191      break;
1192
1193    case gain_control_data_present:
1194      bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
1195      break;
1196
1197
1198    case esc1_hcr:
1199      if (syntaxFlags & AC_ER_HCR)
1200      {
1201        error = AAC_ENC_UNKNOWN;
1202      }
1203      break;
1204
1205    case spectral_data:
1206      if (hBitStream != NULL)
1207      {
1208        INT spectralBits = 0;
1209
1210          spectralBits = FDKaacEnc_encodeSpectralData( psyOutChannel[ch]->sfbOffsets,
1211                                                       pChSectionData,
1212                                                       qcOutChannel[ch]->quantSpec,
1213                                                       hBitStream );
1214
1215        if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
1216          return AAC_ENC_WRITE_SPEC_ERROR;
1217        }
1218        bitDemand += spectralBits;
1219      }
1220      break;
1221
1222      /* Non data cases */
1223    case adtscrc_start_reg1:
1224      if (hTpEnc != NULL) {
1225        crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
1226      }
1227      break;
1228    case adtscrc_start_reg2:
1229      if (hTpEnc != NULL) {
1230        crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
1231      }
1232      break;
1233    case adtscrc_end_reg1:
1234    case drmcrc_end_reg:
1235      if (hTpEnc != NULL) {
1236        transportEnc_CrcEndReg(hTpEnc, crcReg1);
1237      }
1238      break;
1239    case adtscrc_end_reg2:
1240      if (hTpEnc != NULL) {
1241        transportEnc_CrcEndReg(hTpEnc, crcReg2);
1242      }
1243      break;
1244    case drmcrc_start_reg:
1245      if (hTpEnc != NULL) {
1246        crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
1247      }
1248      break;
1249    case next_channel:
1250      ch = (ch + 1) % numberOfChannels;
1251      break;
1252    case link_sequence:
1253      list = list->next[decision_bit];
1254      i=-1;
1255      break;
1256
1257    default:
1258      error = AAC_ENC_UNKNOWN;
1259      break;
1260    }
1261
1262    if (error != AAC_ENC_OK) {
1263      return error;
1264    }
1265
1266    i++;
1267
1268  } while (list->id[i] != end_of_sequence);
1269
1270bail:
1271  if (pBitDemand != NULL) {
1272    *pBitDemand = bitDemand;
1273  }
1274
1275  return error;
1276}
1277
1278
1279//-----------------------------------------------------------------------------------------------
1280
1281AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
1282                                           CHANNEL_MAPPING *channelMapping,
1283                                           QC_OUT *qcOut,
1284                                           PSY_OUT* psyOut,
1285                                           QC_STATE *qcKernel,
1286                                           AUDIO_OBJECT_TYPE  aot,
1287                                           UINT  syntaxFlags,
1288                                           SCHAR  epConfig
1289                                          )
1290{
1291  HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
1292  AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
1293  int   i, n, doByteAlign = 1;
1294  INT   bitMarkUp;
1295  INT   frameBits;
1296  /* Get first bit of raw data block.
1297     In case of ADTS+PCE, AU would start at PCE.
1298     This is okay because PCE assures alignment. */
1299  UINT alignAnchor = FDKgetValidBits(hBs);
1300
1301  frameBits = bitMarkUp = alignAnchor;
1302
1303
1304  /* Channel element loop */
1305  for (i=0; i<channelMapping->nElements; i++) {
1306
1307    ELEMENT_INFO elInfo = channelMapping->elInfo[i];
1308    INT elementUsedBits = 0;
1309
1310    switch (elInfo.elType)
1311    {
1312        case ID_SCE:      /* single channel */
1313        case ID_CPE:      /* channel pair */
1314        case ID_LFE:      /* low freq effects channel */
1315        {
1316          if ( AAC_ENC_OK != (ErrorStatus = FDKaacEnc_ChannelElementWrite( hTpEnc,
1317                                                      &elInfo,
1318                                                       qcOut->qcElement[i]->qcOutChannel,
1319                                                       psyOut->psyOutElement[i],
1320                                                       psyOut->psyOutElement[i]->psyOutChannel,
1321                                                       syntaxFlags,   /* syntaxFlags (ER tools ...) */
1322                                                       aot,           /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
1323                                                       epConfig,      /* epConfig -1, 0, 1 */
1324                                                       NULL,
1325                                                       0 )) )
1326          {
1327            return ErrorStatus;
1328          }
1329
1330          if ( !(syntaxFlags & AC_ER) )
1331          {
1332            /* Write associated extension payload */
1333            for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1334              FDKaacEnc_writeExtensionData( hTpEnc,
1335                                           &qcOut->qcElement[i]->extension[n],
1336                                            0,
1337                                            alignAnchor,
1338                                            syntaxFlags,
1339                                            aot,
1340                                            epConfig );
1341            }
1342          }
1343        }
1344        break;
1345
1346        /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
1347        default:
1348          return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
1349
1350    }   /* switch */
1351
1352    if(elInfo.elType != ID_DSE) {
1353      elementUsedBits -= bitMarkUp;
1354      bitMarkUp        = FDKgetValidBits(hBs);
1355      elementUsedBits += bitMarkUp;
1356      frameBits       += elementUsedBits;
1357    }
1358
1359  } /* for (i=0; i<channelMapping.nElements; i++) */
1360
1361  if ( (syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM) )
1362  {
1363    UCHAR channelElementExtensionWritten[(8)][(1)]; /* 0: extension not touched, 1: extension already written */
1364
1365    FDKmemclear(channelElementExtensionWritten, sizeof(channelElementExtensionWritten));
1366
1367    if ( syntaxFlags & AC_ELD ) {
1368
1369      for (i=0; i<channelMapping->nElements; i++) {
1370        for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1371
1372          if ( (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA)
1373            || (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA_CRC) )
1374          {
1375            /* Write sbr extension payload */
1376            FDKaacEnc_writeExtensionData( hTpEnc,
1377                                         &qcOut->qcElement[i]->extension[n],
1378                                          0,
1379                                          alignAnchor,
1380                                          syntaxFlags,
1381                                          aot,
1382                                          epConfig );
1383
1384            channelElementExtensionWritten[i][n] = 1;
1385          } /* SBR */
1386        } /* n */
1387      } /* i */
1388    } /* AC_ELD */
1389
1390    for (i=0; i<channelMapping->nElements; i++) {
1391      for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1392
1393        if (channelElementExtensionWritten[i][n]==0)
1394        {
1395          /* Write all ramaining extension payloads in element */
1396          FDKaacEnc_writeExtensionData( hTpEnc,
1397                                       &qcOut->qcElement[i]->extension[n],
1398                                        0,
1399                                        alignAnchor,
1400                                        syntaxFlags,
1401                                        aot,
1402                                        epConfig );
1403        }
1404      } /* n */
1405    } /* i */
1406  } /* if AC_ER */
1407
1408  /* Extend global extension payload table with fill bits */
1409  if ( syntaxFlags & AC_DRM )
1410  {
1411    /* Exception for Drm */
1412    for (n = 0; n < qcOut->nExtensions; n++) {
1413      if ( (qcOut->extension[n].type == EXT_SBR_DATA)
1414        || (qcOut->extension[n].type == EXT_SBR_DATA_CRC) ) {
1415        /* SBR data must be the last extension! */
1416        FDKmemcpy(&qcOut->extension[qcOut->nExtensions], &qcOut->extension[n], sizeof(QC_OUT_EXTENSION));
1417        break;
1418      }
1419    }
1420    /* Do byte alignment after AAC (+ MPS) payload.
1421       Assure that MPS has been written as channel assigned extension payload! */
1422    if (((FDKgetValidBits(hBs)-alignAnchor+(UINT)qcOut->totFillBits)&0x7)!=(UINT)qcOut->alignBits) {
1423      return AAC_ENC_WRITTEN_BITS_ERROR;
1424    }
1425    FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
1426    doByteAlign = 0;
1427
1428  } /* AC_DRM */
1429
1430  /* Add fill data / stuffing bits */
1431  n = qcOut->nExtensions;
1432  qcOut->extension[n].type = EXT_FILL_DATA;
1433  qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
1434  qcOut->nExtensions++;
1435
1436  /* Write global extension payload and fill data */
1437  for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++)
1438  {
1439    FDKaacEnc_writeExtensionData( hTpEnc,
1440                                 &qcOut->extension[n],
1441                                  0,
1442                                  alignAnchor,
1443                                  syntaxFlags,
1444                                  aot,
1445                                  epConfig );
1446
1447    /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */
1448  }
1449
1450  if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) {
1451    FDKwriteBits(hBs, ID_END, EL_ID_BITS);
1452  }
1453
1454  if (doByteAlign) {
1455    /* Assure byte alignment*/
1456    if (((alignAnchor-FDKgetValidBits(hBs))&0x7)!=(UINT)qcOut->alignBits) {
1457      return AAC_ENC_WRITTEN_BITS_ERROR;
1458    }
1459
1460    FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
1461  }
1462
1463  frameBits -= bitMarkUp;
1464  frameBits += FDKgetValidBits(hBs);
1465
1466  transportEnc_EndAccessUnit(hTpEnc, &frameBits);
1467
1468  if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){
1469    return AAC_ENC_WRITTEN_BITS_ERROR;
1470  }
1471
1472  return ErrorStatus;
1473}
1474
1475