1
2/* -----------------------------------------------------------------------------------------------------------
3Software 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
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and 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
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This 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
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-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
96static 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*******/
112static
113UINT 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
140static
141UINT 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
189static
190UINT 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
286TRANSPORTENC_ERROR
287CreateStreamMuxConfig(
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
512static TRANSPORTENC_ERROR
513WriteAuPayloadLengthInfo( 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
531static
532TRANSPORTENC_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
550static
551int 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 */
597static
598TRANSPORTENC_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 */
644UINT 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
664static TRANSPORTENC_ERROR
665AdvanceAudioMuxElement (
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
714TRANSPORTENC_ERROR
715transportEnc_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
759void 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
770void 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 */
827TRANSPORTENC_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
874bail:
875  return ErrorStatus;
876}
877
878
879
880
881
882
883