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