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