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