• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2012 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /*****************************  MPEG-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->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
WriteAuPayloadLengthInfo(HANDLE_FDK_BITSTREAM hBitStream,int AuLengthBits)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
transportEnc_LatmSetNrOfSubframes(HANDLE_LATM_STREAM hAss,INT noSubframes_next)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
allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss,UCHAR noProgram,UCHAR noLayer[])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
transportEnc_InitLatmStream(HANDLE_LATM_STREAM hAss,int fractDelayPresent,signed int muxConfigPeriod,UINT audioMuxVersion,TRANSPORT_TYPE tt)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  */
transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,unsigned int streamDataLength)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
AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)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
transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)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 
transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss,int * bits)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 
transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int * bytes)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  */
transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,CODER_CONFIG * layerConfig,UINT audioMuxVersion,TRANSPORT_TYPE tt,CSTpCallBacks * cb)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 
883