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