• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and 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 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This 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
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-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 
103 static const int globalGainOffset = 100;
104 static const int icsReservedBit   = 0;
105 static 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 *****************************************************************************/
FDKaacEnc_encodeSpectralData(INT * sfbOffset,SECTION_DATA * sectionData,SHORT * quantSpectrum,HANDLE_FDK_BITSTREAM hBitStream)116 static 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 *****************************************************************************/
FDKaacEnc_encodeGlobalGain(INT globalGain,INT scalefac,HANDLE_FDK_BITSTREAM hBitStream,INT mdctScale)151 static 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 
FDKaacEnc_encodeIcsInfo(INT blockType,INT windowShape,INT groupingMask,INT maxSfbPerGroup,HANDLE_FDK_BITSTREAM hBitStream,UINT syntaxFlags)173 static 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 *****************************************************************************/
FDKaacEnc_encodeSectionData(SECTION_DATA * sectionData,HANDLE_FDK_BITSTREAM hBitStream,UINT useVCB11)235 static 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 *****************************************************************************/
FDKaacEnc_encodeScaleFactorData(UINT * maxValueInSfb,SECTION_DATA * sectionData,INT * scalefac,HANDLE_FDK_BITSTREAM hBitStream,INT * RESTRICT noiseNrg,const INT * isScale,INT globalGain)292 static 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 *****************************************************************************/
FDKaacEnc_encodeMSInfo(INT sfbCnt,INT grpSfb,INT maxSfb,INT msDigest,INT * jsFlags,HANDLE_FDK_BITSTREAM hBitStream)382 static 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 *****************************************************************************/
FDKaacEnc_encodeTnsDataPresent(TNS_INFO * tnsInfo,INT blockType,HANDLE_FDK_BITSTREAM hBitStream)446 static 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 *****************************************************************************/
FDKaacEnc_encodeTnsData(TNS_INFO * tnsInfo,INT blockType,HANDLE_FDK_BITSTREAM hBitStream)480 static 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 *****************************************************************************/
FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream)602 static 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 *****************************************************************************/
FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream)619 static 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 *****************************************************************************/
FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,EXT_PAYLOAD_TYPE extPayloadType,const UCHAR * extPayloadData,INT extPayloadBits)637 static 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 ******************************************************************************/
FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,INT elementInstanceTag,INT dataPayloadBytes,UCHAR * dataBuffer,UINT alignAnchor)735 static 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 *****************************************************************************/
FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,QC_OUT_EXTENSION * pExtension,INT elInstanceTag,UINT alignAnchor,UINT syntaxFlags,AUDIO_OBJECT_TYPE aot,SCHAR epConfig)822 INT 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 *****************************************************************************/
FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,int alignBits)984 static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, int alignBits)
985 {
986   FDKwriteBits(hBitStream, 0, alignBits);
987 }
988 
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)989 AAC_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 
1270 bail:
1271   if (pBitDemand != NULL) {
1272     *pBitDemand = bitDemand;
1273   }
1274 
1275   return error;
1276 }
1277 
1278 
1279 //-----------------------------------------------------------------------------------------------
1280 
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)1281 AAC_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[(6)][(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