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