• 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):   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           case TT_MP4_LOAS:      /* PCE in ASC if chChonfig==0 */
216           case TT_MP4_LATM_MCP1: /* PCE in ASC if chChonfig==0 */
217           default:
218             pceFrameCounter = -1; /* no PCE in raw_data_block */
219         }
220         break;
221       case 5: /* MODE_1_2_2 */
222       case 6: /* MODE_1_2_2_1 */
223         /* matrixMixdownCoefficient can only be written if 5.0 and 5.1 config
224          * present. */
225         if (matrixMixdownA != 0) {
226           switch (transportFmt) {
227             case TT_MP4_ADIF: /* ADIF header comprises PCE */
228             case TT_MP4_ADTS:
229             case TT_MP4_LOAS:      /* no PCE in ASC because chConfig!=0 */
230             case TT_MP4_LATM_MCP1: /* no PCE in ASC because chConfig!=0 */
231             case TT_MP4_LATM_MCP0:
232             case TT_MP4_RAW:
233               pceFrameCounter = headerPeriod;
234               break;
235             default:
236               pceFrameCounter = -1; /* no PCE in raw_data_block */
237           }                         /* switch transportFmt */
238         }                           /* if matrixMixdownA!=0 */
239         break;
240       default:
241         pceFrameCounter = -1; /* no PCE in raw_data_block */
242     }                         /* switch getChannelConfig() */
243   }                           /* if headerPeriod>0  */
244   else {
245     pceFrameCounter = -1; /* no PCE in raw_data_block */
246   }
247 
248   return pceFrameCounter;
249 }
250 
transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,UCHAR * bsBuffer,INT bsBufferSize,TRANSPORT_TYPE transportFmt,CODER_CONFIG * cconfig,UINT flags)251 TRANSPORTENC_ERROR transportEnc_Init(HANDLE_TRANSPORTENC hTpEnc,
252                                      UCHAR *bsBuffer, INT bsBufferSize,
253                                      TRANSPORT_TYPE transportFmt,
254                                      CODER_CONFIG *cconfig, UINT flags) {
255   /* Copy configuration structure */
256   FDKmemcpy(&hTpEnc->config, cconfig, sizeof(CODER_CONFIG));
257 
258   /* Init transportEnc struct. */
259   hTpEnc->transportFmt = transportFmt;
260 
261   hTpEnc->bsBuffer = bsBuffer;
262   hTpEnc->bsBufferSize = bsBufferSize;
263 
264   FDKinitBitStream(&hTpEnc->bitStream, hTpEnc->bsBuffer, hTpEnc->bsBufferSize,
265                    0, BS_WRITER);
266 
267   switch (transportFmt) {
268     case TT_MP4_ADIF:
269       /* Sanity checks */
270       if ((hTpEnc->config.aot != AOT_AAC_LC) ||
271           (hTpEnc->config.samplesPerFrame != 1024)) {
272         return TRANSPORTENC_INVALID_PARAMETER;
273       }
274       hTpEnc->writer.adif.headerWritten = 0;
275       hTpEnc->writer.adif.samplingRate = hTpEnc->config.samplingRate;
276       hTpEnc->writer.adif.bitRate = hTpEnc->config.bitRate;
277       hTpEnc->writer.adif.profile = ((int)hTpEnc->config.aot) - 1;
278       hTpEnc->writer.adif.cm = hTpEnc->config.channelMode;
279       hTpEnc->writer.adif.bVariableRate = 0;
280       hTpEnc->writer.adif.instanceTag = 0;
281       hTpEnc->writer.adif.matrixMixdownA = hTpEnc->config.matrixMixdownA;
282       hTpEnc->writer.adif.pseudoSurroundEnable =
283           (hTpEnc->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0;
284       break;
285 
286     case TT_MP4_ADTS:
287       /* Sanity checks */
288       if ((hTpEnc->config.aot != AOT_AAC_LC) ||
289           (hTpEnc->config.samplesPerFrame != 1024)) {
290         return TRANSPORTENC_INVALID_PARAMETER;
291       }
292       if (adtsWrite_Init(&hTpEnc->writer.adts, &hTpEnc->config) != 0) {
293         return TRANSPORTENC_INVALID_PARAMETER;
294       }
295       break;
296 
297     case TT_MP4_LOAS:
298     case TT_MP4_LATM_MCP0:
299     case TT_MP4_LATM_MCP1: {
300       TRANSPORTENC_ERROR error;
301 
302       error = transportEnc_Latm_Init(&hTpEnc->writer.latm, &hTpEnc->bitStream,
303                                      &hTpEnc->config, flags & TP_FLAG_LATM_AMV,
304                                      transportFmt, &hTpEnc->callbacks);
305       if (error != TRANSPORTENC_OK) {
306         return error;
307       }
308     } break;
309 
310     case TT_MP4_RAW:
311       hTpEnc->writer.raw.curSubFrame = 0;
312       hTpEnc->writer.raw.nSubFrames = hTpEnc->config.nSubFrames;
313       break;
314 
315     default:
316       return TRANSPORTENC_INVALID_PARAMETER;
317   }
318 
319   /* pceFrameCounter indicates if PCE must be written in raw_data_block. */
320   hTpEnc->pceFrameCounter = getPceRepetitionRate(
321       hTpEnc->config.channelMode, hTpEnc->config.channelConfigZero,
322       transportFmt, hTpEnc->config.headerPeriod, hTpEnc->config.matrixMixdownA);
323 
324   return TRANSPORTENC_OK;
325 }
326 
transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,const int nBits)327 TRANSPORTENC_ERROR transportEnc_AddOtherDataBits(HANDLE_TRANSPORTENC hTpEnc,
328                                                  const int nBits) {
329   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
330 
331   switch (hTpEnc->transportFmt) {
332     case TT_MP4_LATM_MCP0:
333     case TT_MP4_LATM_MCP1:
334     case TT_MP4_LOAS:
335       tpErr = transportEnc_LatmAddOtherDataBits(&hTpEnc->writer.latm, nBits);
336       break;
337     case TT_MP4_ADTS:
338     case TT_MP4_ADIF:
339     case TT_MP4_RAW:
340     default:
341       tpErr = TRANSPORTENC_UNKOWN_ERROR;
342   }
343 
344   return tpErr;
345 }
346 
transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp)347 HANDLE_FDK_BITSTREAM transportEnc_GetBitstream(HANDLE_TRANSPORTENC hTp) {
348   return &hTp->bitStream;
349 }
350 
transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,const cbSbr_t cbSbr,void * user_data)351 int transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc,
352                                      const cbSbr_t cbSbr, void *user_data) {
353   if (hTpEnc == NULL) {
354     return -1;
355   }
356   hTpEnc->callbacks.cbSbr = cbSbr;
357   hTpEnc->callbacks.cbSbrData = user_data;
358   return 0;
359 }
transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,const cbUsac_t cbUsac,void * user_data)360 int transportEnc_RegisterUsacCallback(HANDLE_TRANSPORTENC hTpEnc,
361                                       const cbUsac_t cbUsac, void *user_data) {
362   if (hTpEnc == NULL) {
363     return -1;
364   }
365   hTpEnc->callbacks.cbUsac = cbUsac;
366   hTpEnc->callbacks.cbUsacData = user_data;
367   return 0;
368 }
369 
transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,const cbSsc_t cbSsc,void * user_data)370 int transportEnc_RegisterSscCallback(HANDLE_TRANSPORTENC hTpEnc,
371                                      const cbSsc_t cbSsc, void *user_data) {
372   if (hTpEnc == NULL) {
373     return -1;
374   }
375   hTpEnc->callbacks.cbSsc = cbSsc;
376   hTpEnc->callbacks.cbSscData = user_data;
377   return 0;
378 }
379 
transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,INT frameUsedBits,int bufferFullness,int ncc)380 TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(HANDLE_TRANSPORTENC hTp,
381                                                 INT frameUsedBits,
382                                                 int bufferFullness, int ncc) {
383   TRANSPORTENC_ERROR err = TRANSPORTENC_OK;
384 
385   if (!hTp) {
386     return TRANSPORTENC_INVALID_PARAMETER;
387   }
388   HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;
389 
390   /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
391   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
392     frameUsedBits += transportEnc_GetPCEBits(
393         hTp->config.channelMode, hTp->config.matrixMixdownA,
394         3); /* Consider 3 bits ID signalling in alignment */
395   }
396 
397   switch (hTp->transportFmt) {
398     case TT_MP4_ADIF:
399       FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
400                        BS_WRITER);
401       if (0 != adifWrite_EncodeHeader(&hTp->writer.adif, hBs, bufferFullness)) {
402         err = TRANSPORTENC_INVALID_CONFIG;
403       }
404       break;
405     case TT_MP4_ADTS:
406       bufferFullness /= ncc; /* Number of Considered Channels */
407       bufferFullness /= 32;
408       bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
409       adtsWrite_EncodeHeader(&hTp->writer.adts, &hTp->bitStream, bufferFullness,
410                              frameUsedBits);
411       break;
412     case TT_MP4_LOAS:
413     case TT_MP4_LATM_MCP0:
414     case TT_MP4_LATM_MCP1:
415       bufferFullness /= ncc; /* Number of Considered Channels */
416       bufferFullness /= 32;
417       bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
418       transportEnc_LatmWrite(&hTp->writer.latm, hBs, frameUsedBits,
419                              bufferFullness, &hTp->callbacks);
420       break;
421     case TT_MP4_RAW:
422       if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
423         hTp->writer.raw.curSubFrame = 0;
424         FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0,
425                          BS_WRITER);
426       }
427       hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
428       break;
429     default:
430       err = TRANSPORTENC_UNSUPPORTED_FORMAT;
431       break;
432   }
433 
434   /* Write PCE in raw_data_block if required */
435   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
436     INT crcIndex = 0;
437     /* Align inside PCE with repsect to the first bit of the raw_data_block() */
438     UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);
439 
440     /* Write PCE element ID bits */
441     FDKwriteBits(&hTp->bitStream, ID_PCE, 3);
442 
443     if ((hTp->transportFmt == TT_MP4_ADTS) &&
444         !hTp->writer.adts.protection_absent) {
445       crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
446     }
447 
448     /* Write PCE as first raw_data_block element */
449     transportEnc_writePCE(
450         &hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0,
451         1, hTp->config.matrixMixdownA,
452         (hTp->config.flags & CC_PSEUDO_SURROUND) ? 1 : 0, alignAnchor);
453 
454     if ((hTp->transportFmt == TT_MP4_ADTS) &&
455         !hTp->writer.adts.protection_absent) {
456       adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
457     }
458     hTp->pceFrameCounter = 0; /* reset pce frame counter */
459   }
460 
461   if (hTp->pceFrameCounter != -1) {
462     hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is
463                                active. */
464   }
465 
466   return err;
467 }
468 
transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,int * bits)469 TRANSPORTENC_ERROR transportEnc_EndAccessUnit(HANDLE_TRANSPORTENC hTp,
470                                               int *bits) {
471   switch (hTp->transportFmt) {
472     case TT_MP4_LATM_MCP0:
473     case TT_MP4_LATM_MCP1:
474     case TT_MP4_LOAS:
475       transportEnc_LatmAdjustSubframeBits(&hTp->writer.latm, bits);
476       break;
477     case TT_MP4_ADTS:
478       adtsWrite_EndRawDataBlock(&hTp->writer.adts, &hTp->bitStream, bits);
479       break;
480     case TT_MP4_ADIF:
481       /* Substract ADIF header from AU bits, not to be considered. */
482       *bits -= adifWrite_GetHeaderBits(&hTp->writer.adif);
483       hTp->writer.adif.headerWritten = 1;
484       break;
485     case TT_MP4_RAW:
486       *bits -= hTp->writer.raw.prevBits;
487       break;
488     default:
489       break;
490   }
491 
492   return TRANSPORTENC_OK;
493 }
494 
transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,int * nbytes)495 TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc,
496                                          int *nbytes) {
497   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
498   HANDLE_FDK_BITSTREAM hBs = &hTpEnc->bitStream;
499 
500   switch (hTpEnc->transportFmt) {
501     case TT_MP4_LATM_MCP0:
502     case TT_MP4_LATM_MCP1:
503     case TT_MP4_LOAS:
504       *nbytes = hTpEnc->bsBufferSize;
505       tpErr = transportEnc_LatmGetFrame(&hTpEnc->writer.latm, hBs, nbytes);
506       break;
507     case TT_MP4_ADTS:
508       if (hTpEnc->writer.adts.currentBlock >=
509           hTpEnc->writer.adts.num_raw_blocks + 1) {
510         *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
511         hTpEnc->writer.adts.currentBlock = 0;
512       } else {
513         *nbytes = 0;
514       }
515       break;
516     case TT_MP4_ADIF:
517       FDK_ASSERT((INT)FDKgetValidBits(hBs) >= 0);
518       *nbytes = (FDKgetValidBits(hBs) + 7) >> 3;
519       break;
520     case TT_MP4_RAW:
521       FDKsyncCache(hBs);
522       hTpEnc->writer.raw.curSubFrame++;
523       *nbytes = ((FDKgetValidBits(hBs) - hTpEnc->writer.raw.prevBits) + 7) >> 3;
524       break;
525     default:
526       break;
527   }
528 
529   return tpErr;
530 }
531 
transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp,int auBits)532 INT transportEnc_GetStaticBits(HANDLE_TRANSPORTENC hTp, int auBits) {
533   INT nbits = 0, nPceBits = 0;
534 
535   /* Write PCE within raw_data_block in transport lib. */
536   if (hTp->pceFrameCounter >= hTp->config.headerPeriod) {
537     nPceBits = transportEnc_GetPCEBits(
538         hTp->config.channelMode, hTp->config.matrixMixdownA,
539         3);             /* Consider 3 bits ID signalling in alignment */
540     auBits += nPceBits; /* Adapt required raw_data_block bit consumtpion for AU
541                            length information e.g. in LATM/LOAS configuration.
542                          */
543   }
544 
545   switch (hTp->transportFmt) {
546     case TT_MP4_ADIF:
547     case TT_MP4_RAW:
548       nbits = 0; /* Do not consider the ADIF header into the total bitrate */
549       break;
550     case TT_MP4_ADTS:
551       nbits = adtsWrite_GetHeaderBits(&hTp->writer.adts);
552       break;
553     case TT_MP4_LOAS:
554     case TT_MP4_LATM_MCP0:
555     case TT_MP4_LATM_MCP1:
556       nbits =
557           transportEnc_LatmCountTotalBitDemandHeader(&hTp->writer.latm, auBits);
558       break;
559     default:
560       nbits = 0;
561       break;
562   }
563 
564   /* PCE is written in the transport library therefore the bit consumption is
565    * part of the transport static bits. */
566   nbits += nPceBits;
567 
568   return nbits;
569 }
570 
transportEnc_Close(HANDLE_TRANSPORTENC * phTp)571 void transportEnc_Close(HANDLE_TRANSPORTENC *phTp) {
572   if (phTp != NULL) {
573     if (*phTp != NULL) {
574       FreeRam_TransportEncoder(phTp);
575     }
576   }
577 }
578 
transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc,int mBits)579 int transportEnc_CrcStartReg(HANDLE_TRANSPORTENC hTpEnc, int mBits) {
580   int crcReg = 0;
581 
582   switch (hTpEnc->transportFmt) {
583     case TT_MP4_ADTS:
584       crcReg = adtsWrite_CrcStartReg(&hTpEnc->writer.adts, &hTpEnc->bitStream,
585                                      mBits);
586       break;
587     default:
588       break;
589   }
590 
591   return crcReg;
592 }
593 
transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc,int reg)594 void transportEnc_CrcEndReg(HANDLE_TRANSPORTENC hTpEnc, int reg) {
595   switch (hTpEnc->transportFmt) {
596     case TT_MP4_ADTS:
597       adtsWrite_CrcEndReg(&hTpEnc->writer.adts, &hTpEnc->bitStream, reg);
598       break;
599     default:
600       break;
601   }
602 }
603 
transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,CODER_CONFIG * cc,FDK_BITSTREAM * dataBuffer,UINT * confType)604 TRANSPORTENC_ERROR transportEnc_GetConf(HANDLE_TRANSPORTENC hTpEnc,
605                                         CODER_CONFIG *cc,
606                                         FDK_BITSTREAM *dataBuffer,
607                                         UINT *confType) {
608   TRANSPORTENC_ERROR tpErr = TRANSPORTENC_OK;
609   HANDLE_LATM_STREAM hLatmConfig = &hTpEnc->writer.latm;
610 
611   *confType = 0; /* set confType variable to default */
612 
613   /* write StreamMuxConfig or AudioSpecificConfig depending on format used */
614   switch (hTpEnc->transportFmt) {
615     case TT_MP4_LATM_MCP0:
616     case TT_MP4_LATM_MCP1:
617     case TT_MP4_LOAS:
618       tpErr =
619           CreateStreamMuxConfig(hLatmConfig, dataBuffer, 0, &hTpEnc->callbacks);
620       *confType = 1; /* config is SMC */
621       break;
622     default:
623       if (transportEnc_writeASC(dataBuffer, cc, &hTpEnc->callbacks) != 0) {
624         tpErr = TRANSPORTENC_UNKOWN_ERROR;
625       }
626   }
627 
628   return tpErr;
629 }
630 
transportEnc_GetLibInfo(LIB_INFO * info)631 TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) {
632   int i;
633 
634   if (info == NULL) {
635     return TRANSPORTENC_INVALID_PARAMETER;
636   }
637   /* search for next free tab */
638   for (i = 0; i < FDK_MODULE_LAST; i++) {
639     if (info[i].module_id == FDK_NONE) break;
640   }
641   if (i == FDK_MODULE_LAST) {
642     return TRANSPORTENC_UNKOWN_ERROR;
643   }
644   info += i;
645 
646   info->module_id = FDK_TPENC;
647   info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2);
648   LIB_VERSION_STRING(info);
649 #ifdef __ANDROID__
650   info->build_date = "";
651   info->build_time = "";
652 #else
653   info->build_date = __DATE__;
654   info->build_time = __TIME__;
655 #endif
656   info->title = TP_LIB_TITLE;
657 
658   /* Set flags */
659   info->flags =
660       0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | CAPF_RAWPACKETS;
661 
662   return TRANSPORTENC_OK;
663 }
664