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