2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
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.
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.
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.
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.
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:
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.
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.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
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.
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."
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.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
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.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
84 /***************************** MPEG-4 AAC Encoder **************************
89 ******************************************************************************/
91 #include "tpenc_latm.h"
94 #include "genericStds.h"
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
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
113 UINT
transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs
, int value
)
115 UCHAR valueBytes
= 4;
116 unsigned int bitsWritten
= 0;
119 if ( value
< (1<<8) ) {
121 } else if ( value
< (1<<16) ) {
123 } else if ( value
< (1<<24) ) {
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);
135 bitsWritten
= (valueBytes
<<3)+2;
141 UINT
transportEnc_LatmCountFixBitDemandHeader ( HANDLE_LATM_STREAM hAss
)
144 int insertSetupData
= 0 ;
146 /* only if start of new latm frame */
147 if (hAss
->subFrameCnt
==0)
149 /* AudioSyncStream */
151 if (hAss
->tt
== TT_MP4_LOAS
) {
152 bitDemand
+= 11 ; /* syncword */
153 bitDemand
+= 13 ; /* audioMuxLengthBytes */
158 /* AudioMuxElement::Stream Mux Config */
159 if (hAss
->muxConfigPeriod
> 0) {
160 insertSetupData
= (hAss
->latmFrameCounter
== 0);
165 if (hAss
->tt
!= TT_MP4_LATM_MCP0
) {
166 /* AudioMuxElement::useSameStreamMux Flag */
169 if( insertSetupData
) {
170 bitDemand
+= hAss
->streamMuxConfigBits
;
174 /* AudioMuxElement::otherDataBits */
175 bitDemand
+= 8*hAss
->otherDataLenBytes
;
177 /* AudioMuxElement::ByteAlign */
178 if ( bitDemand
% 8 ) {
179 hAss
->fillBits
= 8 - (bitDemand
% 8);
180 bitDemand
+= hAss
->fillBits
;
190 UINT
transportEnc_LatmCountVarBitDemandHeader ( HANDLE_LATM_STREAM hAss
, unsigned int streamDataLength
)
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
]);
201 if( p_linfo
->streamID
>= 0 ) {
202 switch( p_linfo
->frameLengthType
) {
204 if ( streamDataLength
> 0 ) {
205 streamDataLength
-= bitDemand
;
206 while( streamDataLength
>= (255<<3) ) {
208 streamDataLength
-= (255<<3);
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 );
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
]);
240 if( p_linfo
->streamID
>= 0 ) {
242 bitDemand
+=4; /* streamID */
243 switch( p_linfo
->frameLengthType
) {
245 streamDataLength
-= bitDemand
;
246 while( streamDataLength
>= (255<<3) ) {
248 streamDataLength
-= (255<<3);
253 /*bitDemand += 1; endFlag
265 hAss
->varStreamCnt
++;
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);
287 CreateStreamMuxConfig(
288 HANDLE_LATM_STREAM hAss
,
289 HANDLE_FDK_BITSTREAM hBs
,
294 INT streamIDcnt
, tmp
;
297 USHORT coreFrameOffset
=0;
299 hAss
->audioMuxVersionA
= 0; /* for future extensions */
300 hAss
->streamMuxConfigBits
= 0;
302 FDKwriteBits( hBs
, hAss
->audioMuxVersion
, 1 ); /* audioMuxVersion */
303 hAss
->streamMuxConfigBits
+= 1;
305 if ( hAss
->audioMuxVersion
== 1 ) {
306 FDKwriteBits( hBs
, hAss
->audioMuxVersionA
, 1 ); /* audioMuxVersionA */
307 hAss
->streamMuxConfigBits
+=1;
310 if ( hAss
->audioMuxVersionA
== 0 )
312 if ( hAss
->audioMuxVersion
== 1 ) {
313 hAss
->streamMuxConfigBits
+= transportEnc_LatmWriteValue( hBs
, hAss
->taraBufferFullness
);/* taraBufferFullness */
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 */
319 hAss
->streamMuxConfigBits
+=11;
322 for( prog
=0; prog
<hAss
->noProgram
; prog
++ ) {
325 FDKwriteBits( hBs
, hAss
->noLayer
[prog
]-1, 3 );
326 hAss
->streamMuxConfigBits
+=3;
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
];
332 p_linfo
->streamID
= -1;
334 if( hAss
->config
[prog
][layer
] != NULL
) {
335 int useSameConfig
= 0;
337 if( transLayer
> 0 ) {
338 FDKwriteBits( hBs
, useSameConfig
? 1 : 0, 1 );
339 hAss
->streamMuxConfigBits
+=1;
341 if( (useSameConfig
== 0) || (transLayer
==0) ) {
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 */
348 bits
= FDKgetValidBits( hBs
);
350 transportEnc_writeASC(
352 hAss
->config
[prog
][layer
],
356 bits
= FDKgetValidBits( hBs
) - bits
;
358 if ( hAss
->audioMuxVersion
== 1 ) {
359 FDKpushBack(hBs
, bits
+2);
360 hAss
->streamMuxConfigBits
+= transportEnc_LatmWriteValue( hBs
, bits
);
361 transportEnc_writeASC(
363 hAss
->config
[prog
][layer
],
368 hAss
->streamMuxConfigBits
+= bits
; /* add asc length to smc summary */
372 if( !hAss
->allStreamsSameTimeFraming
) {
373 if( streamIDcnt
>= LATM_MAX_STREAM_ID
)
374 return TRANSPORTENC_INVALID_CONFIG
;
376 p_linfo
->streamID
= streamIDcnt
++;
378 switch( p_lci
->aot
) {
385 case AOT_ER_AAC_ELD
:
388 p_linfo
->frameLengthType
= 0;
390 FDKwriteBits( hBs
, p_linfo
->frameLengthType
, 3 ); /* frameLengthType */
391 FDKwriteBits( hBs
, bufferFullness
, 8 ); /* bufferFullness */
392 hAss
->streamMuxConfigBits
+=11;
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;
405 p_linfo
->frameLengthType
= 1;
406 tmp
= ( (p_lci
->bitsFrame
+7) >> 3 ) - 20; /* transmission frame length in bytes */
408 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH
;
410 FDKwriteBits( hBs
, p_linfo
->frameLengthType
, 3 ); /* frameLengthType */
411 FDKwriteBits( hBs
, tmp
, 9 );
412 hAss
->streamMuxConfigBits
+=12;
414 p_linfo
->frameLengthBits
= (tmp
+20) << 3;
418 p_linfo
->frameLengthType
= 4;
419 FDKwriteBits( hBs
, p_linfo
->frameLengthType
, 3 ); /* frameLengthType */
420 hAss
->streamMuxConfigBits
+=3;
423 for( i
=0; i
<62; i
++ ) {
424 if( celpFrameLengthTable
[i
] == p_lci
->bitsFrame
)
428 return TRANSPORTENC_INVALID_CELP_FRAME_LENGTH
;
431 FDKwriteBits( hBs
, i
, 6 ); /* CELPframeLengthTabelIndex */
432 hAss
->streamMuxConfigBits
+=6;
434 p_linfo
->frameLengthBits
= p_lci
->bitsFrame
;
438 p_linfo
->frameLengthType
= 6;
439 FDKwriteBits( hBs
, p_linfo
->frameLengthType
, 3 ); /* frameLengthType */
440 hAss
->streamMuxConfigBits
+=3;
444 if( p_lci
->bitsFrame
== 40 ) {
446 } else if( p_lci
->bitsFrame
== 80 ) {
449 return TRANSPORTENC_INVALID_FRAME_BITS
;
451 FDKwriteBits( hBs
, i
, 1 ); /* HVXCframeLengthTableIndex */
452 hAss
->streamMuxConfigBits
+=1;
454 p_linfo
->frameLengthBits
= p_lci
->bitsFrame
;
457 case AOT_NULL_OBJECT
:
459 return TRANSPORTENC_INVALID_AOT
;
465 FDKwriteBits( hBs
, (hAss
->otherDataLenBytes
>0) ? 1:0, 1 ); /* otherDataPresent */
466 hAss
->streamMuxConfigBits
+=1;
468 if( hAss
->otherDataLenBytes
> 0 ) {
470 INT otherDataLenTmp
= hAss
->otherDataLenBytes
;
472 INT otherDataLenEsc
= 1;
474 while(otherDataLenTmp
) {
475 otherDataLenTmp
>>= 8;
480 otherDataLenTmp
= (hAss
->otherDataLenBytes
>>(escCnt
*8)) & 0xFF;
482 otherDataLenEsc
= escCnt
>0;
484 FDKwriteBits( hBs
, otherDataLenEsc
, 1 );
485 FDKwriteBits( hBs
, otherDataLenTmp
, 8 );
486 hAss
->streamMuxConfigBits
+=9;
487 } while(otherDataLenEsc
);
491 USHORT crcCheckPresent
=0;
492 USHORT crcCheckSum
=0;
494 FDKwriteBits( hBs
, crcCheckPresent
, 1 ); /* crcCheckPresent */
495 hAss
->streamMuxConfigBits
+=1;
496 if ( crcCheckPresent
){
497 FDKwriteBits( hBs
, crcCheckSum
, 8 ); /* crcCheckSum */
498 hAss
->streamMuxConfigBits
+=8;
502 } else { /* if ( audioMuxVersionA == 0 ) */
504 /* for future extensions */
508 return TRANSPORTENC_OK
;
512 static TRANSPORTENC_ERROR
513 WriteAuPayloadLengthInfo( HANDLE_FDK_BITSTREAM hBitStream
, int AuLengthBits
)
517 if( AuLengthBits
% 8 )
518 return TRANSPORTENC_INVALID_AU_LENGTH
;
520 while( AuLengthBits
>= 255*8 ) {
521 FDKwriteBits( hBitStream
, 255, 8 ); /* 255 shows incomplete AU */
522 AuLengthBits
-= (255*8);
525 restBytes
= (AuLengthBits
) >> 3;
526 FDKwriteBits( hBitStream
, restBytes
, 8 );
528 return TRANSPORTENC_OK
;
532 TRANSPORTENC_ERROR
transportEnc_LatmSetNrOfSubframes( HANDLE_LATM_STREAM hAss
,
533 INT noSubframes_next
) /* nr of access units / payloads within a latm frame */
536 if (noSubframes_next
< 1 || noSubframes_next
> MAX_NR_OF_SUBFRAMES
) {
537 return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES
;
540 hAss
->noSubframes_next
= noSubframes_next
;
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
;
547 return TRANSPORTENC_OK
;
551 int allStreamsSameTimeFraming( HANDLE_LATM_STREAM hAss
, UCHAR noProgram
, UCHAR noLayer
[] /* return */ )
555 signed int lastNoSamples
= -1;
556 signed int minFrameSamples
= FDK_INT_MAX
;
557 signed int maxFrameSamples
= 0;
559 signed int highestSamplingRate
= -1;
561 for( prog
=0; prog
<noProgram
; prog
++ ) {
564 for( layer
=0; layer
<LATM_MAX_LAYERS
; layer
++ )
566 if( hAss
->config
[prog
][layer
] != NULL
)
572 if( highestSamplingRate
< 0 )
573 highestSamplingRate
= hAss
->config
[prog
][layer
]->samplingRate
;
575 hsfSamplesFrame
= hAss
->config
[prog
][layer
]->samplesPerFrame
* highestSamplingRate
/ hAss
->config
[prog
][layer
]->samplingRate
;
577 if( hsfSamplesFrame
<= minFrameSamples
) minFrameSamples
= hsfSamplesFrame
;
578 if( hsfSamplesFrame
>= maxFrameSamples
) maxFrameSamples
= hsfSamplesFrame
;
580 if( lastNoSamples
== -1 ) {
581 lastNoSamples
= hsfSamplesFrame
;
583 if( hsfSamplesFrame
!= lastNoSamples
) {
595 * Initialize LATM/LOAS Stream and add layer 0 at program 0.
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
,
605 TRANSPORTENC_ERROR ErrorStatus
= TRANSPORTENC_OK
;
608 return TRANSPORTENC_INVALID_PARAMETER
;
614 hAss
->audioMuxVersion
= audioMuxVersion
;
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
);
621 hAss
->fractDelayPresent
= fractDelayPresent
;
622 hAss
->otherDataLenBytes
= 0;
624 hAss
->varMode
= LATMVAR_SIMPLE_SEQUENCE
;
626 /* initialize counters */
627 hAss
->subFrameCnt
= 0;
628 hAss
->noSubframes
= DEFAULT_LATM_NR_OF_SUBFRAMES
;
629 hAss
->noSubframes_next
= DEFAULT_LATM_NR_OF_SUBFRAMES
;
631 /* sync layer related */
632 hAss
->audioMuxLengthBytes
= 0;
634 hAss
->latmFrameCounter
= 0;
635 hAss
->muxConfigPeriod
= muxConfigPeriod
;
644 UINT
transportEnc_LatmCountTotalBitDemandHeader ( HANDLE_LATM_STREAM hAss
, unsigned int streamDataLength
)
650 case TT_MP4_LATM_MCP0
:
651 case TT_MP4_LATM_MCP1
:
652 if (hAss
->subFrameCnt
== 0) {
653 bitDemand
= transportEnc_LatmCountFixBitDemandHeader ( hAss
);
655 bitDemand
+= transportEnc_LatmCountVarBitDemandHeader ( hAss
, streamDataLength
/*- bitDemand*/);
664 static TRANSPORTENC_ERROR
665 AdvanceAudioMuxElement (
666 HANDLE_LATM_STREAM hAss
,
667 HANDLE_FDK_BITSTREAM hBs
,
673 TRANSPORTENC_ERROR ErrorStatus
= TRANSPORTENC_OK
;
676 /* Insert setup data to assemble Buffer */
677 if (hAss
->subFrameCnt
== 0)
679 if (hAss
->muxConfigPeriod
> 0) {
680 insertMuxSetup
= (hAss
->latmFrameCounter
== 0);
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
)
692 FDKwriteBits( hBs
, 1, 1 ); /* useSameStreamMux */
697 /* PayloadLengthInfo */
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
)
709 /* At this point comes the access unit. */
711 return TRANSPORTENC_OK
;
715 transportEnc_LatmWrite (
716 HANDLE_LATM_STREAM hAss
,
717 HANDLE_FDK_BITSTREAM hBs
,
723 TRANSPORTENC_ERROR ErrorStatus
;
725 if (hAss
->subFrameCnt
== 0) {
726 /* Start new frame */
727 FDKresetBitbuffer(hBs
, BS_WRITER
);
730 hAss
->latmSubframeStart
= FDKgetValidBits(hBs
);
732 /* Insert syncword and syncword distance
734 - we must update the syncword distance (=audiomuxlengthbytes) later
736 if( hAss
->tt
== TT_MP4_LOAS
&& hAss
->subFrameCnt
== 0)
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 );
745 ErrorStatus
= AdvanceAudioMuxElement(
753 if (ErrorStatus
!= TRANSPORTENC_OK
)
759 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss
,
762 /* Substract bits from possible previous subframe */
763 *bits
-= hAss
->latmSubframeStart
;
765 if (hAss
->subFrameCnt
== 0)
766 *bits
+= hAss
->fillBits
;
770 void transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss
,
771 HANDLE_FDK_BITSTREAM hBs
,
776 if (hAss
->subFrameCnt
>= hAss
->noSubframes
)
779 /* Add LOAS frame length if required. */
780 if (hAss
->tt
== TT_MP4_LOAS
)
784 latmBytes
= (FDKgetValidBits(hBs
)+7) >> 3;
786 /* write length info into assembler buffer */
787 hAss
->audioMuxLengthBytes
= latmBytes
- 3; /* 3=Syncword + length */
789 FDK_BITSTREAM tmpBuf
;
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
);
798 /* Write AudioMuxElement byte alignment fill bits */
799 FDKwriteBits(hBs
, 0, hAss
->fillBits
);
801 FDK_ASSERT( (FDKgetValidBits(hBs
) % 8) == 0);
803 hAss
->subFrameCnt
= 0;
806 *bytes
= (FDKgetValidBits(hBs
) + 7)>>3;
807 //FDKfetchBuffer(hBs, buffer, (UINT*)bytes);
809 if (hAss
->muxConfigPeriod
> 0)
811 hAss
->latmFrameCounter
++;
813 if (hAss
->latmFrameCounter
>= hAss
->muxConfigPeriod
) {
814 hAss
->latmFrameCounter
= 0;
815 hAss
->noSubframes
= hAss
->noSubframes_next
;
819 /* No data this time */
827 TRANSPORTENC_ERROR
transportEnc_Latm_Init(
828 HANDLE_LATM_STREAM hAss
,
829 HANDLE_FDK_BITSTREAM hBs
,
830 CODER_CONFIG
*layerConfig
,
831 UINT audioMuxVersion
,
836 TRANSPORTENC_ERROR ErrorStatus
;
837 int fractDelayPresent
= 0;
840 int setupDataDistanceFrames
= layerConfig
->headerPeriod
;
842 FDK_ASSERT(setupDataDistanceFrames
>=0);
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;
851 hAss
->config
[0][0] = layerConfig
;
852 hAss
->m_linfo
[0][0].streamID
= 0;
854 ErrorStatus
= transportEnc_InitLatmStream( hAss
,
856 setupDataDistanceFrames
,
857 (audioMuxVersion
)?1:0,
860 if (ErrorStatus
!= TRANSPORTENC_OK
)
863 ErrorStatus
= transportEnc_LatmSetNrOfSubframes(
865 layerConfig
->nSubFrames
867 if (ErrorStatus
!= TRANSPORTENC_OK
)
870 /* Get the size of the StreamMuxConfig somehow */
871 AdvanceAudioMuxElement(hAss
, hBs
, 0, 0, cb
);
872 //CreateStreamMuxConfig(hAss, hBs, 0);