1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 *******/ 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 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 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 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 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 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 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 */ 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 */ 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 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 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 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 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 */ 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 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