1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 � Copyright 1995 - 2015 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-4 AAC Encoder **************************
85
86 Author(s):
87 Description:
88
89 ******************************************************************************/
90
91 #include "tpenc_latm.h"
92
93
94 #include "genericStds.h"
95
96 static const short celpFrameLengthTable[64] = {
97 154, 170, 186, 147, 156, 165, 114, 120,
98 186, 126, 132, 138, 142, 146, 154, 166,
99 174, 182, 190, 198, 206, 210, 214, 110,
100 114, 118, 120, 122, 218, 230, 242, 254,
101 266, 278, 286, 294, 318, 342, 358, 374,
102 390, 406, 422, 136, 142, 148, 154, 160,
103 166, 170, 174, 186, 198, 206, 214, 222,
104 230, 238, 216, 160, 280, 338, 0, 0
105 };
106
107 /*******
108 write value to transport stream
109 first two bits define the size of the value itself
110 then the value itself, with a size of 0-3 bytes
111 *******/
112 static
transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs,int value)113 UINT transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs, int value)
114 {
115 UCHAR valueBytes = 4;
116 unsigned int bitsWritten = 0;
117 int i;
118
119 if ( value < (1<<8) ) {
120 valueBytes = 1;
121 } else if ( value < (1<<16) ) {
122 valueBytes = 2;
123 } else if ( value < (1<<24) ) {
124 valueBytes = 3;
125 } else {
126 valueBytes = 4;
127 }
128
129 FDKwriteBits(hBs, valueBytes-1, 2 ); /* size of value in Bytes */
130 for (i=0; i<valueBytes; i++) {
131 /* write most significant Byte first */
132 FDKwriteBits(hBs, (UCHAR)(value>>((valueBytes-1-i)<<3)), 8);
133 }
134
135 bitsWritten = (valueBytes<<3)+2;
136
137 return bitsWritten;
138 }
139
140 static
transportEnc_LatmCountFixBitDemandHeader(HANDLE_LATM_STREAM hAss)141 UINT transportEnc_LatmCountFixBitDemandHeader ( HANDLE_LATM_STREAM hAss )
142 {
143 int bitDemand = 0;
144 int insertSetupData = 0 ;
145
146 /* only if start of new latm frame */
147 if (hAss->subFrameCnt==0)
148 {
149 /* AudioSyncStream */
150
151 if (hAss->tt == TT_MP4_LOAS) {
152 bitDemand += 11 ; /* syncword */
153 bitDemand += 13 ; /* audioMuxLengthBytes */
154 }
155
156 /* AudioMuxElement*/
157
158 /* AudioMuxElement::Stream Mux Config */
159 if (hAss->muxConfigPeriod > 0) {
160 insertSetupData = (hAss->latmFrameCounter == 0);
161 } else {
162 insertSetupData = 0;
163 }
164
165 if (hAss->tt != TT_MP4_LATM_MCP0) {
166 /* AudioMuxElement::useSameStreamMux Flag */
167 bitDemand+=1;
168
169 if( insertSetupData ) {
170 bitDemand += hAss->streamMuxConfigBits;
171 }
172 }
173
174 /* AudioMuxElement::otherDataBits */
175 bitDemand += 8*hAss->otherDataLenBytes;
176
177 /* AudioMuxElement::ByteAlign */
178 if ( bitDemand % 8 ) {
179 hAss->fillBits = 8 - (bitDemand % 8);
180 bitDemand += hAss->fillBits ;
181 } else {
182 hAss->fillBits = 0;
183 }
184 }
185
186 return bitDemand ;
187 }
188
189 static
transportEnc_LatmCountVarBitDemandHeader(HANDLE_LATM_STREAM hAss,unsigned int streamDataLength)190 UINT transportEnc_LatmCountVarBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength )
191 {
192 int bitDemand = 0;
193 int prog, layer;
194
195 /* Payload Length Info*/
196 if( hAss->allStreamsSameTimeFraming ) {
197 for( prog=0; prog<hAss->noProgram; prog++ ) {
198 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) {
199 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
200
201 if( p_linfo->streamID >= 0 ) {
202 switch( p_linfo->frameLengthType ) {
203 case 0:
204 if ( streamDataLength > 0 ) {
205 streamDataLength -= bitDemand ;
206 while( streamDataLength >= (255<<3) ) {
207 bitDemand+=8;
208 streamDataLength -= (255<<3);
209 }
210 bitDemand += 8;
211 }
212 break;
213
214 case 1:
215 case 4:
216 case 6:
217 bitDemand += 2;
218 break;
219
220 default:
221 return 0;
222 }
223 }
224 }
225 }
226 } else {
227 /* there are many possibilities to use this mechanism. */
228 switch( hAss->varMode ) {
229 case LATMVAR_SIMPLE_SEQUENCE: {
230 /* Use the sequence generated by the encoder */
231 //int streamCntPosition = transportEnc_SetWritePointer( hAss->hAssemble, 0 );
232 //int streamCntPosition = FDKgetValidBits( hAss->hAssemble );
233 bitDemand+=4;
234
235 hAss->varStreamCnt = 0;
236 for( prog=0; prog<hAss->noProgram; prog++ ) {
237 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) {
238 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
239
240 if( p_linfo->streamID >= 0 ) {
241
242 bitDemand+=4; /* streamID */
243 switch( p_linfo->frameLengthType ) {
244 case 0:
245 streamDataLength -= bitDemand ;
246 while( streamDataLength >= (255<<3) ) {
247 bitDemand+=8;
248 streamDataLength -= (255<<3);
249 }
250
251 bitDemand += 8;
252 break;
253 /*bitDemand += 1; endFlag
254 break;*/
255
256 case 1:
257 case 4:
258 case 6:
259
260 break;
261
262 default:
263 return 0;
264 }
265 hAss->varStreamCnt++;
266 }
267 }
268 }
269 bitDemand+=4;
270 //transportEnc_UpdateBitstreamField( hAss->hAssemble, streamCntPosition, hAss->varStreamCnt-1, 4 );
271 //UINT pos = streamCntPosition-FDKgetValidBits(hAss->hAssemble);
272 //FDKpushBack( hAss->hAssemble, pos);
273 //FDKwriteBits( hAss->hAssemble, hAss->varStreamCnt-1, 4);
274 //FDKpushFor( hAss->hAssemble, pos-4);
275 }
276 break;
277
278 default:
279 return 0;
280 }
281 }
282
283 return bitDemand ;
284 }
285
286 TRANSPORTENC_ERROR
CreateStreamMuxConfig(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int bufferFullness,CSTpCallBacks * cb)287 CreateStreamMuxConfig(
288 HANDLE_LATM_STREAM hAss,
289 HANDLE_FDK_BITSTREAM hBs,
290 int bufferFullness,
291 CSTpCallBacks *cb
292 )
293 {
294 INT streamIDcnt, tmp;
295 int layer, prog;
296
297 USHORT coreFrameOffset=0;
298
299 hAss->taraBufferFullness = 0xFF;
300 hAss->audioMuxVersionA = 0; /* for future extensions */
301 hAss->streamMuxConfigBits = 0;
302
303 FDKwriteBits( hBs, hAss->audioMuxVersion, 1 ); /* audioMuxVersion */
304 hAss->streamMuxConfigBits += 1;
305
306 if ( hAss->audioMuxVersion == 1 ) {
307 FDKwriteBits( hBs, hAss->audioMuxVersionA, 1 ); /* audioMuxVersionA */
308 hAss->streamMuxConfigBits+=1;
309 }
310
311 if ( hAss->audioMuxVersionA == 0 )
312 {
313 if ( hAss->audioMuxVersion == 1 ) {
314 hAss->streamMuxConfigBits+= transportEnc_LatmWriteValue( hBs, hAss->taraBufferFullness );/* taraBufferFullness */
315 }
316 FDKwriteBits( hBs, hAss->allStreamsSameTimeFraming ? 1:0, 1 ); /* allStreamsSameTimeFraming */
317 FDKwriteBits( hBs, hAss->noSubframes-1, 6 ); /* Number of Subframes */
318 FDKwriteBits( hBs, hAss->noProgram-1, 4 ); /* Number of Programs */
319
320 hAss->streamMuxConfigBits+=11;
321
322 streamIDcnt = 0;
323 for( prog=0; prog<hAss->noProgram; prog++ ) {
324 int transLayer = 0;
325
326 FDKwriteBits( hBs, hAss->noLayer[prog]-1, 3 );
327 hAss->streamMuxConfigBits+=3;
328
329 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) {
330 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
331 CODER_CONFIG *p_lci = hAss->config[prog][layer];
332
333 p_linfo->streamID = -1;
334
335 if( hAss->config[prog][layer] != NULL ) {
336 int useSameConfig = 0;
337
338 if( transLayer > 0 ) {
339 FDKwriteBits( hBs, useSameConfig ? 1 : 0, 1 );
340 hAss->streamMuxConfigBits+=1;
341 }
342 if( (useSameConfig == 0) || (transLayer==0) ) {
343 const UINT alignAnchor = FDKgetValidBits(hBs);
344
345 transportEnc_writeASC(
346 hBs,
347 hAss->config[prog][layer],
348 cb
349 );
350
351 if ( hAss->audioMuxVersion == 1 ) {
352 UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
353 FDKbyteAlign(hBs, alignAnchor);
354 ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
355 FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
356
357 transportEnc_LatmWriteValue(hBs, ascLen);
358
359 transportEnc_writeASC(
360 hBs,
361 hAss->config[prog][layer],
362 cb
363 );
364
365 FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
366 }
367
368 hAss->streamMuxConfigBits += FDKgetValidBits(hBs) - alignAnchor; /* add asc length to smc summary */
369 }
370 transLayer++;
371
372 if( !hAss->allStreamsSameTimeFraming ) {
373 if( streamIDcnt >= LATM_MAX_STREAM_ID )
374 return TRANSPORTENC_INVALID_CONFIG;
375 }
376 p_linfo->streamID = streamIDcnt++;
377
378 switch( p_lci->aot ) {
379 case AOT_AAC_MAIN :
380 case AOT_AAC_LC :
381 case AOT_AAC_SSR :
382 case AOT_AAC_LTP :
383 case AOT_AAC_SCAL :
384 case AOT_ER_AAC_LD :
385 case AOT_ER_AAC_ELD :
386 case AOT_USAC:
387 p_linfo->frameLengthType = 0;
388
389 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
390 FDKwriteBits( hBs, bufferFullness, 8 ); /* bufferFullness */
391 hAss->streamMuxConfigBits+=11;
392
393 if ( !hAss->allStreamsSameTimeFraming ) {
394 CODER_CONFIG *p_lci_prev = hAss->config[prog][layer-1];
395 if ( ((p_lci->aot == AOT_AAC_SCAL) || (p_lci->aot == AOT_ER_AAC_SCAL)) &&
396 ((p_lci_prev->aot == AOT_CELP) || (p_lci_prev->aot == AOT_ER_CELP)) ) {
397 FDKwriteBits( hBs, coreFrameOffset, 6 ); /* coreFrameOffset */
398 hAss->streamMuxConfigBits+=6;
399 }
400 }
401 break;
402
403 case AOT_TWIN_VQ:
404 p_linfo->frameLengthType = 1;
405 tmp = ( (p_lci->bitsFrame+7) >> 3 ) - 20; /* transmission frame length in bytes */
406 if( (tmp < 0) ) {
407 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
408 }
409 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
410 FDKwriteBits( hBs, tmp, 9 );
411 hAss->streamMuxConfigBits+=12;
412
413 p_linfo->frameLengthBits = (tmp+20) << 3;
414 break;
415
416 case AOT_CELP:
417 p_linfo->frameLengthType = 4;
418 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
419 hAss->streamMuxConfigBits+=3;
420 {
421 int i;
422 for( i=0; i<62; i++ ) {
423 if( celpFrameLengthTable[i] == p_lci->bitsFrame )
424 break;
425 }
426 if( i>=62 ) {
427 return TRANSPORTENC_INVALID_CELP_FRAME_LENGTH;
428 }
429
430 FDKwriteBits( hBs, i, 6 ); /* CELPframeLengthTabelIndex */
431 hAss->streamMuxConfigBits+=6;
432 }
433 p_linfo->frameLengthBits = p_lci->bitsFrame;
434 break;
435
436 case AOT_HVXC:
437 p_linfo->frameLengthType = 6;
438 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
439 hAss->streamMuxConfigBits+=3;
440 {
441 int i;
442
443 if( p_lci->bitsFrame == 40 ) {
444 i = 0;
445 } else if( p_lci->bitsFrame == 80 ) {
446 i = 1;
447 } else {
448 return TRANSPORTENC_INVALID_FRAME_BITS;
449 }
450 FDKwriteBits( hBs, i, 1 ); /* HVXCframeLengthTableIndex */
451 hAss->streamMuxConfigBits+=1;
452 }
453 p_linfo->frameLengthBits = p_lci->bitsFrame;
454 break;
455
456 case AOT_NULL_OBJECT:
457 default:
458 return TRANSPORTENC_INVALID_AOT;
459 }
460 }
461 }
462 }
463
464 FDKwriteBits( hBs, (hAss->otherDataLenBytes>0) ? 1:0, 1 ); /* otherDataPresent */
465 hAss->streamMuxConfigBits+=1;
466
467 if( hAss->otherDataLenBytes > 0 ) {
468
469 INT otherDataLenTmp = hAss->otherDataLenBytes;
470 INT escCnt = 0;
471 INT otherDataLenEsc = 1;
472
473 while(otherDataLenTmp) {
474 otherDataLenTmp >>= 8;
475 escCnt ++;
476 }
477
478 do {
479 otherDataLenTmp = (hAss->otherDataLenBytes>>(escCnt*8)) & 0xFF;
480 escCnt--;
481 otherDataLenEsc = escCnt>0;
482
483 FDKwriteBits( hBs, otherDataLenEsc, 1 );
484 FDKwriteBits( hBs, otherDataLenTmp, 8 );
485 hAss->streamMuxConfigBits+=9;
486 } while(otherDataLenEsc);
487 }
488
489 {
490 USHORT crcCheckPresent=0;
491 USHORT crcCheckSum=0;
492
493 FDKwriteBits( hBs, crcCheckPresent, 1 ); /* crcCheckPresent */
494 hAss->streamMuxConfigBits+=1;
495 if ( crcCheckPresent ){
496 FDKwriteBits( hBs, crcCheckSum, 8 ); /* crcCheckSum */
497 hAss->streamMuxConfigBits+=8;
498 }
499 }
500
501 } else { /* if ( audioMuxVersionA == 0 ) */
502
503 /* for future extensions */
504
505 }
506
507 return TRANSPORTENC_OK;
508 }
509
510
511 static TRANSPORTENC_ERROR
WriteAuPayloadLengthInfo(HANDLE_FDK_BITSTREAM hBitStream,int AuLengthBits)512 WriteAuPayloadLengthInfo( HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits )
513 {
514 int restBytes;
515
516 if( AuLengthBits % 8 )
517 return TRANSPORTENC_INVALID_AU_LENGTH;
518
519 while( AuLengthBits >= 255*8 ) {
520 FDKwriteBits( hBitStream, 255, 8 ); /* 255 shows incomplete AU */
521 AuLengthBits -= (255*8);
522 }
523
524 restBytes = (AuLengthBits) >> 3;
525 FDKwriteBits( hBitStream, restBytes, 8 );
526
527 return TRANSPORTENC_OK;
528 }
529
530 static
transportEnc_LatmSetNrOfSubframes(HANDLE_LATM_STREAM hAss,INT noSubframes_next)531 TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes( HANDLE_LATM_STREAM hAss,
532 INT noSubframes_next) /* nr of access units / payloads within a latm frame */
533 {
534 /* sanity chk */
535 if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
536 return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
537 }
538
539 hAss->noSubframes_next = noSubframes_next;
540
541 /* if at start then we can take over the value immediately, otherwise we have to wait for the next SMC */
542 if ( (hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0) ) {
543 hAss->noSubframes = noSubframes_next;
544 }
545
546 return TRANSPORTENC_OK;
547 }
548
549 static
allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss,UCHAR noProgram,UCHAR noLayer[])550 int allStreamsSameTimeFraming( HANDLE_LATM_STREAM hAss, UCHAR noProgram, UCHAR noLayer[] /* return */ )
551 {
552 int prog, layer;
553
554 signed int lastNoSamples = -1;
555 signed int minFrameSamples = FDK_INT_MAX;
556 signed int maxFrameSamples = 0;
557
558 signed int highestSamplingRate = -1;
559
560 for( prog=0; prog<noProgram; prog++ ) {
561 noLayer[prog] = 0;
562
563 for( layer=0; layer<LATM_MAX_LAYERS; layer++ )
564 {
565 if( hAss->config[prog][layer] != NULL )
566 {
567 INT hsfSamplesFrame;
568
569 noLayer[prog]++;
570
571 if( highestSamplingRate < 0 )
572 highestSamplingRate = hAss->config[prog][layer]->samplingRate;
573
574 hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame * highestSamplingRate / hAss->config[prog][layer]->samplingRate;
575
576 if( hsfSamplesFrame <= minFrameSamples ) minFrameSamples = hsfSamplesFrame;
577 if( hsfSamplesFrame >= maxFrameSamples ) maxFrameSamples = hsfSamplesFrame;
578
579 if( lastNoSamples == -1 ) {
580 lastNoSamples = hsfSamplesFrame;
581 } else {
582 if( hsfSamplesFrame != lastNoSamples ) {
583 return 0;
584 }
585 }
586 }
587 }
588 }
589
590 return 1;
591 }
592
593 /**
594 * Initialize LATM/LOAS Stream and add layer 0 at program 0.
595 */
596 static
transportEnc_InitLatmStream(HANDLE_LATM_STREAM hAss,int fractDelayPresent,signed int muxConfigPeriod,UINT audioMuxVersion,TRANSPORT_TYPE tt)597 TRANSPORTENC_ERROR transportEnc_InitLatmStream( HANDLE_LATM_STREAM hAss,
598 int fractDelayPresent,
599 signed int muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
600 UINT audioMuxVersion,
601 TRANSPORT_TYPE tt
602 )
603 {
604 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
605
606 if (hAss == NULL)
607 return TRANSPORTENC_INVALID_PARAMETER;
608
609 hAss->tt = tt;
610
611 hAss->noProgram = 1;
612
613 hAss->audioMuxVersion = audioMuxVersion;
614
615 /* Fill noLayer array using hAss->config */
616 hAss->allStreamsSameTimeFraming = allStreamsSameTimeFraming( hAss, hAss->noProgram, hAss->noLayer );
617 /* Only allStreamsSameTimeFraming==1 is supported */
618 FDK_ASSERT(hAss->allStreamsSameTimeFraming);
619
620 hAss->fractDelayPresent = fractDelayPresent;
621 hAss->otherDataLenBytes = 0;
622
623 hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
624
625 /* initialize counters */
626 hAss->subFrameCnt = 0;
627 hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES;
628 hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES;
629
630 /* sync layer related */
631 hAss->audioMuxLengthBytes = 0;
632
633 hAss->latmFrameCounter = 0;
634 hAss->muxConfigPeriod = muxConfigPeriod;
635
636 return ErrorStatus;
637 }
638
639
640 /**
641 *
642 */
transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,unsigned int streamDataLength)643 UINT transportEnc_LatmCountTotalBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength )
644 {
645 UINT bitDemand = 0;
646
647 switch (hAss->tt) {
648 case TT_MP4_LOAS:
649 case TT_MP4_LATM_MCP0:
650 case TT_MP4_LATM_MCP1:
651 if (hAss->subFrameCnt == 0) {
652 bitDemand = transportEnc_LatmCountFixBitDemandHeader ( hAss );
653 }
654 bitDemand += transportEnc_LatmCountVarBitDemandHeader ( hAss , streamDataLength /*- bitDemand*/);
655 break;
656 default:
657 break;
658 }
659
660 return bitDemand;
661 }
662
663 static TRANSPORTENC_ERROR
AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)664 AdvanceAudioMuxElement (
665 HANDLE_LATM_STREAM hAss,
666 HANDLE_FDK_BITSTREAM hBs,
667 int auBits,
668 int bufferFullness,
669 CSTpCallBacks *cb
670 )
671 {
672 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
673 int insertMuxSetup;
674
675 /* Insert setup data to assemble Buffer */
676 if (hAss->subFrameCnt == 0)
677 {
678 if (hAss->muxConfigPeriod > 0) {
679 insertMuxSetup = (hAss->latmFrameCounter == 0);
680 } else {
681 insertMuxSetup = 0;
682 }
683
684 if (hAss->tt != TT_MP4_LATM_MCP0) {
685 if( insertMuxSetup ) {
686 FDKwriteBits( hBs, 0, 1 ); /* useSameStreamMux useNewStreamMux */
687 CreateStreamMuxConfig(hAss, hBs, bufferFullness, cb);
688 if (ErrorStatus != TRANSPORTENC_OK)
689 return ErrorStatus;
690 } else {
691 FDKwriteBits( hBs, 1, 1 ); /* useSameStreamMux */
692 }
693 }
694 }
695
696 /* PayloadLengthInfo */
697 {
698 int prog, layer;
699
700 for (prog = 0; prog < hAss->noProgram; prog++) {
701 for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
702 ErrorStatus = WriteAuPayloadLengthInfo( hBs, auBits );
703 if (ErrorStatus != TRANSPORTENC_OK)
704 return ErrorStatus;
705 }
706 }
707 }
708 /* At this point comes the access unit. */
709
710 return TRANSPORTENC_OK;
711 }
712
713 TRANSPORTENC_ERROR
transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)714 transportEnc_LatmWrite (
715 HANDLE_LATM_STREAM hAss,
716 HANDLE_FDK_BITSTREAM hBs,
717 int auBits,
718 int bufferFullness,
719 CSTpCallBacks *cb
720 )
721 {
722 TRANSPORTENC_ERROR ErrorStatus;
723
724 if (hAss->subFrameCnt == 0) {
725 /* Start new frame */
726 FDKresetBitbuffer(hBs, BS_WRITER);
727 }
728
729 hAss->latmSubframeStart = FDKgetValidBits(hBs);
730
731 /* Insert syncword and syncword distance
732 - only if loas
733 - we must update the syncword distance (=audiomuxlengthbytes) later
734 */
735 if( hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0)
736 {
737 /* Start new LOAS frame */
738 FDKwriteBits( hBs, 0x2B7, 11 );
739 hAss->audioMuxLengthBytes = 0;
740 hAss->audioMuxLengthBytesPos = FDKgetValidBits( hBs ); /* store read pointer position */
741 FDKwriteBits( hBs, hAss->audioMuxLengthBytes, 13 );
742 }
743
744 ErrorStatus = AdvanceAudioMuxElement(
745 hAss,
746 hBs,
747 auBits,
748 bufferFullness,
749 cb
750 );
751
752 if (ErrorStatus != TRANSPORTENC_OK)
753 return ErrorStatus;
754
755 return ErrorStatus;
756 }
757
transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss,int * bits)758 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss,
759 int *bits)
760 {
761 /* Substract bits from possible previous subframe */
762 *bits -= hAss->latmSubframeStart;
763 /* Add fill bits */
764 if (hAss->subFrameCnt == 0)
765 *bits += hAss->fillBits;
766 }
767
768
transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int * bytes)769 void transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
770 HANDLE_FDK_BITSTREAM hBs,
771 int *bytes)
772 {
773
774 hAss->subFrameCnt++;
775 if (hAss->subFrameCnt >= hAss->noSubframes)
776 {
777
778 /* Add LOAS frame length if required. */
779 if (hAss->tt == TT_MP4_LOAS)
780 {
781 int latmBytes;
782
783 latmBytes = (FDKgetValidBits(hBs)+7) >> 3;
784
785 /* write length info into assembler buffer */
786 hAss->audioMuxLengthBytes = latmBytes - 3; /* 3=Syncword + length */
787 {
788 FDK_BITSTREAM tmpBuf;
789
790 FDKinitBitStream( &tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER ) ;
791 FDKpushFor( &tmpBuf, hAss->audioMuxLengthBytesPos );
792 FDKwriteBits( &tmpBuf, hAss->audioMuxLengthBytes, 13 );
793 FDKsyncCache( &tmpBuf );
794 }
795 }
796
797 /* Write AudioMuxElement byte alignment fill bits */
798 FDKwriteBits(hBs, 0, hAss->fillBits);
799
800 FDK_ASSERT( (FDKgetValidBits(hBs) % 8) == 0);
801
802 hAss->subFrameCnt = 0;
803
804 FDKsyncCache(hBs);
805 *bytes = (FDKgetValidBits(hBs) + 7)>>3;
806 //FDKfetchBuffer(hBs, buffer, (UINT*)bytes);
807
808 if (hAss->muxConfigPeriod > 0)
809 {
810 hAss->latmFrameCounter++;
811
812 if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
813 hAss->latmFrameCounter = 0;
814 hAss->noSubframes = hAss->noSubframes_next;
815 }
816 }
817 } else {
818 /* No data this time */
819 *bytes = 0;
820 }
821 }
822
823 /**
824 * Init LATM/LOAS
825 */
transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,CODER_CONFIG * layerConfig,UINT audioMuxVersion,TRANSPORT_TYPE tt,CSTpCallBacks * cb)826 TRANSPORTENC_ERROR transportEnc_Latm_Init(
827 HANDLE_LATM_STREAM hAss,
828 HANDLE_FDK_BITSTREAM hBs,
829 CODER_CONFIG *layerConfig,
830 UINT audioMuxVersion,
831 TRANSPORT_TYPE tt,
832 CSTpCallBacks *cb
833 )
834 {
835 TRANSPORTENC_ERROR ErrorStatus;
836 int fractDelayPresent = 0;
837 int prog, layer;
838
839 int setupDataDistanceFrames = layerConfig->headerPeriod;
840
841 FDK_ASSERT(setupDataDistanceFrames>=0);
842
843 for (prog=0; prog<LATM_MAX_PROGRAMS; prog++) {
844 for (layer=0; layer<LATM_MAX_LAYERS; layer++) {
845 hAss->config[prog][layer] = NULL;
846 hAss->m_linfo[prog][layer].streamID = -1;
847 }
848 }
849
850 hAss->config[0][0] = layerConfig;
851 hAss->m_linfo[0][0].streamID = 0;
852
853 ErrorStatus = transportEnc_InitLatmStream( hAss,
854 fractDelayPresent,
855 setupDataDistanceFrames,
856 (audioMuxVersion)?1:0,
857 tt
858 );
859 if (ErrorStatus != TRANSPORTENC_OK)
860 goto bail;
861
862 ErrorStatus = transportEnc_LatmSetNrOfSubframes(
863 hAss,
864 layerConfig->nSubFrames
865 );
866 if (ErrorStatus != TRANSPORTENC_OK)
867 goto bail;
868
869 /* Get the size of the StreamMuxConfig somehow */
870 AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb);
871 //CreateStreamMuxConfig(hAss, hBs, 0);
872
873 bail:
874 return ErrorStatus;
875 }
876
877
878
879
880
881
882