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 case EXT_DYNAMIC_RANGE:
647 case EXT_SBR_DATA:
648 case EXT_SBR_DATA_CRC:
649 if (hBitStream != NULL) {
650 int i, writeBits = extPayloadBits;
651 for (i = 0; writeBits >= 8; i++) {
652 FDKwriteBits(hBitStream, *extPayloadData++, 8);
653 writeBits -= 8;
654 }
655 if (writeBits > 0) {
656 FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits),
657 writeBits);
658 }
659 }
660 extBitsUsed += extPayloadBits;
661 break;
662
663 case EXT_DATA_ELEMENT: {
664 INT dataElementLength = (extPayloadBits + 7) >> 3;
665 INT cnt = dataElementLength;
666 int loopCounter = 1;
667
668 while (dataElementLength >= 255) {
669 loopCounter++;
670 dataElementLength -= 255;
671 }
672
673 if (hBitStream != NULL) {
674 int i;
675 FDKwriteBits(
676 hBitStream, 0x00,
677 DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */
678
679 for (i = 1; i < loopCounter; i++) {
680 FDKwriteBits(hBitStream, 255, 8);
681 }
682 FDKwriteBits(hBitStream, dataElementLength, 8);
683
684 for (i = 0; i < cnt; i++) {
685 FDKwriteBits(hBitStream, extPayloadData[i], 8);
686 }
687 }
688 extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8);
689 } break;
690
691 case EXT_FILL_DATA:
692 fillByte = 0xA5;
693 case EXT_FIL:
694 default:
695 if (hBitStream != NULL) {
696 int writeBits = extPayloadBits;
697 FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS);
698 writeBits -=
699 8; /* acount for the extension type and the fill nibble */
700 while (writeBits >= 8) {
701 FDKwriteBits(hBitStream, fillByte, 8);
702 writeBits -= 8;
703 }
704 }
705 extBitsUsed += FILL_NIBBLE_BITS + (extPayloadBits & ~0x7) - 8;
706 break;
707 }
708 }
709
710 return (extBitsUsed);
711 }
712
713 /*****************************************************************************
714
715 functionname: FDKaacEnc_writeDataStreamElement
716 description: write data stream elements like ancillary data ...
717 returns: the amount of used bits
718 input:
719 output:
720
721 ******************************************************************************/
FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,INT elementInstanceTag,INT dataPayloadBytes,UCHAR * dataBuffer,UINT alignAnchor)722 static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc,
723 INT elementInstanceTag,
724 INT dataPayloadBytes,
725 UCHAR *dataBuffer,
726 UINT alignAnchor) {
727 #define DATA_BYTE_ALIGN_FLAG (0)
728
729 #define EL_INSTANCE_TAG_BITS (4)
730 #define DATA_BYTE_ALIGN_FLAG_BITS (1)
731 #define DATA_LEN_COUNT_BITS (8)
732 #define DATA_LEN_ESC_COUNT_BITS (8)
733
734 #define MAX_DATA_ALIGN_BITS (7)
735 #define MAX_DSE_DATA_BYTES (510)
736
737 INT dseBitsUsed = 0;
738
739 while (dataPayloadBytes > 0) {
740 int esc_count = -1;
741 int cnt = 0;
742 INT crcReg = -1;
743
744 dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS +
745 DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS;
746
747 if (DATA_BYTE_ALIGN_FLAG) {
748 dseBitsUsed += MAX_DATA_ALIGN_BITS;
749 }
750
751 cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes);
752 if (cnt >= 255) {
753 esc_count = cnt - 255;
754 dseBitsUsed += DATA_LEN_ESC_COUNT_BITS;
755 }
756
757 dataPayloadBytes -= cnt;
758 dseBitsUsed += cnt * 8;
759
760 if (hTpEnc != NULL) {
761 HANDLE_FDK_BITSTREAM hBitStream = transportEnc_GetBitstream(hTpEnc);
762 int i;
763
764 FDKwriteBits(hBitStream, ID_DSE, EL_ID_BITS);
765
766 crcReg = transportEnc_CrcStartReg(hTpEnc, 0);
767
768 FDKwriteBits(hBitStream, elementInstanceTag, EL_INSTANCE_TAG_BITS);
769 FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS);
770
771 /* write length field(s) */
772 if (esc_count >= 0) {
773 FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS);
774 FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS);
775 } else {
776 FDKwriteBits(hBitStream, cnt, DATA_LEN_COUNT_BITS);
777 }
778
779 if (DATA_BYTE_ALIGN_FLAG) {
780 INT tmp = (INT)FDKgetValidBits(hBitStream);
781 FDKbyteAlign(hBitStream, alignAnchor);
782 /* count actual bits */
783 dseBitsUsed +=
784 (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS;
785 }
786
787 /* write payload */
788 for (i = 0; i < cnt; i++) {
789 FDKwriteBits(hBitStream, dataBuffer[i], 8);
790 }
791 transportEnc_CrcEndReg(hTpEnc, crcReg);
792 }
793 }
794
795 return (dseBitsUsed);
796 }
797
798 /*****************************************************************************
799
800 functionname: FDKaacEnc_writeExtensionData
801 description: write extension payload to bitstream
802 returns: number of written bits
803 input:
804 output:
805
806 *****************************************************************************/
FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,QC_OUT_EXTENSION * pExtension,INT elInstanceTag,UINT alignAnchor,UINT syntaxFlags,AUDIO_OBJECT_TYPE aot,SCHAR epConfig)807 INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc,
808 QC_OUT_EXTENSION *pExtension,
809 INT elInstanceTag, /* for DSE only */
810 UINT alignAnchor, /* for DSE only */
811 UINT syntaxFlags, AUDIO_OBJECT_TYPE aot,
812 SCHAR epConfig) {
813 #define FILL_EL_COUNT_BITS (4)
814 #define FILL_EL_ESC_COUNT_BITS (8)
815 #define MAX_FILL_DATA_BYTES (269)
816
817 HANDLE_FDK_BITSTREAM hBitStream = NULL;
818 INT payloadBits = pExtension->nPayloadBits;
819 INT extBitsUsed = 0;
820
821 if (hTpEnc != NULL) {
822 hBitStream = transportEnc_GetBitstream(hTpEnc);
823 }
824
825 if (syntaxFlags & (AC_SCALABLE | AC_ER)) {
826 {
827 if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) ||
828 (pExtension->type == EXT_SBR_DATA_CRC))) {
829 if (hBitStream != NULL) {
830 int i, writeBits = payloadBits;
831 UCHAR *extPayloadData = pExtension->pPayload;
832
833 for (i = 0; writeBits >= 8; i++) {
834 FDKwriteBits(hBitStream, extPayloadData[i], 8);
835 writeBits -= 8;
836 }
837 if (writeBits > 0) {
838 FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits),
839 writeBits);
840 }
841 }
842 extBitsUsed += payloadBits;
843 } else {
844 /* ER or scalable syntax -> write extension en bloc */
845 extBitsUsed += FDKaacEnc_writeExtensionPayload(
846 hBitStream, pExtension->type, pExtension->pPayload, payloadBits);
847 }
848 }
849 } else {
850 /* We have normal GA bitstream payload (AOT 2,5,29) so pack
851 the data into a fill elements or DSEs */
852
853 if (pExtension->type == EXT_DATA_ELEMENT) {
854 extBitsUsed += FDKaacEnc_writeDataStreamElement(
855 hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3,
856 pExtension->pPayload, alignAnchor);
857 } else {
858 while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) {
859 INT cnt, esc_count = -1, alignBits = 7;
860
861 if ((pExtension->type == EXT_FILL_DATA) ||
862 (pExtension->type == EXT_FIL)) {
863 payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS;
864 if (payloadBits >= 15 * 8) {
865 payloadBits -= FILL_EL_ESC_COUNT_BITS;
866 esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */
867 }
868 alignBits = 0;
869 }
870
871 cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3);
872
873 if (cnt >= 15) {
874 esc_count = cnt - 15 + 1;
875 }
876
877 if (hBitStream != NULL) {
878 /* write bitstream */
879 FDKwriteBits(hBitStream, ID_FIL, EL_ID_BITS);
880 if (esc_count >= 0) {
881 FDKwriteBits(hBitStream, 15, FILL_EL_COUNT_BITS);
882 FDKwriteBits(hBitStream, esc_count, FILL_EL_ESC_COUNT_BITS);
883 } else {
884 FDKwriteBits(hBitStream, cnt, FILL_EL_COUNT_BITS);
885 }
886 }
887
888 extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS +
889 ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0);
890
891 cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */
892 extBitsUsed += FDKaacEnc_writeExtensionPayload(
893 hBitStream, pExtension->type, pExtension->pPayload, cnt);
894 payloadBits -= cnt;
895 }
896 }
897 }
898
899 return (extBitsUsed);
900 }
901
902 /*****************************************************************************
903
904 functionname: FDKaacEnc_ByteAlignment
905 description:
906 returns:
907 input:
908 output:
909
910 *****************************************************************************/
FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,int alignBits)911 static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream,
912 int alignBits) {
913 FDKwriteBits(hBitStream, 0, alignBits);
914 }
915
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)916 AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite(
917 HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo,
918 QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement,
919 PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags,
920 AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) {
921 AAC_ENCODER_ERROR error = AAC_ENC_OK;
922 HANDLE_FDK_BITSTREAM hBitStream = NULL;
923 INT bitDemand = 0;
924 const element_list_t *list;
925 int i, ch, decision_bit;
926 INT crcReg1 = -1, crcReg2 = -1;
927 UCHAR numberOfChannels;
928
929 if (hTpEnc != NULL) {
930 /* Get bitstream handle */
931 hBitStream = transportEnc_GetBitstream(hTpEnc);
932 }
933
934 if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) {
935 numberOfChannels = 1;
936 } else {
937 numberOfChannels = 2;
938 }
939
940 /* Get channel element sequence table */
941 list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0);
942 if (list == NULL) {
943 error = AAC_ENC_UNSUPPORTED_AOT;
944 goto bail;
945 }
946
947 if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
948 if (hBitStream != NULL) {
949 FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS);
950 }
951 bitDemand += EL_ID_BITS;
952 }
953
954 /* Iterate through sequence table */
955 i = 0;
956 ch = 0;
957 decision_bit = 0;
958 do {
959 /* some tmp values */
960 SECTION_DATA *pChSectionData = NULL;
961 INT *pChScf = NULL;
962 UINT *pChMaxValueInSfb = NULL;
963 TNS_INFO *pTnsInfo = NULL;
964 INT chGlobalGain = 0;
965 INT chBlockType = 0;
966 INT chMaxSfbPerGrp = 0;
967 INT chSfbPerGrp = 0;
968 INT chSfbCnt = 0;
969 INT chFirstScf = 0;
970
971 if (minCnt == 0) {
972 if (qcOutChannel != NULL) {
973 pChSectionData = &(qcOutChannel[ch]->sectionData);
974 pChScf = qcOutChannel[ch]->scf;
975 chGlobalGain = qcOutChannel[ch]->globalGain;
976 pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb;
977 chBlockType = pChSectionData->blockType;
978 chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup;
979 chSfbPerGrp = pChSectionData->sfbPerGroup;
980 chSfbCnt = pChSectionData->sfbCnt;
981 chFirstScf = pChScf[pChSectionData->firstScf];
982 } else {
983 /* get values from PSY */
984 chSfbCnt = psyOutChannel[ch]->sfbCnt;
985 chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup;
986 chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup;
987 }
988 pTnsInfo = &psyOutChannel[ch]->tnsInfo;
989 } /* minCnt==0 */
990
991 if (qcOutChannel == NULL) {
992 chBlockType = psyOutChannel[ch]->lastWindowSequence;
993 }
994
995 switch (list->id[i]) {
996 case element_instance_tag:
997 /* Write element instance tag */
998 if (hBitStream != NULL) {
999 FDKwriteBits(hBitStream, pElInfo->instanceTag, 4);
1000 }
1001 bitDemand += 4;
1002 break;
1003
1004 case common_window:
1005 /* Write common window flag */
1006 decision_bit = psyOutElement->commonWindow;
1007 if (hBitStream != NULL) {
1008 FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1);
1009 }
1010 bitDemand += 1;
1011 break;
1012
1013 case ics_info:
1014 /* Write individual channel info */
1015 bitDemand +=
1016 FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape,
1017 psyOutChannel[ch]->groupingMask,
1018 chMaxSfbPerGrp, hBitStream, syntaxFlags);
1019 break;
1020
1021 case ltp_data_present:
1022 /* Write LTP data present flag */
1023 if (hBitStream != NULL) {
1024 FDKwriteBits(hBitStream, 0, 1);
1025 }
1026 bitDemand += 1;
1027 break;
1028
1029 case ltp_data:
1030 /* Predictor data not supported.
1031 Nothing to do here. */
1032 break;
1033
1034 case ms:
1035 /* Write MS info */
1036 bitDemand += FDKaacEnc_encodeMSInfo(
1037 chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp,
1038 (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE,
1039 psyOutElement->toolsInfo.msMask, hBitStream);
1040 break;
1041
1042 case global_gain:
1043 bitDemand += FDKaacEnc_encodeGlobalGain(
1044 chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale);
1045 break;
1046
1047 case section_data: {
1048 INT siBits = FDKaacEnc_encodeSectionData(
1049 pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0);
1050 if (hBitStream != NULL) {
1051 if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) {
1052 error = AAC_ENC_WRITE_SEC_ERROR;
1053 }
1054 }
1055 bitDemand += siBits;
1056 } break;
1057
1058 case scale_factor_data: {
1059 INT sfDataBits = FDKaacEnc_encodeScaleFactorData(
1060 pChMaxValueInSfb, pChSectionData, pChScf, hBitStream,
1061 psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale,
1062 chGlobalGain);
1063 if ((hBitStream != NULL) &&
1064 (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits +
1065 qcOutChannel[ch]->sectionData.noiseNrgBits))) {
1066 error = AAC_ENC_WRITE_SCAL_ERROR;
1067 }
1068 bitDemand += sfDataBits;
1069 } break;
1070
1071 case esc2_rvlc:
1072 if (syntaxFlags & AC_ER_RVLC) {
1073 /* write RVLC data into bitstream (error sens. cat. 2) */
1074 error = AAC_ENC_UNSUPPORTED_AOT;
1075 }
1076 break;
1077
1078 case pulse:
1079 /* Write pulse data */
1080 bitDemand += FDKaacEnc_encodePulseData(hBitStream);
1081 break;
1082
1083 case tns_data_present:
1084 /* Write TNS data present flag */
1085 bitDemand +=
1086 FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream);
1087 break;
1088 case tns_data:
1089 /* Write TNS data */
1090 bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream);
1091 break;
1092
1093 case gain_control_data:
1094 /* Nothing to do here */
1095 break;
1096
1097 case gain_control_data_present:
1098 bitDemand += FDKaacEnc_encodeGainControlData(hBitStream);
1099 break;
1100
1101 case esc1_hcr:
1102 if (syntaxFlags & AC_ER_HCR) {
1103 error = AAC_ENC_UNKNOWN;
1104 }
1105 break;
1106
1107 case spectral_data:
1108 if (hBitStream != NULL) {
1109 INT spectralBits = 0;
1110
1111 spectralBits = FDKaacEnc_encodeSpectralData(
1112 psyOutChannel[ch]->sfbOffsets, pChSectionData,
1113 qcOutChannel[ch]->quantSpec, hBitStream);
1114
1115 if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) {
1116 return AAC_ENC_WRITE_SPEC_ERROR;
1117 }
1118 bitDemand += spectralBits;
1119 }
1120 break;
1121
1122 /* Non data cases */
1123 case adtscrc_start_reg1:
1124 if (hTpEnc != NULL) {
1125 crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192);
1126 }
1127 break;
1128 case adtscrc_start_reg2:
1129 if (hTpEnc != NULL) {
1130 crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128);
1131 }
1132 break;
1133 case adtscrc_end_reg1:
1134 case drmcrc_end_reg:
1135 if (hTpEnc != NULL) {
1136 transportEnc_CrcEndReg(hTpEnc, crcReg1);
1137 }
1138 break;
1139 case adtscrc_end_reg2:
1140 if (hTpEnc != NULL) {
1141 transportEnc_CrcEndReg(hTpEnc, crcReg2);
1142 }
1143 break;
1144 case drmcrc_start_reg:
1145 if (hTpEnc != NULL) {
1146 crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0);
1147 }
1148 break;
1149 case next_channel:
1150 ch = (ch + 1) % numberOfChannels;
1151 break;
1152 case link_sequence:
1153 list = list->next[decision_bit];
1154 i = -1;
1155 break;
1156
1157 default:
1158 error = AAC_ENC_UNKNOWN;
1159 break;
1160 }
1161
1162 if (error != AAC_ENC_OK) {
1163 return error;
1164 }
1165
1166 i++;
1167
1168 } while (list->id[i] != end_of_sequence);
1169
1170 bail:
1171 if (pBitDemand != NULL) {
1172 *pBitDemand = bitDemand;
1173 }
1174
1175 return error;
1176 }
1177
1178 //-----------------------------------------------------------------------------------------------
1179
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)1180 AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc,
1181 CHANNEL_MAPPING *channelMapping,
1182 QC_OUT *qcOut, PSY_OUT *psyOut,
1183 QC_STATE *qcKernel,
1184 AUDIO_OBJECT_TYPE aot,
1185 UINT syntaxFlags, SCHAR epConfig) {
1186 HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc);
1187 AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK;
1188 int i, n, doByteAlign = 1;
1189 INT bitMarkUp;
1190 INT frameBits;
1191 /* Get first bit of raw data block.
1192 In case of ADTS+PCE, AU would start at PCE.
1193 This is okay because PCE assures alignment. */
1194 UINT alignAnchor = FDKgetValidBits(hBs);
1195
1196 frameBits = bitMarkUp = alignAnchor;
1197
1198 /* Channel element loop */
1199 for (i = 0; i < channelMapping->nElements; i++) {
1200 ELEMENT_INFO elInfo = channelMapping->elInfo[i];
1201 INT elementUsedBits = 0;
1202
1203 switch (elInfo.elType) {
1204 case ID_SCE: /* single channel */
1205 case ID_CPE: /* channel pair */
1206 case ID_LFE: /* low freq effects channel */
1207 {
1208 if (AAC_ENC_OK !=
1209 (ErrorStatus = FDKaacEnc_ChannelElementWrite(
1210 hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel,
1211 psyOut->psyOutElement[i],
1212 psyOut->psyOutElement[i]->psyOutChannel,
1213 syntaxFlags, /* syntaxFlags (ER tools ...) */
1214 aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */
1215 epConfig, /* epConfig -1, 0, 1 */
1216 NULL, 0))) {
1217 return ErrorStatus;
1218 }
1219
1220 if (!(syntaxFlags & AC_ER)) {
1221 /* Write associated extension payload */
1222 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1223 FDKaacEnc_writeExtensionData(
1224 hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1225 syntaxFlags, aot, epConfig);
1226 }
1227 }
1228 } break;
1229
1230 /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */
1231 default:
1232 return AAC_ENC_INVALID_ELEMENTINFO_TYPE;
1233
1234 } /* switch */
1235
1236 if (elInfo.elType != ID_DSE) {
1237 elementUsedBits -= bitMarkUp;
1238 bitMarkUp = FDKgetValidBits(hBs);
1239 elementUsedBits += bitMarkUp;
1240 frameBits += elementUsedBits;
1241 }
1242
1243 } /* for (i=0; i<channelMapping.nElements; i++) */
1244
1245 if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) {
1246 UCHAR channelElementExtensionWritten[((8))][(
1247 1)]; /* 0: extension not touched, 1: extension already written */
1248
1249 FDKmemclear(channelElementExtensionWritten,
1250 sizeof(channelElementExtensionWritten));
1251
1252 if (syntaxFlags & AC_ELD) {
1253 for (i = 0; i < channelMapping->nElements; i++) {
1254 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1255 if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) ||
1256 (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) {
1257 /* Write sbr extension payload */
1258 FDKaacEnc_writeExtensionData(
1259 hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor,
1260 syntaxFlags, aot, epConfig);
1261
1262 channelElementExtensionWritten[i][n] = 1;
1263 } /* SBR */
1264 } /* n */
1265 } /* i */
1266 } /* AC_ELD */
1267
1268 for (i = 0; i < channelMapping->nElements; i++) {
1269 for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) {
1270 if (channelElementExtensionWritten[i][n] == 0) {
1271 /* Write all ramaining extension payloads in element */
1272 FDKaacEnc_writeExtensionData(hTpEnc,
1273 &qcOut->qcElement[i]->extension[n], 0,
1274 alignAnchor, syntaxFlags, aot, epConfig);
1275 }
1276 } /* n */
1277 } /* i */
1278 } /* if AC_ER */
1279
1280 /* Extend global extension payload table with fill bits */
1281 n = qcOut->nExtensions;
1282
1283 /* Add fill data / stuffing bits */
1284 qcOut->extension[n].type = EXT_FILL_DATA;
1285 qcOut->extension[n].nPayloadBits = qcOut->totFillBits;
1286 qcOut->nExtensions++;
1287
1288 /* Write global extension payload and fill data */
1289 for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) {
1290 FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor,
1291 syntaxFlags, aot, epConfig);
1292
1293 /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here
1294 */
1295 }
1296
1297 if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) {
1298 FDKwriteBits(hBs, ID_END, EL_ID_BITS);
1299 }
1300
1301 if (doByteAlign) {
1302 /* Assure byte alignment*/
1303 if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) {
1304 return AAC_ENC_WRITTEN_BITS_ERROR;
1305 }
1306
1307 FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits);
1308 }
1309
1310 frameBits -= bitMarkUp;
1311 frameBits += FDKgetValidBits(hBs);
1312
1313 transportEnc_EndAccessUnit(hTpEnc, &frameBits);
1314
1315 if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) {
1316 return AAC_ENC_WRITTEN_BITS_ERROR;
1317 }
1318
1319 return ErrorStatus;
1320 }
1321