Imported Debian version 0.1.3.1
[deb_fdk-aac.git] / libMpegTPEnc / src / tpenc_latm.cpp
1
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5 © Copyright 1995 - 2013 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
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
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
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
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->audioMuxVersionA = 0; /* for future extensions */
300 hAss->streamMuxConfigBits = 0;
301
302 FDKwriteBits( hBs, hAss->audioMuxVersion, 1 ); /* audioMuxVersion */
303 hAss->streamMuxConfigBits += 1;
304
305 if ( hAss->audioMuxVersion == 1 ) {
306 FDKwriteBits( hBs, hAss->audioMuxVersionA, 1 ); /* audioMuxVersionA */
307 hAss->streamMuxConfigBits+=1;
308 }
309
310 if ( hAss->audioMuxVersionA == 0 )
311 {
312 if ( hAss->audioMuxVersion == 1 ) {
313 hAss->streamMuxConfigBits+= transportEnc_LatmWriteValue( hBs, hAss->taraBufferFullness );/* taraBufferFullness */
314 }
315 FDKwriteBits( hBs, hAss->allStreamsSameTimeFraming ? 1:0, 1 ); /* allStreamsSameTimeFraming */
316 FDKwriteBits( hBs, hAss->noSubframes-1, 6 ); /* Number of Subframes */
317 FDKwriteBits( hBs, hAss->noProgram-1, 4 ); /* Number of Programs */
318
319 hAss->streamMuxConfigBits+=11;
320
321 streamIDcnt = 0;
322 for( prog=0; prog<hAss->noProgram; prog++ ) {
323 int transLayer = 0;
324
325 FDKwriteBits( hBs, hAss->noLayer[prog]-1, 3 );
326 hAss->streamMuxConfigBits+=3;
327
328 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) {
329 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
330 CODER_CONFIG *p_lci = hAss->config[prog][layer];
331
332 p_linfo->streamID = -1;
333
334 if( hAss->config[prog][layer] != NULL ) {
335 int useSameConfig = 0;
336
337 if( transLayer > 0 ) {
338 FDKwriteBits( hBs, useSameConfig ? 1 : 0, 1 );
339 hAss->streamMuxConfigBits+=1;
340 }
341 if( (useSameConfig == 0) || (transLayer==0) ) {
342 UINT bits;
343
344 if ( hAss->audioMuxVersion == 1 ) {
345 FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */
346 }
347
348 bits = FDKgetValidBits( hBs );
349
350 transportEnc_writeASC(
351 hBs,
352 hAss->config[prog][layer],
353 cb
354 );
355
356 bits = FDKgetValidBits( hBs ) - bits;
357
358 if ( hAss->audioMuxVersion == 1 ) {
359 FDKpushBack(hBs, bits+2);
360 hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits );
361 transportEnc_writeASC(
362 hBs,
363 hAss->config[prog][layer],
364 cb
365 );
366 }
367
368 hAss->streamMuxConfigBits += bits; /* 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 case AOT_RSVD50:
388 p_linfo->frameLengthType = 0;
389
390 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
391 FDKwriteBits( hBs, bufferFullness, 8 ); /* bufferFullness */
392 hAss->streamMuxConfigBits+=11;
393
394 if ( !hAss->allStreamsSameTimeFraming ) {
395 CODER_CONFIG *p_lci_prev = hAss->config[prog][layer-1];
396 if ( ((p_lci->aot == AOT_AAC_SCAL) || (p_lci->aot == AOT_ER_AAC_SCAL)) &&
397 ((p_lci_prev->aot == AOT_CELP) || (p_lci_prev->aot == AOT_ER_CELP)) ) {
398 FDKwriteBits( hBs, coreFrameOffset, 6 ); /* coreFrameOffset */
399 hAss->streamMuxConfigBits+=6;
400 }
401 }
402 break;
403
404 case AOT_TWIN_VQ:
405 p_linfo->frameLengthType = 1;
406 tmp = ( (p_lci->bitsFrame+7) >> 3 ) - 20; /* transmission frame length in bytes */
407 if( (tmp < 0) ) {
408 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
409 }
410 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
411 FDKwriteBits( hBs, tmp, 9 );
412 hAss->streamMuxConfigBits+=12;
413
414 p_linfo->frameLengthBits = (tmp+20) << 3;
415 break;
416
417 case AOT_CELP:
418 p_linfo->frameLengthType = 4;
419 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
420 hAss->streamMuxConfigBits+=3;
421 {
422 int i;
423 for( i=0; i<62; i++ ) {
424 if( celpFrameLengthTable[i] == p_lci->bitsFrame )
425 break;
426 }
427 if( i>=62 ) {
428 return TRANSPORTENC_INVALID_CELP_FRAME_LENGTH;
429 }
430
431 FDKwriteBits( hBs, i, 6 ); /* CELPframeLengthTabelIndex */
432 hAss->streamMuxConfigBits+=6;
433 }
434 p_linfo->frameLengthBits = p_lci->bitsFrame;
435 break;
436
437 case AOT_HVXC:
438 p_linfo->frameLengthType = 6;
439 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */
440 hAss->streamMuxConfigBits+=3;
441 {
442 int i;
443
444 if( p_lci->bitsFrame == 40 ) {
445 i = 0;
446 } else if( p_lci->bitsFrame == 80 ) {
447 i = 1;
448 } else {
449 return TRANSPORTENC_INVALID_FRAME_BITS;
450 }
451 FDKwriteBits( hBs, i, 1 ); /* HVXCframeLengthTableIndex */
452 hAss->streamMuxConfigBits+=1;
453 }
454 p_linfo->frameLengthBits = p_lci->bitsFrame;
455 break;
456
457 case AOT_NULL_OBJECT:
458 default:
459 return TRANSPORTENC_INVALID_AOT;
460 }
461 }
462 }
463 }
464
465 FDKwriteBits( hBs, (hAss->otherDataLenBytes>0) ? 1:0, 1 ); /* otherDataPresent */
466 hAss->streamMuxConfigBits+=1;
467
468 if( hAss->otherDataLenBytes > 0 ) {
469
470 INT otherDataLenTmp = hAss->otherDataLenBytes;
471 INT escCnt = 0;
472 INT otherDataLenEsc = 1;
473
474 while(otherDataLenTmp) {
475 otherDataLenTmp >>= 8;
476 escCnt ++;
477 }
478
479 do {
480 otherDataLenTmp = (hAss->otherDataLenBytes>>(escCnt*8)) & 0xFF;
481 escCnt--;
482 otherDataLenEsc = escCnt>0;
483
484 FDKwriteBits( hBs, otherDataLenEsc, 1 );
485 FDKwriteBits( hBs, otherDataLenTmp, 8 );
486 hAss->streamMuxConfigBits+=9;
487 } while(otherDataLenEsc);
488 }
489
490 {
491 USHORT crcCheckPresent=0;
492 USHORT crcCheckSum=0;
493
494 FDKwriteBits( hBs, crcCheckPresent, 1 ); /* crcCheckPresent */
495 hAss->streamMuxConfigBits+=1;
496 if ( crcCheckPresent ){
497 FDKwriteBits( hBs, crcCheckSum, 8 ); /* crcCheckSum */
498 hAss->streamMuxConfigBits+=8;
499 }
500 }
501
502 } else { /* if ( audioMuxVersionA == 0 ) */
503
504 /* for future extensions */
505
506 }
507
508 return TRANSPORTENC_OK;
509 }
510
511
512 static TRANSPORTENC_ERROR
513 WriteAuPayloadLengthInfo( HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits )
514 {
515 int restBytes;
516
517 if( AuLengthBits % 8 )
518 return TRANSPORTENC_INVALID_AU_LENGTH;
519
520 while( AuLengthBits >= 255*8 ) {
521 FDKwriteBits( hBitStream, 255, 8 ); /* 255 shows incomplete AU */
522 AuLengthBits -= (255*8);
523 }
524
525 restBytes = (AuLengthBits) >> 3;
526 FDKwriteBits( hBitStream, restBytes, 8 );
527
528 return TRANSPORTENC_OK;
529 }
530
531 static
532 TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes( HANDLE_LATM_STREAM hAss,
533 INT noSubframes_next) /* nr of access units / payloads within a latm frame */
534 {
535 /* sanity chk */
536 if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
537 return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
538 }
539
540 hAss->noSubframes_next = noSubframes_next;
541
542 /* if at start then we can take over the value immediately, otherwise we have to wait for the next SMC */
543 if ( (hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0) ) {
544 hAss->noSubframes = noSubframes_next;
545 }
546
547 return TRANSPORTENC_OK;
548 }
549
550 static
551 int allStreamsSameTimeFraming( HANDLE_LATM_STREAM hAss, UCHAR noProgram, UCHAR noLayer[] /* return */ )
552 {
553 int prog, layer;
554
555 signed int lastNoSamples = -1;
556 signed int minFrameSamples = FDK_INT_MAX;
557 signed int maxFrameSamples = 0;
558
559 signed int highestSamplingRate = -1;
560
561 for( prog=0; prog<noProgram; prog++ ) {
562 noLayer[prog] = 0;
563
564 for( layer=0; layer<LATM_MAX_LAYERS; layer++ )
565 {
566 if( hAss->config[prog][layer] != NULL )
567 {
568 INT hsfSamplesFrame;
569
570 noLayer[prog]++;
571
572 if( highestSamplingRate < 0 )
573 highestSamplingRate = hAss->config[prog][layer]->samplingRate;
574
575 hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame * highestSamplingRate / hAss->config[prog][layer]->samplingRate;
576
577 if( hsfSamplesFrame <= minFrameSamples ) minFrameSamples = hsfSamplesFrame;
578 if( hsfSamplesFrame >= maxFrameSamples ) maxFrameSamples = hsfSamplesFrame;
579
580 if( lastNoSamples == -1 ) {
581 lastNoSamples = hsfSamplesFrame;
582 } else {
583 if( hsfSamplesFrame != lastNoSamples ) {
584 return 0;
585 }
586 }
587 }
588 }
589 }
590
591 return 1;
592 }
593
594 /**
595 * Initialize LATM/LOAS Stream and add layer 0 at program 0.
596 */
597 static
598 TRANSPORTENC_ERROR transportEnc_InitLatmStream( HANDLE_LATM_STREAM hAss,
599 int fractDelayPresent,
600 signed int muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
601 UINT audioMuxVersion,
602 TRANSPORT_TYPE tt
603 )
604 {
605 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
606
607 if (hAss == NULL)
608 return TRANSPORTENC_INVALID_PARAMETER;
609
610 hAss->tt = tt;
611
612 hAss->noProgram = 1;
613
614 hAss->audioMuxVersion = audioMuxVersion;
615
616 /* Fill noLayer array using hAss->config */
617 hAss->allStreamsSameTimeFraming = allStreamsSameTimeFraming( hAss, hAss->noProgram, hAss->noLayer );
618 /* Only allStreamsSameTimeFraming==1 is supported */
619 FDK_ASSERT(hAss->allStreamsSameTimeFraming);
620
621 hAss->fractDelayPresent = fractDelayPresent;
622 hAss->otherDataLenBytes = 0;
623
624 hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
625
626 /* initialize counters */
627 hAss->subFrameCnt = 0;
628 hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES;
629 hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES;
630
631 /* sync layer related */
632 hAss->audioMuxLengthBytes = 0;
633
634 hAss->latmFrameCounter = 0;
635 hAss->muxConfigPeriod = muxConfigPeriod;
636
637 return ErrorStatus;
638 }
639
640
641 /**
642 *
643 */
644 UINT transportEnc_LatmCountTotalBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength )
645 {
646 UINT bitDemand = 0;
647
648 switch (hAss->tt) {
649 case TT_MP4_LOAS:
650 case TT_MP4_LATM_MCP0:
651 case TT_MP4_LATM_MCP1:
652 if (hAss->subFrameCnt == 0) {
653 bitDemand = transportEnc_LatmCountFixBitDemandHeader ( hAss );
654 }
655 bitDemand += transportEnc_LatmCountVarBitDemandHeader ( hAss , streamDataLength /*- bitDemand*/);
656 break;
657 default:
658 break;
659 }
660
661 return bitDemand;
662 }
663
664 static TRANSPORTENC_ERROR
665 AdvanceAudioMuxElement (
666 HANDLE_LATM_STREAM hAss,
667 HANDLE_FDK_BITSTREAM hBs,
668 int auBits,
669 int bufferFullness,
670 CSTpCallBacks *cb
671 )
672 {
673 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
674 int insertMuxSetup;
675
676 /* Insert setup data to assemble Buffer */
677 if (hAss->subFrameCnt == 0)
678 {
679 if (hAss->muxConfigPeriod > 0) {
680 insertMuxSetup = (hAss->latmFrameCounter == 0);
681 } else {
682 insertMuxSetup = 0;
683 }
684
685 if (hAss->tt != TT_MP4_LATM_MCP0) {
686 if( insertMuxSetup ) {
687 FDKwriteBits( hBs, 0, 1 ); /* useSameStreamMux useNewStreamMux */
688 CreateStreamMuxConfig(hAss, hBs, bufferFullness, cb);
689 if (ErrorStatus != TRANSPORTENC_OK)
690 return ErrorStatus;
691 } else {
692 FDKwriteBits( hBs, 1, 1 ); /* useSameStreamMux */
693 }
694 }
695 }
696
697 /* PayloadLengthInfo */
698 {
699 int prog, layer;
700
701 for (prog = 0; prog < hAss->noProgram; prog++) {
702 for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
703 ErrorStatus = WriteAuPayloadLengthInfo( hBs, auBits );
704 if (ErrorStatus != TRANSPORTENC_OK)
705 return ErrorStatus;
706 }
707 }
708 }
709 /* At this point comes the access unit. */
710
711 return TRANSPORTENC_OK;
712 }
713
714 TRANSPORTENC_ERROR
715 transportEnc_LatmWrite (
716 HANDLE_LATM_STREAM hAss,
717 HANDLE_FDK_BITSTREAM hBs,
718 int auBits,
719 int bufferFullness,
720 CSTpCallBacks *cb
721 )
722 {
723 TRANSPORTENC_ERROR ErrorStatus;
724
725 if (hAss->subFrameCnt == 0) {
726 /* Start new frame */
727 FDKresetBitbuffer(hBs, BS_WRITER);
728 }
729
730 hAss->latmSubframeStart = FDKgetValidBits(hBs);
731
732 /* Insert syncword and syncword distance
733 - only if loas
734 - we must update the syncword distance (=audiomuxlengthbytes) later
735 */
736 if( hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0)
737 {
738 /* Start new LOAS frame */
739 FDKwriteBits( hBs, 0x2B7, 11 );
740 hAss->audioMuxLengthBytes = 0;
741 hAss->audioMuxLengthBytesPos = FDKgetValidBits( hBs ); /* store read pointer position */
742 FDKwriteBits( hBs, hAss->audioMuxLengthBytes, 13 );
743 }
744
745 ErrorStatus = AdvanceAudioMuxElement(
746 hAss,
747 hBs,
748 auBits,
749 bufferFullness,
750 cb
751 );
752
753 if (ErrorStatus != TRANSPORTENC_OK)
754 return ErrorStatus;
755
756 return ErrorStatus;
757 }
758
759 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss,
760 int *bits)
761 {
762 /* Substract bits from possible previous subframe */
763 *bits -= hAss->latmSubframeStart;
764 /* Add fill bits */
765 if (hAss->subFrameCnt == 0)
766 *bits += hAss->fillBits;
767 }
768
769
770 void transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
771 HANDLE_FDK_BITSTREAM hBs,
772 int *bytes)
773 {
774
775 hAss->subFrameCnt++;
776 if (hAss->subFrameCnt >= hAss->noSubframes)
777 {
778
779 /* Add LOAS frame length if required. */
780 if (hAss->tt == TT_MP4_LOAS)
781 {
782 int latmBytes;
783
784 latmBytes = (FDKgetValidBits(hBs)+7) >> 3;
785
786 /* write length info into assembler buffer */
787 hAss->audioMuxLengthBytes = latmBytes - 3; /* 3=Syncword + length */
788 {
789 FDK_BITSTREAM tmpBuf;
790
791 FDKinitBitStream( &tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER ) ;
792 FDKpushFor( &tmpBuf, hAss->audioMuxLengthBytesPos );
793 FDKwriteBits( &tmpBuf, hAss->audioMuxLengthBytes, 13 );
794 FDKsyncCache( &tmpBuf );
795 }
796 }
797
798 /* Write AudioMuxElement byte alignment fill bits */
799 FDKwriteBits(hBs, 0, hAss->fillBits);
800
801 FDK_ASSERT( (FDKgetValidBits(hBs) % 8) == 0);
802
803 hAss->subFrameCnt = 0;
804
805 FDKsyncCache(hBs);
806 *bytes = (FDKgetValidBits(hBs) + 7)>>3;
807 //FDKfetchBuffer(hBs, buffer, (UINT*)bytes);
808
809 if (hAss->muxConfigPeriod > 0)
810 {
811 hAss->latmFrameCounter++;
812
813 if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
814 hAss->latmFrameCounter = 0;
815 hAss->noSubframes = hAss->noSubframes_next;
816 }
817 }
818 } else {
819 /* No data this time */
820 *bytes = 0;
821 }
822 }
823
824 /**
825 * Init LATM/LOAS
826 */
827 TRANSPORTENC_ERROR transportEnc_Latm_Init(
828 HANDLE_LATM_STREAM hAss,
829 HANDLE_FDK_BITSTREAM hBs,
830 CODER_CONFIG *layerConfig,
831 UINT audioMuxVersion,
832 TRANSPORT_TYPE tt,
833 CSTpCallBacks *cb
834 )
835 {
836 TRANSPORTENC_ERROR ErrorStatus;
837 int fractDelayPresent = 0;
838 int prog, layer;
839
840 int setupDataDistanceFrames = layerConfig->headerPeriod;
841
842 FDK_ASSERT(setupDataDistanceFrames>=0);
843
844 for (prog=0; prog<LATM_MAX_PROGRAMS; prog++) {
845 for (layer=0; layer<LATM_MAX_LAYERS; layer++) {
846 hAss->config[prog][layer] = NULL;
847 hAss->m_linfo[prog][layer].streamID = -1;
848 }
849 }
850
851 hAss->config[0][0] = layerConfig;
852 hAss->m_linfo[0][0].streamID = 0;
853
854 ErrorStatus = transportEnc_InitLatmStream( hAss,
855 fractDelayPresent,
856 setupDataDistanceFrames,
857 (audioMuxVersion)?1:0,
858 tt
859 );
860 if (ErrorStatus != TRANSPORTENC_OK)
861 goto bail;
862
863 ErrorStatus = transportEnc_LatmSetNrOfSubframes(
864 hAss,
865 layerConfig->nSubFrames
866 );
867 if (ErrorStatus != TRANSPORTENC_OK)
868 goto bail;
869
870 /* Get the size of the StreamMuxConfig somehow */
871 AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb);
872 //CreateStreamMuxConfig(hAss, hBs, 0);
873
874 bail:
875 return ErrorStatus;
876 }
877
878
879
880
881
882