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 *****************************************************************************/
FDKaacEnc_encodeSpectralData(INT * sfbOffset,SECTION_DATA * sectionData,SHORT * quantSpectrum,HANDLE_FDK_BITSTREAM hBitStream)127 static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset,
128 SECTION_DATA *sectionData,
129 SHORT *quantSpectrum,
130 HANDLE_FDK_BITSTREAM hBitStream) {
131 INT i, sfb;
132 INT dbgVal = FDKgetValidBits(hBitStream);
133
134 for (i = 0; i < sectionData->noOfSections; i++) {
135 if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) {
136 /* huffencode spectral data for this huffsection */
137 INT tmp = sectionData->huffsection[i].sfbStart +
138 sectionData->huffsection[i].sfbCnt;
139 for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) {
140 FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb],
141 sfbOffset[sfb + 1] - sfbOffset[sfb],
142 sectionData->huffsection[i].codeBook, hBitStream);
143 }
144 }
145 }
146 return (FDKgetValidBits(hBitStream) - dbgVal);
147 }
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 *****************************************************************************/
FDKaacEnc_encodeGlobalGain(INT globalGain,INT scalefac,HANDLE_FDK_BITSTREAM hBitStream,INT mdctScale)158 static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac,
159 HANDLE_FDK_BITSTREAM hBitStream,
160 INT mdctScale) {
161 if (hBitStream != NULL) {
162 FDKwriteBits(hBitStream,
163 globalGain - scalefac + globalGainOffset -
164 4 * (LOG_NORM_PCM - mdctScale),
165 8);
166 }
167 return (8);
168 }
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
FDKaacEnc_encodeIcsInfo(INT blockType,INT windowShape,INT groupingMask,INT maxSfbPerGroup,HANDLE_FDK_BITSTREAM hBitStream,UINT syntaxFlags)180 static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape,
181 INT groupingMask, INT maxSfbPerGroup,
182 HANDLE_FDK_BITSTREAM hBitStream,
183 UINT syntaxFlags) {
184 INT statBits;
185
186 if (blockType == SHORT_WINDOW) {
187 statBits = 8 + TRANS_FAC - 1;
188 } else {
189 if (syntaxFlags & AC_ELD) {
190 statBits = 6;
191 } else {
192 statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10;
193 }
194 }
195
196 if (hBitStream != NULL) {
197 if (!(syntaxFlags & AC_ELD)) {
198 FDKwriteBits(hBitStream, icsReservedBit, 1);
199 FDKwriteBits(hBitStream, blockType, 2);
200 FDKwriteBits(hBitStream,
201 (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1);
202 }
203
204 switch (blockType) {
205 case LONG_WINDOW:
206 case START_WINDOW:
207 case STOP_WINDOW:
208 FDKwriteBits(hBitStream, maxSfbPerGroup, 6);
209
210 if (!(syntaxFlags &
211 (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */
212 /* No predictor data present */
213 FDKwriteBits(hBitStream, 0, 1);
214 }
215 break;
216
217 case SHORT_WINDOW:
218 FDKwriteBits(hBitStream, maxSfbPerGroup, 4);
219
220 /* Write grouping bits */
221 FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1);
222 break;
223 }
224 }
225
226 return (statBits);
227 }
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 *****************************************************************************/
FDKaacEnc_encodeSectionData(SECTION_DATA * sectionData,HANDLE_FDK_BITSTREAM hBitStream,UINT useVCB11)239 static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
240 HANDLE_FDK_BITSTREAM hBitStream,
241 UINT useVCB11) {
242 if (hBitStream != NULL) {
243 INT sectEscapeVal = 0, sectLenBits = 0;
244 INT sectLen;
245 INT i;
246 INT dbgVal = FDKgetValidBits(hBitStream);
247 INT sectCbBits = 4;
248
249 switch (sectionData->blockType) {
250 case LONG_WINDOW:
251 case START_WINDOW:
252 case STOP_WINDOW:
253 sectEscapeVal = SECT_ESC_VAL_LONG;
254 sectLenBits = SECT_BITS_LONG;
255 break;
256
257 case SHORT_WINDOW:
258 sectEscapeVal = SECT_ESC_VAL_SHORT;
259 sectLenBits = SECT_BITS_SHORT;
260 break;
261 }
262
263 for (i = 0; i < sectionData->noOfSections; i++) {
264 INT codeBook = sectionData->huffsection[i].codeBook;
265
266 FDKwriteBits(hBitStream, codeBook, sectCbBits);
267
268 {
269 sectLen = sectionData->huffsection[i].sfbCnt;
270
271 while (sectLen >= sectEscapeVal) {
272 FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits);
273 sectLen -= sectEscapeVal;
274 }
275 FDKwriteBits(hBitStream, sectLen, sectLenBits);
276 }
277 }
278 return (FDKgetValidBits(hBitStream) - dbgVal);
279 }
280 return (0);
281 }
282
283 /*****************************************************************************
284
285 functionname: FDKaacEnc_encodeScaleFactorData
286 description: encode DPCM coded scale factors
287 returns: none
288 input:
289 output:
290
291 *****************************************************************************/
FDKaacEnc_encodeScaleFactorData(UINT * maxValueInSfb,SECTION_DATA * sectionData,INT * scalefac,HANDLE_FDK_BITSTREAM hBitStream,INT * RESTRICT noiseNrg,const INT * isScale,INT globalGain)292 static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb,
293 SECTION_DATA *sectionData,
294 INT *scalefac,
295 HANDLE_FDK_BITSTREAM hBitStream,
296 INT *RESTRICT noiseNrg,
297 const INT *isScale, INT globalGain) {
298 if (hBitStream != NULL) {
299 INT i, j, lastValScf, deltaScf;
300 INT deltaPns;
301 INT lastValPns = 0;
302 INT noisePCMFlag = TRUE;
303 INT lastValIs;
304
305 INT dbgVal = FDKgetValidBits(hBitStream);
306
307 lastValScf = scalefac[sectionData->firstScf];
308 lastValPns = globalGain - scalefac[sectionData->firstScf] +
309 globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset;
310 lastValIs = 0;
311
312 for (i = 0; i < sectionData->noOfSections; i++) {
313 if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {
314 if ((sectionData->huffsection[i].codeBook ==
315 CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
316 (sectionData->huffsection[i].codeBook ==
317 CODE_BOOK_IS_IN_PHASE_NO)) {
318 INT sfbStart = sectionData->huffsection[i].sfbStart;
319 INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
320 for (j = sfbStart; j < tmp; j++) {
321 INT deltaIs = isScale[j] - lastValIs;
322 lastValIs = isScale[j];
323 if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) {
324 return (1);
325 }
326 } /* sfb */
327 } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) {
328 INT sfbStart = sectionData->huffsection[i].sfbStart;
329 INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
330 for (j = sfbStart; j < tmp; j++) {
331 deltaPns = noiseNrg[j] - lastValPns;
332 lastValPns = noiseNrg[j];
333
334 if (noisePCMFlag) {
335 FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)),
336 PNS_PCM_BITS);
337 noisePCMFlag = FALSE;
338 } else {
339 if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) {
340 return (1);
341 }
342 }
343 } /* sfb */
344 } else {
345 INT tmp = sectionData->huffsection[i].sfbStart +
346 sectionData->huffsection[i].sfbCnt;
347 for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) {
348 /*
349 check if we can repeat the last value to save bits
350 */
351 if (maxValueInSfb[j] == 0)
352 deltaScf = 0;
353 else {
354 deltaScf = -(scalefac[j] - lastValScf);
355 lastValScf = scalefac[j];
356 }
357 if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) {
358 return (1);
359 }
360 } /* sfb */
361 } /* code scalefactor */
362 } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */
363 } /* section loop */
364
365 return (FDKgetValidBits(hBitStream) - dbgVal);
366 } /* if (hBitStream != NULL) */
367
368 return (0);
369 }
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 *****************************************************************************/
FDKaacEnc_encodeMSInfo(INT sfbCnt,INT grpSfb,INT maxSfb,INT msDigest,INT * jsFlags,HANDLE_FDK_BITSTREAM hBitStream)380 static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb,
381 INT msDigest, INT *jsFlags,
382 HANDLE_FDK_BITSTREAM hBitStream) {
383 INT sfb, sfbOff, msBits = 0;
384
385 if (hBitStream != NULL) {
386 switch (msDigest) {
387 case MS_NONE:
388 FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2);
389 msBits += 2;
390 break;
391
392 case MS_ALL:
393 FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2);
394 msBits += 2;
395 break;
396
397 case MS_SOME:
398 FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2);
399 msBits += 2;
400 for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
401 for (sfb = 0; sfb < maxSfb; sfb++) {
402 if (jsFlags[sfbOff + sfb] & MS_ON) {
403 FDKwriteBits(hBitStream, 1, 1);
404 } else {
405 FDKwriteBits(hBitStream, 0, 1);
406 }
407 msBits += 1;
408 }
409 }
410 break;
411 }
412 } else {
413 msBits += 2;
414 if (msDigest == MS_SOME) {
415 for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) {
416 for (sfb = 0; sfb < maxSfb; sfb++) {
417 msBits += 1;
418 }
419 }
420 }
421 }
422 return (msBits);
423 }
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 *****************************************************************************/
FDKaacEnc_encodeTnsDataPresent(TNS_INFO * tnsInfo,INT blockType,HANDLE_FDK_BITSTREAM hBitStream)434 static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType,
435 HANDLE_FDK_BITSTREAM hBitStream) {
436 if ((hBitStream != NULL) && (tnsInfo != NULL)) {
437 INT i, tnsPresent = 0;
438 INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
439
440 for (i = 0; i < numOfWindows; i++) {
441 if (tnsInfo->numOfFilters[i] != 0) {
442 tnsPresent = 1;
443 break;
444 }
445 }
446
447 if (tnsPresent == 0) {
448 FDKwriteBits(hBitStream, 0, 1);
449 } else {
450 FDKwriteBits(hBitStream, 1, 1);
451 }
452 }
453 return (1);
454 }
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 *****************************************************************************/
FDKaacEnc_encodeTnsData(TNS_INFO * tnsInfo,INT blockType,HANDLE_FDK_BITSTREAM hBitStream)465 static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType,
466 HANDLE_FDK_BITSTREAM hBitStream) {
467 INT tnsBits = 0;
468
469 if (tnsInfo != NULL) {
470 INT i, j, k;
471 INT tnsPresent = 0;
472 INT coefBits;
473 INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1);
474
475 for (i = 0; i < numOfWindows; i++) {
476 if (tnsInfo->numOfFilters[i] != 0) {
477 tnsPresent = 1;
478 }
479 }
480
481 if (hBitStream != NULL) {
482 if (tnsPresent == 1) { /* there is data to be written*/
483 for (i = 0; i < numOfWindows; i++) {
484 FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i],
485 (blockType == SHORT_WINDOW ? 1 : 2));
486 tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
487 if (tnsInfo->numOfFilters[i]) {
488 FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1);
489 tnsBits += 1;
490 }
491 for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
492 FDKwriteBits(hBitStream, tnsInfo->length[i][j],
493 (blockType == SHORT_WINDOW ? 4 : 6));
494 tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
495 FDK_ASSERT(tnsInfo->order[i][j] <= 12);
496 FDKwriteBits(hBitStream, tnsInfo->order[i][j],
497 (blockType == SHORT_WINDOW ? 3 : 5));
498 tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
499 if (tnsInfo->order[i][j]) {
500 FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1);
501 tnsBits += 1; /*direction*/
502 if (tnsInfo->coefRes[i] == 4) {
503 coefBits = 3;
504 for (k = 0; k < tnsInfo->order[i][j]; k++) {
505 if (tnsInfo->coef[i][j][k] > 3 ||
506 tnsInfo->coef[i][j][k] < -4) {
507 coefBits = 4;
508 break;
509 }
510 }
511 } else {
512 coefBits = 2;
513 for (k = 0; k < tnsInfo->order[i][j]; k++) {
514 if (tnsInfo->coef[i][j][k] > 1 ||
515 tnsInfo->coef[i][j][k] < -2) {
516 coefBits = 3;
517 break;
518 }
519 }
520 }
521 FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]),
522 1); /*coef_compres*/
523 tnsBits += 1; /*coef_compression */
524 for (k = 0; k < tnsInfo->order[i][j]; k++) {
525 static const INT rmask[] = {0, 1, 3, 7, 15};
526 FDKwriteBits(hBitStream,
527 tnsInfo->coef[i][j][k] & rmask[coefBits],
528 coefBits);
529 tnsBits += coefBits;
530 }
531 }
532 }
533 }
534 }
535 } else {
536 if (tnsPresent != 0) {
537 for (i = 0; i < numOfWindows; i++) {
538 tnsBits += (blockType == SHORT_WINDOW ? 1 : 2);
539 if (tnsInfo->numOfFilters[i]) {
540 tnsBits += 1;
541 for (j = 0; j < tnsInfo->numOfFilters[i]; j++) {
542 tnsBits += (blockType == SHORT_WINDOW ? 4 : 6);
543 tnsBits += (blockType == SHORT_WINDOW ? 3 : 5);
544 if (tnsInfo->order[i][j]) {
545 tnsBits += 1; /*direction*/
546 tnsBits += 1; /*coef_compression */
547 if (tnsInfo->coefRes[i] == 4) {
548 coefBits = 3;
549 for (k = 0; k < tnsInfo->order[i][j]; k++) {
550 if (tnsInfo->coef[i][j][k] > 3 ||
551 tnsInfo->coef[i][j][k] < -4) {
552 coefBits = 4;
553 break;
554 }
555 }
556 } else {
557 coefBits = 2;
558 for (k = 0; k < tnsInfo->order[i][j]; k++) {
559 if (tnsInfo->coef[i][j][k] > 1 ||
560 tnsInfo->coef[i][j][k] < -2) {
561 coefBits = 3;
562 break;
563 }
564 }
565 }
566 for (k = 0; k < tnsInfo->order[i][j]; k++) {
567 tnsBits += coefBits;
568 }
569 }
570 }
571 }
572 }
573 }
574 }
575 } /* (tnsInfo!=NULL) */
576
577 return (tnsBits);
578 }
579
580 /*****************************************************************************
581
582 functionname: FDKaacEnc_encodeGainControlData
583 description: unsupported
584 returns: none
585 input:
586 output:
587
588 *****************************************************************************/
FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream)589 static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) {
590 if (hBitStream != NULL) {
591 FDKwriteBits(hBitStream, 0, 1);
592 }
593 return (1);
594 }
595
596 /*****************************************************************************
597
598 functionname: FDKaacEnc_encodePulseData
599 description: not supported yet (dummy)
600 returns: none
601 input:
602 output:
603
604 *****************************************************************************/
FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream)605 static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) {
606 if (hBitStream != NULL) {
607 FDKwriteBits(hBitStream, 0, 1);
608 }
609 return (1);
610 }
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 *****************************************************************************/
FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,EXT_PAYLOAD_TYPE extPayloadType,const UCHAR * extPayloadData,INT extPayloadBits)621 static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream,
622 EXT_PAYLOAD_TYPE extPayloadType,
623 const UCHAR *extPayloadData,
624 INT extPayloadBits) {
625 #define EXT_TYPE_BITS (4)
626 #define DATA_EL_VERSION_BITS (4)
627 #define FILL_NIBBLE_BITS (4)
628
629 INT extBitsUsed = 0;
630
631 if (extPayloadBits >= EXT_TYPE_BITS) {
632 UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */
633
634 if (hBitStream != NULL) {
635 FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS);
636 }
637 extBitsUsed += EXT_TYPE_BITS;
638
639 switch (extPayloadType) {
640 /* case EXT_SAC_DATA: */
641 case EXT_LDSAC_DATA:
642 if (hBitStream != NULL) {
643 FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */
644 }
645 extBitsUsed += 4;
646 FDK_FALLTHROUGH;
647 case EXT_DYNAMIC_RANGE:
648 case EXT_SBR_DATA:
649 case EXT_SBR_DATA_CRC:
650 if (hBitStream != NULL) {
651 int i, writeBits = extPayloadBits;
652 for (i = 0; writeBits >= 8; i++) {
653 FDKwriteBits(hBitStream, *extPayloadData++, 8);
654 writeBits -= 8;
655 }
656 if (writeBits > 0) {
657 FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
658 writeBits);
659 }
660 }
661 extBitsUsed += extPayloadBits;
662 break;
663
664 case EXT_DATA_ELEMENT: {
665 INT dataElementLength = (extPayloadBits + 7) >> 3;
666 INT cnt = dataElementLength;
667 int loopCounter = 1;
668
669 while (dataElementLength >= 255) {
670 loopCounter++;
671 dataElementLength -= 255;
672 }
673
674 if (hBitStream != NULL) {
675 int i;
676 FDKwriteBits(
677 hBitStream, 0x00,
678 DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */
679
680 for (i = 1; i < loopCounter; i++) {
681 FDKwriteBits(hBitStream, 255, 8);
682 }
683 FDKwriteBits(hBitStream, dataElementLength, 8);
684
685 for (i = 0; i < cnt; i++) {
686 FDKwriteBits(hBitStream, extPayloadData[i], 8);
687 }
688 }
689 extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
690 } break;
691
692 case EXT_FILL_DATA:
693 fillByte = 0xA5;
694 FDK_FALLTHROUGH;
695 case EXT_FIL:
696 default:
697 if (hBitStream != NULL) {
698 int writeBits = extPayloadBits;
699 FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
700 writeBits -=
701 8; /* acount for the extension type and the fill nibble */
702 while (writeBits >= 8) {
703 FDKwriteBits(hBitStream, fillByte, 8);
704 writeBits -= 8;
705 }
706 }
707 extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
708 break;
709 }
710 }
711
712 return (extBitsUsed);
713 }
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 ******************************************************************************/
FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,INT elementInstanceTag,INT dataPayloadBytes,UCHAR * dataBuffer,UINT alignAnchor)724 static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
725 INT elementInstanceTag,
726 INT dataPayloadBytes,
727 UCHAR *dataBuffer,
728 UINT alignAnchor) {
729 #define DATA_BYTE_ALIGN_FLAG (0)
730
731 #define EL_INSTANCE_TAG_BITS (4)
732 #define DATA_BYTE_ALIGN_FLAG_BITS (1)
733 #define DATA_LEN_COUNT_BITS (8)
734 #define DATA_LEN_ESC_COUNT_BITS (8)
735
736 #define MAX_DATA_ALIGN_BITS (7)
737 #define MAX_DSE_DATA_BYTES (510)
738
739 INT dseBitsUsed = 0;
740
741 while (dataPayloadBytes > 0) {
742 int esc_count = -1;
743 int cnt = 0;
744 INT crcReg = -1;
745
746 dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
747 DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
748
749 if (DATA_BYTE_ALIGN_FLAG) {
750 dseBitsUsed += MAX_DATA_ALIGN_BITS;
751 }
752
753 cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
754 if (cnt >= 255) {
755 esc_count = cnt - 255;
756 dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
757 }
758
759 dataPayloadBytes -= cnt;
760 dseBitsUsed += cnt * 8;
761
762 if (hTpEnc != NULL) {
763 HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
764 int i;
765
766 FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
767
768 crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
769
770 FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
771 FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
772
773 /* write length field(s) */
774 if (esc_count >= 0) {
775 FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
776 FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
777 } else {
778 FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
779 }
780
781 if (DATA_BYTE_ALIGN_FLAG) {
782 INT tmp = (INT)FDKgetValidBits(hBitStream);
783 FDKbyteAlign(hBitStream, alignAnchor);
784 /* count actual bits */
785 dseBitsUsed +=
786 (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
787 }
788
789 /* write payload */
790 for (i = 0; i < cnt; i++) {
791 FDKwriteBits(hBitStream, dataBuffer[i], 8);
792 }
793 transportEnc_CrcEndReg(hTpEnc, crcReg);
794 }
795 }
796
797 return (dseBitsUsed);
798 }
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 *****************************************************************************/
FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,QC_OUT_EXTENSION * pExtension,INT elInstanceTag,UINT alignAnchor,UINT syntaxFlags,AUDIO_OBJECT_TYPE aot,SCHAR epConfig)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 SCHAR epConfig) {
815 #define FILL_EL_COUNT_BITS (4)
816 #define FILL_EL_ESC_COUNT_BITS (8)
817 #define MAX_FILL_DATA_BYTES (269)
818
819 HANDLE_FDK_BITSTREAM hBitStream = NULL;
820 INT payloadBits = pExtension->nPayloadBits;
821 INT extBitsUsed = 0;
822
823 if (hTpEnc != NULL) {
824 hBitStream = transportEnc_GetBitstream(hTpEnc);
825 }
826
827 if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
828 {
829 if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
830 (pExtension->type == EXT_SBR_DATA_CRC))) {
831 if (hBitStream != NULL) {
832 int i, writeBits = payloadBits;
833 UCHAR *extPayloadData = pExtension->pPayload;
834
835 for (i = 0; writeBits >= 8; i++) {
836 FDKwriteBits(hBitStream, extPayloadData[i], 8);
837 writeBits -= 8;
838 }
839 if (writeBits > 0) {
840 FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
841 writeBits);
842 }
843 }
844 extBitsUsed += payloadBits;
845 } else {
846 /* ER or scalable syntax -> write extension en bloc */
847 extBitsUsed += FDKaacEnc_writeExtensionPayload(
848 hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
849 }
850 }
851 } 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 if (pExtension->type == EXT_DATA_ELEMENT) {
856 extBitsUsed += FDKaacEnc_writeDataStreamElement(
857 hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
858 pExtension->pPayload, alignAnchor);
859 } else {
860 while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
861 INT cnt, esc_count = -1, alignBits = 7;
862
863 if ((pExtension->type == EXT_FILL_DATA) ||
864 (pExtension->type == EXT_FIL)) {
865 payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
866 if (payloadBits >= 15 * 8) {
867 payloadBits -= FILL_EL_ESC_COUNT_BITS;
868 esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
869 }
870 alignBits = 0;
871 }
872
873 cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);
874
875 if (cnt >= 15) {
876 esc_count = cnt - 15 + 1;
877 }
878
879 if (hBitStream != NULL) {
880 /* write bitstream */
881 FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
882 if (esc_count >= 0) {
883 FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
884 FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
885 } else {
886 FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
887 }
888 }
889
890 extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
891 ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);
892
893 cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
894 extBitsUsed += FDKaacEnc_writeExtensionPayload(
895 hBitStream, pExtension->type, pExtension->pPayload, cnt);
896 payloadBits -= cnt;
897 }
898 }
899 }
900
901 return (extBitsUsed);
902 }
903
904 /*****************************************************************************
905
906 functionname: FDKaacEnc_ByteAlignment
907 description:
908 returns:
909 input:
910 output:
911
912 *****************************************************************************/
FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,int alignBits)913 static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
914 int alignBits) {
915 FDKwriteBits(hBitStream, 0, alignBits);
916 }
917
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 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 AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
923 AAC_ENCODER_ERROR error = AAC_ENC_OK;
924 HANDLE_FDK_BITSTREAM hBitStream = NULL;
925 INT bitDemand = 0;
926 const element_list_t *list;
927 int i, ch, decision_bit;
928 INT crcReg1 = -1, crcReg2 = -1;
929 UCHAR numberOfChannels;
930
931 if (hTpEnc != NULL) {
932 /* Get bitstream handle */
933 hBitStream = transportEnc_GetBitstream(hTpEnc);
934 }
935
936 if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
937 numberOfChannels = 1;
938 } else {
939 numberOfChannels = 2;
940 }
941
942 /* Get channel element sequence table */
943 list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
944 if (list == NULL) {
945 error = AAC_ENC_UNSUPPORTED_AOT;
946 goto bail;
947 }
948
949 if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
950 if (hBitStream != NULL) {
951 FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
952 }
953 bitDemand += EL_ID_BITS;
954 }
955
956 /* Iterate through sequence table */
957 i = 0;
958 ch = 0;
959 decision_bit = 0;
960 do {
961 /* some tmp values */
962 SECTION_DATA *pChSectionData = NULL;
963 INT *pChScf = NULL;
964 UINT *pChMaxValueInSfb = NULL;
965 TNS_INFO *pTnsInfo = NULL;
966 INT chGlobalGain = 0;
967 INT chBlockType = 0;
968 INT chMaxSfbPerGrp = 0;
969 INT chSfbPerGrp = 0;
970 INT chSfbCnt = 0;
971 INT chFirstScf = 0;
972
973 if (minCnt == 0) {
974 if (qcOutChannel != NULL) {
975 pChSectionData = &(qcOutChannel[ch]->sectionData);
976 pChScf = qcOutChannel[ch]->scf;
977 chGlobalGain = qcOutChannel[ch]->globalGain;
978 pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
979 chBlockType = pChSectionData->blockType;
980 chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
981 chSfbPerGrp = pChSectionData->sfbPerGroup;
982 chSfbCnt = pChSectionData->sfbCnt;
983 chFirstScf = pChScf[pChSectionData->firstScf];
984 } else {
985 /* get values from PSY */
986 chSfbCnt = psyOutChannel[ch]->sfbCnt;
987 chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
988 chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
989 }
990 pTnsInfo = &psyOutChannel[ch]->tnsInfo;
991 } /* minCnt==0 */
992
993 if (qcOutChannel == NULL) {
994 chBlockType = psyOutChannel[ch]->lastWindowSequence;
995 }
996
997 switch (list->id[i]) {
998 case element_instance_tag:
999 /* Write element instance tag */
1000 if (hBitStream != NULL) {
1001 FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
1002 }
1003 bitDemand += 4;
1004 break;
1005
1006 case common_window:
1007 /* Write common window flag */
1008 decision_bit = psyOutElement->commonWindow;
1009 if (hBitStream != NULL) {
1010 FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
1011 }
1012 bitDemand += 1;
1013 break;
1014
1015 case ics_info:
1016 /* Write individual channel info */
1017 bitDemand +=
1018 FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
1019 psyOutChannel[ch]->groupingMask,
1020 chMaxSfbPerGrp, hBitStream, syntaxFlags);
1021 break;
1022
1023 case ltp_data_present:
1024 /* Write LTP data present flag */
1025 if (hBitStream != NULL) {
1026 FDKwriteBits(hBitStream, 0, 1);
1027 }
1028 bitDemand += 1;
1029 break;
1030
1031 case ltp_data:
1032 /* Predictor data not supported.
1033 Nothing to do here. */
1034 break;
1035
1036 case ms:
1037 /* Write MS info */
1038 bitDemand += FDKaacEnc_encodeMSInfo(
1039 chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
1040 (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
1041 psyOutElement->toolsInfo.msMask, hBitStream);
1042 break;
1043
1044 case global_gain:
1045 bitDemand += FDKaacEnc_encodeGlobalGain(
1046 chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
1047 break;
1048
1049 case section_data: {
1050 INT siBits = FDKaacEnc_encodeSectionData(
1051 pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
1052 if (hBitStream != NULL) {
1053 if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
1054 error = AAC_ENC_WRITE_SEC_ERROR;
1055 }
1056 }
1057 bitDemand += siBits;
1058 } break;
1059
1060 case scale_factor_data: {
1061 INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
1062 pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
1063 psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
1064 chGlobalGain);
1065 if ((hBitStream != NULL) &&
1066 (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
1067 qcOutChannel[ch]->sectionData.noiseNrgBits))) {
1068 error = AAC_ENC_WRITE_SCAL_ERROR;
1069 }
1070 bitDemand += sfDataBits;
1071 } break;
1072
1073 case esc2_rvlc:
1074 if (syntaxFlags & AC_ER_RVLC) {
1075 /* write RVLC data into bitstream (error sens. cat. 2) */
1076 error = AAC_ENC_UNSUPPORTED_AOT;
1077 }
1078 break;
1079
1080 case pulse:
1081 /* Write pulse data */
1082 bitDemand += FDKaacEnc_encodePulseData(hBitStream);
1083 break;
1084
1085 case tns_data_present:
1086 /* Write TNS data present flag */
1087 bitDemand +=
1088 FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
1089 break;
1090 case tns_data:
1091 /* Write TNS data */
1092 bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
1093 break;
1094
1095 case gain_control_data:
1096 /* Nothing to do here */
1097 break;
1098
1099 case gain_control_data_present:
1100 bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
1101 break;
1102
1103 case esc1_hcr:
1104 if (syntaxFlags & AC_ER_HCR) {
1105 error = AAC_ENC_UNKNOWN;
1106 }
1107 break;
1108
1109 case spectral_data:
1110 if (hBitStream != NULL) {
1111 INT spectralBits = 0;
1112
1113 spectralBits = FDKaacEnc_encodeSpectralData(
1114 psyOutChannel[ch]->sfbOffsets, pChSectionData,
1115 qcOutChannel[ch]->quantSpec, hBitStream);
1116
1117 if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
1118 return AAC_ENC_WRITE_SPEC_ERROR;
1119 }
1120 bitDemand += spectralBits;
1121 }
1122 break;
1123
1124 /* Non data cases */
1125 case adtscrc_start_reg1:
1126 if (hTpEnc != NULL) {
1127 crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
1128 }
1129 break;
1130 case adtscrc_start_reg2:
1131 if (hTpEnc != NULL) {
1132 crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
1133 }
1134 break;
1135 case adtscrc_end_reg1:
1136 case drmcrc_end_reg:
1137 if (hTpEnc != NULL) {
1138 transportEnc_CrcEndReg(hTpEnc, crcReg1);
1139 }
1140 break;
1141 case adtscrc_end_reg2:
1142 if (hTpEnc != NULL) {
1143 transportEnc_CrcEndReg(hTpEnc, crcReg2);
1144 }
1145 break;
1146 case drmcrc_start_reg:
1147 if (hTpEnc != NULL) {
1148 crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
1149 }
1150 break;
1151 case next_channel:
1152 ch = (ch + 1) % numberOfChannels;
1153 break;
1154 case link_sequence:
1155 list = list->next[decision_bit];
1156 i = -1;
1157 break;
1158
1159 default:
1160 error = AAC_ENC_UNKNOWN;
1161 break;
1162 }
1163
1164 if (error != AAC_ENC_OK) {
1165 return error;
1166 }
1167
1168 i++;
1169
1170 } while (list->id[i] != end_of_sequence);
1171
1172 bail:
1173 if (pBitDemand != NULL) {
1174 *pBitDemand = bitDemand;
1175 }
1176
1177 return error;
1178 }
1179
1180 //-----------------------------------------------------------------------------------------------
1181
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 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 UINT syntaxFlags, SCHAR epConfig) {
1188 HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
1189 AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
1190 int i, n, doByteAlign = 1;
1191 INT bitMarkUp;
1192 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 UINT alignAnchor = FDKgetValidBits(hBs);
1197
1198 frameBits = bitMarkUp = alignAnchor;
1199
1200 /* Channel element loop */
1201 for (i = 0; i < channelMapping->nElements; i++) {
1202 ELEMENT_INFO elInfo = channelMapping->elInfo[i];
1203 INT elementUsedBits = 0;
1204
1205 switch (elInfo.elType) {
1206 case ID_SCE: /* single channel */
1207 case ID_CPE: /* channel pair */
1208 case ID_LFE: /* low freq effects channel */
1209 {
1210 if (AAC_ENC_OK !=
1211 (ErrorStatus = FDKaacEnc_ChannelElementWrite(
1212 hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
1213 psyOut->psyOutElement[i],
1214 psyOut->psyOutElement[i]->psyOutChannel,
1215 syntaxFlags, /* syntaxFlags (ER tools ...) */
1216 aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
1217 epConfig, /* epConfig -1, 0, 1 */
1218 NULL, 0))) {
1219 return ErrorStatus;
1220 }
1221
1222 if (!(syntaxFlags & AC_ER)) {
1223 /* Write associated extension payload */
1224 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1225 FDKaacEnc_writeExtensionData(
1226 hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1227 syntaxFlags, aot, epConfig);
1228 }
1229 }
1230 } break;
1231
1232 /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
1233 default:
1234 return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
1235
1236 } /* switch */
1237
1238 if (elInfo.elType != ID_DSE) {
1239 elementUsedBits -= bitMarkUp;
1240 bitMarkUp = FDKgetValidBits(hBs);
1241 elementUsedBits += bitMarkUp;
1242 frameBits += elementUsedBits;
1243 }
1244
1245 } /* for (i=0; i<channelMapping.nElements; i++) */
1246
1247 if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
1248 UCHAR channelElementExtensionWritten[((8))][(
1249 1)]; /* 0: extension not touched, 1: extension already written */
1250
1251 FDKmemclear(channelElementExtensionWritten,
1252 sizeof(channelElementExtensionWritten));
1253
1254 if (syntaxFlags & AC_ELD) {
1255 for (i = 0; i < channelMapping->nElements; i++) {
1256 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1257 if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
1258 (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
1259 /* Write sbr extension payload */
1260 FDKaacEnc_writeExtensionData(
1261 hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1262 syntaxFlags, aot, epConfig);
1263
1264 channelElementExtensionWritten[i][n] = 1;
1265 } /* SBR */
1266 } /* n */
1267 } /* i */
1268 } /* AC_ELD */
1269
1270 for (i = 0; i < channelMapping->nElements; i++) {
1271 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1272 if (channelElementExtensionWritten[i][n] == 0) {
1273 /* Write all ramaining extension payloads in element */
1274 FDKaacEnc_writeExtensionData(hTpEnc,
1275 &qcOut->qcElement[i]->extension[n], 0,
1276 alignAnchor, syntaxFlags, aot, epConfig);
1277 }
1278 } /* n */
1279 } /* i */
1280 } /* if AC_ER */
1281
1282 /* Extend global extension payload table with fill bits */
1283 n = qcOut->nExtensions;
1284
1285 /* Add fill data / stuffing bits */
1286 qcOut->extension[n].type = EXT_FILL_DATA;
1287 qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
1288 qcOut->nExtensions++;
1289
1290 /* Write global extension payload and fill data */
1291 for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) {
1292 FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor,
1293 syntaxFlags, aot, epConfig);
1294
1295 /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
1296 */
1297 }
1298
1299 if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
1300 FDKwriteBits(hBs, ID_END, EL_ID_BITS);
1301 }
1302
1303 if (doByteAlign) {
1304 /* Assure byte alignment*/
1305 if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
1306 return AAC_ENC_WRITTEN_BITS_ERROR;
1307 }
1308
1309 FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
1310 }
1311
1312 frameBits -= bitMarkUp;
1313 frameBits += FDKgetValidBits(hBs);
1314
1315 transportEnc_EndAccessUnit(hTpEnc, &frameBits);
1316
1317 if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) {
1318 return AAC_ENC_WRITTEN_BITS_ERROR;
1319 }
1320
1321 return ErrorStatus;
1322 }
1323