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):   Manuel Jander
98 
99    Description: MPEG Transport encode
100 
101 *******************************************************************************/
102 
103 #include "tpenc_lib.h"
104 
105 /* library info */
106 #include "tp_version.h"
107 
108 #define MODULE_NAME "transportEnc"
109 
110 #include "tpenc_asc.h"
111 
112 #include "tpenc_adts.h"
113 
114 #include "tpenc_adif.h"
115 
116 #include "tpenc_latm.h"
117 
118 typedef struct {
119   int curSubFrame;
120   int nSubFrames;
121   int prevBits;
122 } RAWPACKETS_INFO;
123 
124 struct TRANSPORTENC {
125   CODER_CONFIG config;
126   TRANSPORT_TYPE transportFmt; /*!< MPEG4 transport type. */
127 
128   FDK_BITSTREAM bitStream;
129   UCHAR *bsBuffer;
130   INT bsBufferSize;
131 
132   INT pceFrameCounter; /*!< Indicates frame period when PCE must be written in
133                           raw_data_block. -1 means not to write a PCE in
134                           raw_dat_block. */
135   union {
136     STRUCT_ADTS adts;
137 
138     ADIF_INFO adif;
139 
140     LATM_STREAM latm;
141 
142     RAWPACKETS_INFO raw;
143 
144   } writer;
145 
146   CSTpCallBacks callbacks;
147 };
148 
149 typedef struct _TRANSPORTENC_STRUCT TRANSPORTENC_STRUCT;
150 
151 /*
152  * MEMORY Declaration
153  */
154 
155 C_ALLOC_MEM(Ram_TransportEncoder, struct TRANSPORTENC, 1)
156 
transportEnc_Open(HANDLE_TRANSPORTENC * phTpEnc)157 TRANSPORTENC_ERROR transportEnc_Open(HANDLE_TRANSPORTENC *phTpEnc) {
158   HANDLE_TRANSPORTENC hTpEnc;
159 
160   if (phTpEnc == NULL) {
161     return TRANSPORTENC_INVALID_PARAMETER;
162   }
163 
164   hTpEnc = GetRam_TransportEncoder(0);
165 
166   if (hTpEnc == NULL) {
167     return TRANSPORTENC_NO_MEM;
168   }
169 
170   *phTpEnc = hTpEnc;
171   return TRANSPORTENC_OK;
172 }
173 
174 /**
175  * \brief  Get frame period of PCE in raw_data_block.
176  *
177  * - Write PCE only if necessary. PCE can be part of the ASC if chConfig==0
178  * whererfore no additonal PCE will be written in raw_data_block.
179  * - A matrixMixdown coefficient can only be written if chConfig is 5.0 or 5.1.
180  * - The PCE repetition rate in raw_data_block can be controlled via
181  * headerPeriod parameter.
182  *
183  * \param channelMode           Encoder Channel Mode.
184  * \param channelConfigZero     No standard channel configuration.
185  * \param transportFmt          Format of the transport to be written.
186  * \param headerPeriod          Chosen PCE frame repetition rate.
187  * \param matrixMixdownA        Indicates if a valid Matrix Mixdown coefficient
188  * is available.
189  *
190  * \return  PCE frame repetition rate. -1 means no PCE present in
191  * raw_data_block.
192  */
getPceRepetitionRate(const CHANNEL_MODE channelMode,const int channelConfigZero,const TRANSPORT_TYPE transportFmt,const int headerPeriod,const int matrixMixdownA)193 static INT getPceRepetitionRate(const CHANNEL_MODE channelMode,
194                                 const int channelConfigZero,
195                                 const TRANSPORT_TYPE transportFmt,
196                                 const int headerPeriod,
197                                 const int matrixMixdownA) {
198   INT pceFrameCounter = -1; /* variable to be returned */
199 
200   if (headerPeriod > 0) {
201     switch (getChannelConfig(channelMode, channelConfigZero)) {
202       case 0:
203         switch (transportFmt) {
204           case TT_MP4_ADTS:
205           case TT_MP4_LATM_MCP0:
206           case TT_MP4_RAW:
207             pceFrameCounter = headerPeriod;
208             break;
209           case TT_MP4_ADIF: /* ADIF header comprises PCE */
210             if ((channelMode == MODE_1_2_2) || (channelMode == MODE_1_2_2_1)) {
211               pceFrameCounter = headerPeriod; /* repeating pce only meaningful
212                                                  for potential matrix mixdown */
213               break;
214             }
215             FDK_FALLTHROUGH;
216           case TT_MP4_LOAS:      /* PCE in ASC if chChonfig==0 */
217           case TT_MP4_LATM_MCP1: /* PCE in ASC if chChonfig==0 */
218           default:
219             pceFrameCounter = -1; /* no PCE in raw_data_block */
220         }
221         break;
222       case 5: /* MODE_1_2_2 */
223       case 6: /* MODE_1_2_2_1 */
224         /* matrixMixdownCoefficient can only be written if 5.0 and 5.1 config
225          * present. */
226         if (matrixMixdownA != 0) {
227           switch (transportFmt) {
228             case TT_MP4_ADIF: /* ADIF header comprises PCE */
229             case TT_MP4_ADTS:
230             case TT_MP4_LOAS:      /* no PCE in ASC because chConfig!=0 */
231             case TT_MP4_LATM_MCP1: /* no PCE in ASC because chConfig!=0 */
232             case TT_MP4_LATM_MCP0:
233             case TT_MP4_RAW:
234               pceFrameCounter = headerPeriod;
235               break;
236             default:
237               pceFrameCounter = -1; /* no PCE in raw_data_block */
238           }                         /* switch transportFmt */
239         }                           /* if matrixMixdownA!=0 */
240         break;
241       default:
242         pceFrameCounter = -1; /* no PCE in raw_data_block */
243     }                         /* switch getChannelConfig() */
244   }                           /* if headerPeriod>0  */
245   else {
246     pceFrameCounter = -1; /* no PCE in raw_data_block */
247   }
248 
249   return pceFrameCounter;
250 }
251 
transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,UCHAR * bsBuffer,INT bsBufferSize,TRANSPORT_TYPE transportFmt,CODER_CONFIG * cconfig,UINT flags)252 TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
253                                      UCHAR *bsBuffer, INT bsBufferSize,
254                                      TRANSPORT_TYPE transportFmt,
255                                      CODER_CONFIG *cconfig, UINT flags) {
256   /* Copy configuration structure */
257   FDKmemcpy(&hTpEnc->config, cconfig, sizeof(CODER_CONFIG));
258 
259   /* Init transportEnc struct. */
260   hTpEnc->transportFmt = transportFmt;
261 
262   hTpEnc->bsBuffer = bsBuffer;
263   hTpEnc->bsBufferSize = bsBufferSize;
264 
265   FDKinitBitStream(&hTpEnc->bitStream, hTpEnc->bsBuffer, hTpEnc->bsBufferSize,
266                    0, BS_WRITER);
267 
268   switch (transportFmt) {
269     case TT_MP4_ADIF:
270       /* Sanity checks */
271       if ((hTpEnc->config.aot != AOT_AAC_LC) ||
272           (hTpEnc->config.samplesPerFrame != 1024)) {
273         return TRANSPORTENC_INVALID_PARAMETER;
274       }
275       hTpEnc->writer.adif.headerWritten = 0;
276       hTpEnc->writer.adif.samplingRate = hTpEnc->config.samplingRate;
277       hTpEnc->writer.adif.bitRate = hTpEnc->config.bitRate;
278       hTpEnc->writer.adif.profile = ((int)hTpEnc->config.aot) - 1;
279       hTpEnc->writer.adif.cm = hTpEnc->config.channelMode;
280       hTpEnc->writer.adif.bVariableRate = 0;
281       hTpEnc->writer.adif.instanceTag = 0;
282       hTpEnc->writer.adif.matrixMixdownA = hTpEnc->config.matrixMixdownA;
283       hTpEnc->writer.adif.pseudoSurroundEnable =
284           (hTpEnc->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0;
285       break;
286 
287     case TT_MP4_ADTS:
288       /* Sanity checks */
289       if ((hTpEnc->config.aot != AOT_AAC_LC) ||
290           (hTpEnc->config.samplesPerFrame != 1024)) {
291         return TRANSPORTENC_INVALID_PARAMETER;
292       }
293       if (adtsWrite_Init(&hTpEnc->writer.adts, &hTpEnc->config) != 0) {
294         return TRANSPORTENC_INVALID_PARAMETER;
295       }
296       break;
297 
298     case TT_MP4_LOAS:
299     case TT_MP4_LATM_MCP0:
300     case TT_MP4_LATM_MCP1: {
301       TRANSPORTENC_ERROR error;
302 
303       error = transportEnc_Latm_Init(&hTpEnc->writer.latm, &hTpEnc->bitStream,
304                                      &hTpEnc->config, flags & TP_FLAG_LATM_AMV,
305                                      transportFmt, &hTpEnc->callbacks);
306       if (error != TRANSPORTENC_OK) {
307         return error;
308       }
309     } break;
310 
311     case TT_MP4_RAW:
312       hTpEnc->writer.raw.curSubFrame = 0;
313       hTpEnc->writer.raw.nSubFrames = hTpEnc->config.nSubFrames;
314       break;
315 
316     default:
317       return TRANSPORTENC_INVALID_PARAMETER;
318   }
319 
320   /* pceFrameCounter indicates if PCE must be written in raw_data_block. */
321   hTpEnc->pceFrameCounter = getPceRepetitionRate(
322       hTpEnc->config.channelMode, hTpEnc->config.channelConfigZero,
323       transportFmt, hTpEnc->config.headerPeriod, hTpEnc->config.matrixMixdownA);
324 
325   return TRANSPORTENC_OK;
326 }
327 
transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,const int nBits)328 TRANSPORTENC_ERROR transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,
329                                                  const int nBits) {
330   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
331 
332   switch (hTpEnc->transportFmt) {
333     case TT_MP4_LATM_MCP0:
334     case TT_MP4_LATM_MCP1:
335     case TT_MP4_LOAS:
336       tpErr = transportEnc_LatmAddOtherDataBits(&hTpEnc->writer.latm, nBits);
337       break;
338     case TT_MP4_ADTS:
339     case TT_MP4_ADIF:
340     case TT_MP4_RAW:
341     default:
342       tpErr = TRANSPORTENC_UNKOWN_ERROR;
343   }
344 
345   return tpErr;
346 }
347 
transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp)348 HANDLE_FDK_BITSTREAM transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp) {
349   return &hTp->bitStream;
350 }
351 
transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,const cbSbr_t cbSbr,void * user_data)352 int transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,
353                                      const cbSbr_t cbSbr, void *user_data) {
354   if (hTpEnc == NULL) {
355     return -1;
356   }
357   hTpEnc->callbacks.cbSbr = cbSbr;
358   hTpEnc->callbacks.cbSbrData = user_data;
359   return 0;
360 }
transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,const cbUsac_t cbUsac,void * user_data)361 int transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,
362                                       const cbUsac_t cbUsac, void *user_data) {
363   if (hTpEnc == NULL) {
364     return -1;
365   }
366   hTpEnc->callbacks.cbUsac = cbUsac;
367   hTpEnc->callbacks.cbUsacData = user_data;
368   return 0;
369 }
370 
transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,const cbSsc_t cbSsc,void * user_data)371 int transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,
372                                      const cbSsc_t cbSsc, void *user_data) {
373   if (hTpEnc == NULL) {
374     return -1;
375   }
376   hTpEnc->callbacks.cbSsc = cbSsc;
377   hTpEnc->callbacks.cbSscData = user_data;
378   return 0;
379 }
380 
transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,INT frameUsedBits,int bufferFullness,int ncc)381 TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
382                                                 INT frameUsedBits,
383                                                 int bufferFullness, int ncc) {
384   TRANSPORTENC_ERROR err = TRANSPORTENC_OK;
385 
386   if (!hTp) {
387     return TRANSPORTENC_INVALID_PARAMETER;
388   }
389   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;
390 
391   /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
392   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
393     frameUsedBits += transportEnc_GetPCEBits(
394         hTp->config.channelMode, hTp->config.matrixMixdownA,
395         3); /* Consider 3 bits ID signalling in alignment */
396   }
397 
398   switch (hTp->transportFmt) {
399     case TT_MP4_ADIF:
400       FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
401                        BS_WRITER);
402       if (0 != adifWrite_EncodeHeader(&hTp->writer.adif, hBs, bufferFullness)) {
403         err = TRANSPORTENC_INVALID_CONFIG;
404       }
405       break;
406     case TT_MP4_ADTS:
407       bufferFullness /= ncc; /* Number of Considered Channels */
408       bufferFullness /= 32;
409       bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
410       adtsWrite_EncodeHeader(&hTp->writer.adts, &hTp->bitStream, bufferFullness,
411                              frameUsedBits);
412       break;
413     case TT_MP4_LOAS:
414     case TT_MP4_LATM_MCP0:
415     case TT_MP4_LATM_MCP1:
416       bufferFullness /= ncc; /* Number of Considered Channels */
417       bufferFullness /= 32;
418       bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
419       transportEnc_LatmWrite(&hTp->writer.latm, hBs, frameUsedBits,
420                              bufferFullness, &hTp->callbacks);
421       break;
422     case TT_MP4_RAW:
423       if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
424         hTp->writer.raw.curSubFrame = 0;
425         FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
426                          BS_WRITER);
427       }
428       hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
429       break;
430     default:
431       err = TRANSPORTENC_UNSUPPORTED_FORMAT;
432       break;
433   }
434 
435   /* Write PCE in raw_data_block if required */
436   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
437     INT crcIndex = 0;
438     /* Align inside PCE with repsect to the first bit of the raw_data_block() */
439     UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);
440 
441     /* Write PCE element ID bits */
442     FDKwriteBits(&hTp->bitStream, ID_PCE, 3);
443 
444     if ((hTp->transportFmt == TT_MP4_ADTS) &&
445         !hTp->writer.adts.protection_absent) {
446       crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
447     }
448 
449     /* Write PCE as first raw_data_block element */
450     transportEnc_writePCE(
451         &hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0,
452         1, hTp->config.matrixMixdownA,
453         (hTp->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0, alignAnchor);
454 
455     if ((hTp->transportFmt == TT_MP4_ADTS) &&
456         !hTp->writer.adts.protection_absent) {
457       adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
458     }
459     hTp->pceFrameCounter = 0; /* reset pce frame counter */
460   }
461 
462   if (hTp->pceFrameCounter != -1) {
463     hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is
464                                active. */
465   }
466 
467   return err;
468 }
469 
transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,int * bits)470 TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
471                                               int *bits) {
472   switch (hTp->transportFmt) {
473     case TT_MP4_LATM_MCP0:
474     case TT_MP4_LATM_MCP1:
475     case TT_MP4_LOAS:
476       transportEnc_LatmAdjustSubframeBits(&hTp->writer.latm, bits);
477       break;
478     case TT_MP4_ADTS:
479       adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
480       break;
481     case TT_MP4_ADIF:
482       /* Substract ADIF header from AU bits, not to be considered. */
483       *bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
484       hTp->writer.adif.headerWritten = 1;
485       break;
486     case TT_MP4_RAW:
487       *bits -= hTp->writer.raw.prevBits;
488       break;
489     default:
490       break;
491   }
492 
493   return TRANSPORTENC_OK;
494 }
495 
transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,int * nbytes)496 TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
497                                          int *nbytes) {
498   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
499   HANDLE_FDK_BITSTREAM hBs = &hTpEnc->bitStream;
500 
501   switch (hTpEnc->transportFmt) {
502     case TT_MP4_LATM_MCP0:
503     case TT_MP4_LATM_MCP1:
504     case TT_MP4_LOAS:
505       *nbytes = hTpEnc->bsBufferSize;
506       tpErr = transportEnc_LatmGetFrame(&hTpEnc->writer.latm, hBs, nbytes);
507       break;
508     case TT_MP4_ADTS:
509       if (hTpEnc->writer.adts.currentBlock >=
510           hTpEnc->writer.adts.num_raw_blocks + 1) {
511         *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
512         hTpEnc->writer.adts.currentBlock = 0;
513       } else {
514         *nbytes = 0;
515       }
516       break;
517     case TT_MP4_ADIF:
518       FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
519       *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
520       break;
521     case TT_MP4_RAW:
522       FDKsyncCache(hBs);
523       hTpEnc->writer.raw.curSubFrame++;
524       *nbytes = ((FDKgetValidBits(hBs) - hTpEnc->writer.raw.prevBits) + 7) >> 3;
525       break;
526     default:
527       break;
528   }
529 
530   return tpErr;
531 }
532 
transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp,int auBits)533 INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits) {
534   INT nbits = 0, nPceBits = 0;
535 
536   /* Write PCE within raw_data_block in transport lib. */
537   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
538     nPceBits = transportEnc_GetPCEBits(
539         hTp->config.channelMode, hTp->config.matrixMixdownA,
540         3);             /* Consider 3 bits ID signalling in alignment */
541     auBits += nPceBits; /* Adapt required raw_data_block bit consumtpion for AU
542                            length information e.g. in LATM/LOAS configuration.
543                          */
544   }
545 
546   switch (hTp->transportFmt) {
547     case TT_MP4_ADIF:
548     case TT_MP4_RAW:
549       nbits = 0; /* Do not consider the ADIF header into the total bitrate */
550       break;
551     case TT_MP4_ADTS:
552       nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
553       break;
554     case TT_MP4_LOAS:
555     case TT_MP4_LATM_MCP0:
556     case TT_MP4_LATM_MCP1:
557       nbits =
558           transportEnc_LatmCountTotalBitDemandHeader(&hTp->writer.latm, auBits);
559       break;
560     default:
561       nbits = 0;
562       break;
563   }
564 
565   /* PCE is written in the transport library therefore the bit consumption is
566    * part of the transport static bits. */
567   nbits += nPceBits;
568 
569   return nbits;
570 }
571 
transportEnc_Close(HANDLE_TRANSPORTENC * phTp)572 void transportEnc_Close(HANDLE_TRANSPORTENC *phTp) {
573   if (phTp != NULL) {
574     if (*phTp != NULL) {
575       FreeRam_TransportEncoder(phTp);
576     }
577   }
578 }
579 
transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc,int mBits)580 int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits) {
581   int crcReg = 0;
582 
583   switch (hTpEnc->transportFmt) {
584     case TT_MP4_ADTS:
585       crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream,
586                                      mBits);
587       break;
588     default:
589       break;
590   }
591 
592   return crcReg;
593 }
594 
transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc,int reg)595 void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg) {
596   switch (hTpEnc->transportFmt) {
597     case TT_MP4_ADTS:
598       adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
599       break;
600     default:
601       break;
602   }
603 }
604 
transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,CODER_CONFIG * cc,FDK_BITSTREAM * dataBuffer,UINT * confType)605 TRANSPORTENC_ERROR transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,
606                                         CODER_CONFIG *cc,
607                                         FDK_BITSTREAM *dataBuffer,
608                                         UINT *confType) {
609   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
610   HANDLE_LATM_STREAM hLatmConfig = &hTpEnc->writer.latm;
611 
612   *confType = 0; /* set confType variable to default */
613 
614   /* write StreamMuxConfig or AudioSpecificConfig depending on format used */
615   switch (hTpEnc->transportFmt) {
616     case TT_MP4_LATM_MCP0:
617     case TT_MP4_LATM_MCP1:
618     case TT_MP4_LOAS:
619       tpErr =
620           CreateStreamMuxConfig(hLatmConfig, dataBuffer, 0, &hTpEnc->callbacks);
621       *confType = 1; /* config is SMC */
622       break;
623     default:
624       if (transportEnc_writeASC(dataBuffer, cc, &hTpEnc->callbacks) != 0) {
625         tpErr = TRANSPORTENC_UNKOWN_ERROR;
626       }
627   }
628 
629   return tpErr;
630 }
631 
transportEnc_GetLibInfo(LIB_INFO * info)632 TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
633   int i;
634 
635   if (info == NULL) {
636     return TRANSPORTENC_INVALID_PARAMETER;
637   }
638   /* search for next free tab */
639   for (i = 0; i < FDK_MODULE_LAST; i++) {
640     if (info[i].module_id == FDK_NONE) break;
641   }
642   if (i == FDK_MODULE_LAST) {
643     return TRANSPORTENC_UNKOWN_ERROR;
644   }
645   info += i;
646 
647   info->module_id = FDK_TPENC;
648   info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
649   LIB_VERSION_STRING(info);
650 #ifdef SUPPRESS_BUILD_DATE_INFO
651   info->build_date = "";
652   info->build_time = "";
653 #else
654   info->build_date = __DATE__;
655   info->build_time = __TIME__;
656 #endif
657   info->title = TP_LIB_TITLE;
658 
659   /* Set flags */
660   info->flags =
661       0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS;
662 
663   return TRANSPORTENC_OK;
664 }
665