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