• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /******************* MPEG transport format encoder library *********************
96 
97    Author(s):
98 
99    Description:
100 
101 *******************************************************************************/
102 
103 #include "tpenc_latm.h"
104 
105 #include "genericStds.h"
106 
107 static const short celpFrameLengthTable[64] = {
108     154, 170, 186, 147, 156, 165, 114, 120, 186, 126, 132, 138, 142,
109     146, 154, 166, 174, 182, 190, 198, 206, 210, 214, 110, 114, 118,
110     120, 122, 218, 230, 242, 254, 266, 278, 286, 294, 318, 342, 358,
111     374, 390, 406, 422, 136, 142, 148, 154, 160, 166, 170, 174, 186,
112     198, 206, 214, 222, 230, 238, 216, 160, 280, 338, 0,   0};
113 
114 /*******
115  write value to transport stream
116  first two bits define the size of the value itself
117  then the value itself, with a size of 0-3 bytes
118 *******/
transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs,int value)119 static UINT transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs, int value) {
120   UCHAR valueBytes = 4;
121   unsigned int bitsWritten = 0;
122   int i;
123 
124   if (value < (1 << 8)) {
125     valueBytes = 1;
126   } else if (value < (1 << 16)) {
127     valueBytes = 2;
128   } else if (value < (1 << 24)) {
129     valueBytes = 3;
130   } else {
131     valueBytes = 4;
132   }
133 
134   FDKwriteBits(hBs, valueBytes - 1, 2); /* size of value in Bytes */
135   for (i = 0; i < valueBytes; i++) {
136     /* write most significant Byte first */
137     FDKwriteBits(hBs, (UCHAR)(value >> ((valueBytes - 1 - i) << 3)), 8);
138   }
139 
140   bitsWritten = (valueBytes << 3) + 2;
141 
142   return bitsWritten;
143 }
144 
transportEnc_LatmCountFixBitDemandHeader(HANDLE_LATM_STREAM hAss)145 static UINT transportEnc_LatmCountFixBitDemandHeader(HANDLE_LATM_STREAM hAss) {
146   int bitDemand = 0;
147   int insertSetupData = 0;
148 
149   /* only if start of new latm frame */
150   if (hAss->subFrameCnt == 0) {
151     /* AudioSyncStream */
152 
153     if (hAss->tt == TT_MP4_LOAS) {
154       bitDemand += 11; /* syncword */
155       bitDemand += 13; /* audioMuxLengthBytes */
156     }
157 
158     /* AudioMuxElement*/
159 
160     /* AudioMuxElement::Stream Mux Config */
161     if (hAss->muxConfigPeriod > 0) {
162       insertSetupData = (hAss->latmFrameCounter == 0);
163     } else {
164       insertSetupData = 0;
165     }
166 
167     if (hAss->tt != TT_MP4_LATM_MCP0) {
168       /* AudioMuxElement::useSameStreamMux Flag */
169       bitDemand += 1;
170 
171       if (insertSetupData) {
172         bitDemand += hAss->streamMuxConfigBits;
173       }
174     }
175 
176     /* AudioMuxElement::otherDataBits */
177     bitDemand += hAss->otherDataLenBits;
178 
179     /* AudioMuxElement::ByteAlign */
180     if (bitDemand % 8) {
181       hAss->fillBits = 8 - (bitDemand % 8);
182       bitDemand += hAss->fillBits;
183     } else {
184       hAss->fillBits = 0;
185     }
186   }
187 
188   return bitDemand;
189 }
190 
transportEnc_LatmCountVarBitDemandHeader(HANDLE_LATM_STREAM hAss,unsigned int streamDataLength)191 static UINT transportEnc_LatmCountVarBitDemandHeader(
192     HANDLE_LATM_STREAM hAss, unsigned int streamDataLength) {
193   int bitDemand = 0;
194   int prog, layer;
195 
196   /* Payload Length Info*/
197   if (hAss->allStreamsSameTimeFraming) {
198     for (prog = 0; prog < hAss->noProgram; prog++) {
199       for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
200         LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
201 
202         if (p_linfo->streamID >= 0) {
203           switch (p_linfo->frameLengthType) {
204             case 0:
205               if (streamDataLength > 0) {
206                 streamDataLength -= bitDemand;
207                 while (streamDataLength >= (255 << 3)) {
208                   bitDemand += 8;
209                   streamDataLength -= (255 << 3);
210                 }
211                 bitDemand += 8;
212               }
213               break;
214 
215             case 1:
216             case 4:
217             case 6:
218               bitDemand += 2;
219               break;
220 
221             default:
222               return 0;
223           }
224         }
225       }
226     }
227   } else {
228     /* there are many possibilities to use this mechanism.  */
229     switch (hAss->varMode) {
230       case LATMVAR_SIMPLE_SEQUENCE: {
231         /* Use the sequence generated by the encoder */
232         // int streamCntPosition = transportEnc_SetWritePointer(
233         // hAss->hAssemble, 0 );  int streamCntPosition = FDKgetValidBits(
234         // hAss->hAssemble );
235         bitDemand += 4;
236 
237         hAss->varStreamCnt = 0;
238         for (prog = 0; prog < hAss->noProgram; prog++) {
239           for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
240             LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
241 
242             if (p_linfo->streamID >= 0) {
243               bitDemand += 4; /* streamID */
244               switch (p_linfo->frameLengthType) {
245                 case 0:
246                   streamDataLength -= bitDemand;
247                   while (streamDataLength >= (255 << 3)) {
248                     bitDemand += 8;
249                     streamDataLength -= (255 << 3);
250                   }
251 
252                   bitDemand += 8;
253                   break;
254                   /*bitDemand += 1; endFlag
255                   break;*/
256 
257                 case 1:
258                 case 4:
259                 case 6:
260 
261                   break;
262 
263                 default:
264                   return 0;
265               }
266               hAss->varStreamCnt++;
267             }
268           }
269         }
270         bitDemand += 4;
271         // transportEnc_UpdateBitstreamField( hAss->hAssemble,
272         // streamCntPosition, hAss->varStreamCnt-1, 4 );  UINT pos =
273         // streamCntPosition-FDKgetValidBits(hAss->hAssemble);  FDKpushBack(
274         // hAss->hAssemble,  pos);  FDKwriteBits( hAss->hAssemble,
275         // hAss->varStreamCnt-1, 4);  FDKpushFor( hAss->hAssemble, pos-4);
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(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
288                       int bufferFullness, CSTpCallBacks *cb) {
289   INT streamIDcnt, tmp;
290   int layer, prog;
291 
292   USHORT coreFrameOffset = 0;
293 
294   hAss->taraBufferFullness = 0xFF;
295   hAss->audioMuxVersionA = 0; /* for future extensions */
296   hAss->streamMuxConfigBits = 0;
297 
298   FDKwriteBits(hBs, hAss->audioMuxVersion, 1); /* audioMuxVersion */
299   hAss->streamMuxConfigBits += 1;
300 
301   if (hAss->audioMuxVersion == 1) {
302     FDKwriteBits(hBs, hAss->audioMuxVersionA, 1); /* audioMuxVersionA */
303     hAss->streamMuxConfigBits += 1;
304   }
305 
306   if (hAss->audioMuxVersionA == 0) {
307     if (hAss->audioMuxVersion == 1) {
308       hAss->streamMuxConfigBits += transportEnc_LatmWriteValue(
309           hBs, hAss->taraBufferFullness); /* taraBufferFullness */
310     }
311     FDKwriteBits(hBs, hAss->allStreamsSameTimeFraming ? 1 : 0,
312                  1);                             /* allStreamsSameTimeFraming */
313     FDKwriteBits(hBs, hAss->noSubframes - 1, 6); /* Number of Subframes */
314     FDKwriteBits(hBs, hAss->noProgram - 1, 4);   /* Number of Programs */
315 
316     hAss->streamMuxConfigBits += 11;
317 
318     streamIDcnt = 0;
319     for (prog = 0; prog < hAss->noProgram; prog++) {
320       int transLayer = 0;
321 
322       FDKwriteBits(hBs, hAss->noLayer[prog] - 1, 3);
323       hAss->streamMuxConfigBits += 3;
324 
325       for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
326         LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]);
327         CODER_CONFIG *p_lci = hAss->config[prog][layer];
328 
329         p_linfo->streamID = -1;
330 
331         if (hAss->config[prog][layer] != NULL) {
332           int useSameConfig = 0;
333 
334           if (transLayer > 0) {
335             FDKwriteBits(hBs, useSameConfig ? 1 : 0, 1);
336             hAss->streamMuxConfigBits += 1;
337           }
338           if ((useSameConfig == 0) || (transLayer == 0)) {
339             const UINT alignAnchor = FDKgetValidBits(hBs);
340 
341             if (0 !=
342                 (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
343               return TRANSPORTENC_UNKOWN_ERROR;
344             }
345 
346             if (hAss->audioMuxVersion == 1) {
347               UINT ascLen = transportEnc_LatmWriteValue(hBs, 0);
348               FDKbyteAlign(hBs, alignAnchor);
349               ascLen = FDKgetValidBits(hBs) - alignAnchor - ascLen;
350               FDKpushBack(hBs, FDKgetValidBits(hBs) - alignAnchor);
351 
352               transportEnc_LatmWriteValue(hBs, ascLen);
353 
354               if (0 !=
355                   (transportEnc_writeASC(hBs, hAss->config[prog][layer], cb))) {
356                 return TRANSPORTENC_UNKOWN_ERROR;
357               }
358 
359               FDKbyteAlign(hBs, alignAnchor); /* asc length fillbits */
360             }
361 
362             hAss->streamMuxConfigBits +=
363                 FDKgetValidBits(hBs) -
364                 alignAnchor; /* add asc length to smc summary */
365           }
366           transLayer++;
367 
368           if (!hAss->allStreamsSameTimeFraming) {
369             if (streamIDcnt >= LATM_MAX_STREAM_ID)
370               return TRANSPORTENC_INVALID_CONFIG;
371           }
372           p_linfo->streamID = streamIDcnt++;
373 
374           switch (p_lci->aot) {
375             case AOT_AAC_MAIN:
376             case AOT_AAC_LC:
377             case AOT_AAC_SSR:
378             case AOT_AAC_LTP:
379             case AOT_AAC_SCAL:
380             case AOT_ER_AAC_LD:
381             case AOT_ER_AAC_ELD:
382             case AOT_USAC:
383               p_linfo->frameLengthType = 0;
384 
385               FDKwriteBits(hBs, p_linfo->frameLengthType,
386                            3);                      /* frameLengthType */
387               FDKwriteBits(hBs, bufferFullness, 8); /* bufferFullness */
388               hAss->streamMuxConfigBits += 11;
389 
390               if (!hAss->allStreamsSameTimeFraming) {
391                 CODER_CONFIG *p_lci_prev = hAss->config[prog][layer - 1];
392                 if (((p_lci->aot == AOT_AAC_SCAL) ||
393                      (p_lci->aot == AOT_ER_AAC_SCAL)) &&
394                     ((p_lci_prev->aot == AOT_CELP) ||
395                      (p_lci_prev->aot == AOT_ER_CELP))) {
396                   FDKwriteBits(hBs, coreFrameOffset, 6); /* coreFrameOffset */
397                   hAss->streamMuxConfigBits += 6;
398                 }
399               }
400               break;
401 
402             case AOT_TWIN_VQ:
403               p_linfo->frameLengthType = 1;
404               tmp = ((p_lci->bitsFrame + 7) >> 3) -
405                     20; /* transmission frame length in bytes */
406               if ((tmp < 0)) {
407                 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH;
408               }
409               FDKwriteBits(hBs, p_linfo->frameLengthType,
410                            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,
420                            3); /* frameLengthType */
421               hAss->streamMuxConfigBits += 3;
422               {
423                 int i;
424                 for (i = 0; i < 62; i++) {
425                   if (celpFrameLengthTable[i] == p_lci->bitsFrame) 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,
440                            3); /* frameLengthType */
441               hAss->streamMuxConfigBits += 3;
442               {
443                 int i;
444 
445                 if (p_lci->bitsFrame == 40) {
446                   i = 0;
447                 } else if (p_lci->bitsFrame == 80) {
448                   i = 1;
449                 } else {
450                   return TRANSPORTENC_INVALID_FRAME_BITS;
451                 }
452                 FDKwriteBits(hBs, i, 1); /* HVXCframeLengthTableIndex */
453                 hAss->streamMuxConfigBits += 1;
454               }
455               p_linfo->frameLengthBits = p_lci->bitsFrame;
456               break;
457 
458             case AOT_NULL_OBJECT:
459             default:
460               return TRANSPORTENC_INVALID_AOT;
461           }
462         }
463       }
464     }
465 
466     FDKwriteBits(hBs, (hAss->otherDataLenBits > 0) ? 1 : 0,
467                  1); /* otherDataPresent */
468     hAss->streamMuxConfigBits += 1;
469 
470     if (hAss->otherDataLenBits > 0) {
471       FDKwriteBits(hBs, 0, 1);
472       FDKwriteBits(hBs, hAss->otherDataLenBits, 8);
473       hAss->streamMuxConfigBits += 9;
474     }
475 
476     FDKwriteBits(hBs, 0, 1); /* crcCheckPresent=0 */
477     hAss->streamMuxConfigBits += 1;
478 
479   } else { /* if ( audioMuxVersionA == 0 ) */
480 
481     /* for future extensions */
482   }
483 
484   return TRANSPORTENC_OK;
485 }
486 
WriteAuPayloadLengthInfo(HANDLE_FDK_BITSTREAM hBitStream,int AuLengthBits)487 static TRANSPORTENC_ERROR WriteAuPayloadLengthInfo(
488     HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits) {
489   int restBytes;
490 
491   if (AuLengthBits % 8) return TRANSPORTENC_INVALID_AU_LENGTH;
492 
493   while (AuLengthBits >= 255 * 8) {
494     FDKwriteBits(hBitStream, 255, 8); /* 255 shows incomplete AU */
495     AuLengthBits -= (255 * 8);
496   }
497 
498   restBytes = (AuLengthBits) >> 3;
499   FDKwriteBits(hBitStream, restBytes, 8);
500 
501   return TRANSPORTENC_OK;
502 }
503 
transportEnc_LatmSetNrOfSubframes(HANDLE_LATM_STREAM hAss,INT noSubframes_next)504 static TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes(
505     HANDLE_LATM_STREAM hAss, INT noSubframes_next) /* nr of access units /
506                                                       payloads within a latm
507                                                       frame */
508 {
509   /* sanity chk */
510   if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) {
511     return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES;
512   }
513 
514   hAss->noSubframes_next = noSubframes_next;
515 
516   /* if at start then we can take over the value immediately, otherwise we have
517    * to wait for the next SMC */
518   if ((hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0)) {
519     hAss->noSubframes = noSubframes_next;
520   }
521 
522   return TRANSPORTENC_OK;
523 }
524 
allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss,UCHAR noProgram,UCHAR noLayer[])525 static int allStreamsSameTimeFraming(HANDLE_LATM_STREAM hAss, UCHAR noProgram,
526                                      UCHAR noLayer[] /* return */) {
527   int prog, layer;
528 
529   signed int lastNoSamples = -1;
530   signed int minFrameSamples = FDK_INT_MAX;
531   signed int maxFrameSamples = 0;
532 
533   signed int highestSamplingRate = -1;
534 
535   for (prog = 0; prog < noProgram; prog++) {
536     noLayer[prog] = 0;
537 
538     for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
539       if (hAss->config[prog][layer] != NULL) {
540         INT hsfSamplesFrame;
541 
542         noLayer[prog]++;
543 
544         if (highestSamplingRate < 0)
545           highestSamplingRate = hAss->config[prog][layer]->samplingRate;
546 
547         hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame *
548                           highestSamplingRate /
549                           hAss->config[prog][layer]->samplingRate;
550 
551         if (hsfSamplesFrame <= minFrameSamples)
552           minFrameSamples = hsfSamplesFrame;
553         if (hsfSamplesFrame >= maxFrameSamples)
554           maxFrameSamples = hsfSamplesFrame;
555 
556         if (lastNoSamples == -1) {
557           lastNoSamples = hsfSamplesFrame;
558         } else {
559           if (hsfSamplesFrame != lastNoSamples) {
560             return 0;
561           }
562         }
563       }
564     }
565   }
566 
567   return 1;
568 }
569 
570 /**
571  * Initialize LATM/LOAS Stream and add layer 0 at program 0.
572  */
transportEnc_InitLatmStream(HANDLE_LATM_STREAM hAss,int fractDelayPresent,signed int muxConfigPeriod,UINT audioMuxVersion,TRANSPORT_TYPE tt)573 static TRANSPORTENC_ERROR transportEnc_InitLatmStream(
574     HANDLE_LATM_STREAM hAss, int fractDelayPresent,
575     signed int
576         muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */
577     UINT audioMuxVersion, TRANSPORT_TYPE tt) {
578   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
579 
580   if (hAss == NULL) return TRANSPORTENC_INVALID_PARAMETER;
581 
582   hAss->tt = tt;
583 
584   hAss->noProgram = 1;
585 
586   hAss->audioMuxVersion = audioMuxVersion;
587 
588   /* Fill noLayer array using hAss->config */
589   hAss->allStreamsSameTimeFraming =
590       allStreamsSameTimeFraming(hAss, hAss->noProgram, hAss->noLayer);
591   /* Only allStreamsSameTimeFraming==1 is supported */
592   FDK_ASSERT(hAss->allStreamsSameTimeFraming);
593 
594   hAss->fractDelayPresent = fractDelayPresent;
595   hAss->otherDataLenBits = 0;
596 
597   hAss->varMode = LATMVAR_SIMPLE_SEQUENCE;
598 
599   /* initialize counters */
600   hAss->subFrameCnt = 0;
601   hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES;
602   hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES;
603 
604   /* sync layer related */
605   hAss->audioMuxLengthBytes = 0;
606 
607   hAss->latmFrameCounter = 0;
608   hAss->muxConfigPeriod = muxConfigPeriod;
609 
610   return ErrorStatus;
611 }
612 
613 /**
614  *
615  */
transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,unsigned int streamDataLength)616 UINT transportEnc_LatmCountTotalBitDemandHeader(HANDLE_LATM_STREAM hAss,
617                                                 unsigned int streamDataLength) {
618   UINT bitDemand = 0;
619 
620   switch (hAss->tt) {
621     case TT_MP4_LOAS:
622     case TT_MP4_LATM_MCP0:
623     case TT_MP4_LATM_MCP1:
624       if (hAss->subFrameCnt == 0) {
625         bitDemand = transportEnc_LatmCountFixBitDemandHeader(hAss);
626       }
627       bitDemand += transportEnc_LatmCountVarBitDemandHeader(
628           hAss, streamDataLength /*- bitDemand*/);
629       break;
630     default:
631       break;
632   }
633 
634   return bitDemand;
635 }
636 
AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)637 static TRANSPORTENC_ERROR AdvanceAudioMuxElement(HANDLE_LATM_STREAM hAss,
638                                                  HANDLE_FDK_BITSTREAM hBs,
639                                                  int auBits, int bufferFullness,
640                                                  CSTpCallBacks *cb) {
641   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
642   int insertMuxSetup;
643 
644   /* Insert setup data to assemble Buffer */
645   if (hAss->subFrameCnt == 0) {
646     if (hAss->muxConfigPeriod > 0) {
647       insertMuxSetup = (hAss->latmFrameCounter == 0);
648     } else {
649       insertMuxSetup = 0;
650     }
651 
652     if (hAss->tt != TT_MP4_LATM_MCP0) {
653       if (insertMuxSetup) {
654         FDKwriteBits(hBs, 0, 1); /* useSameStreamMux useNewStreamMux */
655         if (TRANSPORTENC_OK != (ErrorStatus = CreateStreamMuxConfig(
656                                     hAss, hBs, bufferFullness, cb))) {
657           return ErrorStatus;
658         }
659       } else {
660         FDKwriteBits(hBs, 1, 1); /* useSameStreamMux */
661       }
662     }
663   }
664 
665   /* PayloadLengthInfo */
666   {
667     int prog, layer;
668 
669     for (prog = 0; prog < hAss->noProgram; prog++) {
670       for (layer = 0; layer < hAss->noLayer[prog]; layer++) {
671         ErrorStatus = WriteAuPayloadLengthInfo(hBs, auBits);
672         if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
673       }
674     }
675   }
676   /* At this point comes the access unit. */
677 
678   return TRANSPORTENC_OK;
679 }
680 
681 TRANSPORTENC_ERROR
transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int auBits,int bufferFullness,CSTpCallBacks * cb)682 transportEnc_LatmWrite(HANDLE_LATM_STREAM hAss, HANDLE_FDK_BITSTREAM hBs,
683                        int auBits, int bufferFullness, CSTpCallBacks *cb) {
684   TRANSPORTENC_ERROR ErrorStatus;
685 
686   if (hAss->subFrameCnt == 0) {
687     /* Start new frame */
688     FDKresetBitbuffer(hBs, BS_WRITER);
689   }
690 
691   hAss->latmSubframeStart = FDKgetValidBits(hBs);
692 
693   /* Insert syncword and syncword distance
694      - only if loas
695      - we must update the syncword distance (=audiomuxlengthbytes) later
696    */
697   if (hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0) {
698     /* Start new LOAS frame */
699     FDKwriteBits(hBs, 0x2B7, 11);
700     hAss->audioMuxLengthBytes = 0;
701     hAss->audioMuxLengthBytesPos =
702         FDKgetValidBits(hBs); /* store read pointer position */
703     FDKwriteBits(hBs, hAss->audioMuxLengthBytes, 13);
704   }
705 
706   ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, auBits, bufferFullness, cb);
707 
708   if (ErrorStatus != TRANSPORTENC_OK) return ErrorStatus;
709 
710   return ErrorStatus;
711 }
712 
transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss,int * bits)713 void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss, int *bits) {
714   /* Substract bits from possible previous subframe */
715   *bits -= hAss->latmSubframeStart;
716   /* Add fill bits */
717   if (hAss->subFrameCnt == 0) {
718     *bits += hAss->otherDataLenBits;
719     *bits += hAss->fillBits;
720   }
721 }
722 
transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,int * pBytes)723 TRANSPORTENC_ERROR transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss,
724                                              HANDLE_FDK_BITSTREAM hBs,
725                                              int *pBytes) {
726   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
727 
728   hAss->subFrameCnt++;
729   if (hAss->subFrameCnt >= hAss->noSubframes) {
730     /* Add LOAS frame length if required. */
731     if (hAss->tt == TT_MP4_LOAS) {
732       FDK_BITSTREAM tmpBuf;
733 
734       /* Determine frame length info */
735       hAss->audioMuxLengthBytes =
736           ((FDKgetValidBits(hBs) + hAss->otherDataLenBits + 7) >> 3) -
737           3; /* 3=Syncword + length */
738 
739       /* Check frame length info */
740       if (hAss->audioMuxLengthBytes >= (1 << 13)) {
741         ErrorStatus = TRANSPORTENC_INVALID_AU_LENGTH;
742         goto bail;
743       }
744 
745       /* Write length info into assembler buffer */
746       FDKinitBitStream(&tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0,
747                        BS_WRITER);
748       FDKpushFor(&tmpBuf, hAss->audioMuxLengthBytesPos);
749       FDKwriteBits(&tmpBuf, hAss->audioMuxLengthBytes, 13);
750       FDKsyncCache(&tmpBuf);
751     }
752 
753     /* Write AudioMuxElement other data bits */
754     FDKwriteBits(hBs, 0, hAss->otherDataLenBits);
755 
756     /* Write AudioMuxElement byte alignment fill bits */
757     FDKwriteBits(hBs, 0, hAss->fillBits);
758 
759     FDK_ASSERT((FDKgetValidBits(hBs) % 8) == 0);
760 
761     hAss->subFrameCnt = 0;
762 
763     FDKsyncCache(hBs);
764     *pBytes = (FDKgetValidBits(hBs) + 7) >> 3;
765 
766     if (hAss->muxConfigPeriod > 0) {
767       hAss->latmFrameCounter++;
768 
769       if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) {
770         hAss->latmFrameCounter = 0;
771         hAss->noSubframes = hAss->noSubframes_next;
772       }
773     }
774   } else {
775     /* No data this time */
776     *pBytes = 0;
777   }
778 
779 bail:
780   return ErrorStatus;
781 }
782 
783 /**
784  * Init LATM/LOAS
785  */
transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,HANDLE_FDK_BITSTREAM hBs,CODER_CONFIG * layerConfig,UINT audioMuxVersion,TRANSPORT_TYPE tt,CSTpCallBacks * cb)786 TRANSPORTENC_ERROR transportEnc_Latm_Init(HANDLE_LATM_STREAM hAss,
787                                           HANDLE_FDK_BITSTREAM hBs,
788                                           CODER_CONFIG *layerConfig,
789                                           UINT audioMuxVersion,
790                                           TRANSPORT_TYPE tt,
791                                           CSTpCallBacks *cb) {
792   TRANSPORTENC_ERROR ErrorStatus;
793   int fractDelayPresent = 0;
794   int prog, layer;
795 
796   int setupDataDistanceFrames = layerConfig->headerPeriod;
797 
798   FDK_ASSERT(setupDataDistanceFrames >= 0);
799 
800   for (prog = 0; prog < LATM_MAX_PROGRAMS; prog++) {
801     for (layer = 0; layer < LATM_MAX_LAYERS; layer++) {
802       hAss->config[prog][layer] = NULL;
803       hAss->m_linfo[prog][layer].streamID = -1;
804     }
805   }
806 
807   hAss->config[0][0] = layerConfig;
808   hAss->m_linfo[0][0].streamID = 0;
809 
810   ErrorStatus = transportEnc_InitLatmStream(hAss, fractDelayPresent,
811                                             setupDataDistanceFrames,
812                                             (audioMuxVersion) ? 1 : 0, tt);
813   if (ErrorStatus != TRANSPORTENC_OK) goto bail;
814 
815   ErrorStatus =
816       transportEnc_LatmSetNrOfSubframes(hAss, layerConfig->nSubFrames);
817   if (ErrorStatus != TRANSPORTENC_OK) goto bail;
818 
819   /* Get the size of the StreamMuxConfig somehow */
820   if (TRANSPORTENC_OK !=
821       (ErrorStatus = AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb))) {
822     goto bail;
823   }
824 
825   // CreateStreamMuxConfig(hAss, hBs, 0);
826 
827 bail:
828   return ErrorStatus;
829 }
830 
transportEnc_LatmAddOtherDataBits(HANDLE_LATM_STREAM hAss,const int otherDataBits)831 TRANSPORTENC_ERROR transportEnc_LatmAddOtherDataBits(HANDLE_LATM_STREAM hAss,
832                                                      const int otherDataBits) {
833   TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK;
834 
835   if ((hAss->otherDataLenBits != 0) || (otherDataBits % 8 != 0)) {
836     /* This implementation allows to add other data bits only once.
837        To keep existing alignment only whole bytes are allowed. */
838     ErrorStatus = TRANSPORTENC_UNKOWN_ERROR;
839   } else {
840     /* Ensure correct addional bits in payload. */
841     if (hAss->tt == TT_MP4_LATM_MCP0) {
842       hAss->otherDataLenBits = otherDataBits;
843     } else {
844       hAss->otherDataLenBits = otherDataBits - 9;
845       hAss->streamMuxConfigBits += 9;
846     }
847   }
848 
849   return ErrorStatus;
850 }
851