1 2/* ----------------------------------------------------------------------------------------------------------- 3Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5� Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16of the MPEG specifications. 17 18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20individually for the purpose of encoding or decoding bit streams in products that are compliant with 21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27applications information and documentation. 28 292. COPYRIGHT LICENSE 30 31Redistribution and use in source and binary forms, with or without modification, are permitted without 32payment of copyright license fees provided that you satisfy the following conditions: 33 34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35your modifications thereto in source code form. 36 37You must retain the complete text of this software license in the documentation and/or other materials 38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40modifications thereto to recipients of copies in binary form. 41 42The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43prior written permission. 44 45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46software or your modifications thereto. 47 48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49and the date of any change. For modified versions of the FDK AAC Codec, the term 50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 533. NO PATENT LICENSE 54 55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57respect to this software. 58 59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60by appropriate patent licenses. 61 624. DISCLAIMER 63 64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69or business interruption, however caused and on any theory of liability, whether in contract, strict 70liability, or tort (including negligence), arising in any way out of the use of this software, even if 71advised of the possibility of such damage. 72 735. CONTACT INFORMATION 74 75Fraunhofer Institute for Integrated Circuits IIS 76Attention: Audio and Multimedia Departments - FDK AAC LL 77Am Wolfsmantel 33 7891058 Erlangen, Germany 79 80www.iis.fraunhofer.de/amm 81amm-info@iis.fraunhofer.de 82----------------------------------------------------------------------------------------------------------- */ 83 84/***************************** MPEG-4 AAC Encoder ************************** 85 86 Author(s): 87 Description: 88 89******************************************************************************/ 90 91#include "tpenc_latm.h" 92 93 94#include "genericStds.h" 95 96static const short celpFrameLengthTable[64] = { 97 154, 170, 186, 147, 156, 165, 114, 120, 98 186, 126, 132, 138, 142, 146, 154, 166, 99 174, 182, 190, 198, 206, 210, 214, 110, 100 114, 118, 120, 122, 218, 230, 242, 254, 101 266, 278, 286, 294, 318, 342, 358, 374, 102 390, 406, 422, 136, 142, 148, 154, 160, 103 166, 170, 174, 186, 198, 206, 214, 222, 104 230, 238, 216, 160, 280, 338, 0, 0 105}; 106 107/******* 108 write value to transport stream 109 first two bits define the size of the value itself 110 then the value itself, with a size of 0-3 bytes 111*******/ 112static 113UINT transportEnc_LatmWriteValue(HANDLE_FDK_BITSTREAM hBs, int value) 114{ 115 UCHAR valueBytes = 4; 116 unsigned int bitsWritten = 0; 117 int i; 118 119 if ( value < (1<<8) ) { 120 valueBytes = 1; 121 } else if ( value < (1<<16) ) { 122 valueBytes = 2; 123 } else if ( value < (1<<24) ) { 124 valueBytes = 3; 125 } else { 126 valueBytes = 4; 127 } 128 129 FDKwriteBits(hBs, valueBytes-1, 2 ); /* size of value in Bytes */ 130 for (i=0; i<valueBytes; i++) { 131 /* write most significant Byte first */ 132 FDKwriteBits(hBs, (UCHAR)(value>>((valueBytes-1-i)<<3)), 8); 133 } 134 135 bitsWritten = (valueBytes<<3)+2; 136 137 return bitsWritten; 138} 139 140static 141UINT transportEnc_LatmCountFixBitDemandHeader ( HANDLE_LATM_STREAM hAss ) 142{ 143 int bitDemand = 0; 144 int insertSetupData = 0 ; 145 146 /* only if start of new latm frame */ 147 if (hAss->subFrameCnt==0) 148 { 149 /* AudioSyncStream */ 150 151 if (hAss->tt == TT_MP4_LOAS) { 152 bitDemand += 11 ; /* syncword */ 153 bitDemand += 13 ; /* audioMuxLengthBytes */ 154 } 155 156 /* AudioMuxElement*/ 157 158 /* AudioMuxElement::Stream Mux Config */ 159 if (hAss->muxConfigPeriod > 0) { 160 insertSetupData = (hAss->latmFrameCounter == 0); 161 } else { 162 insertSetupData = 0; 163 } 164 165 if (hAss->tt != TT_MP4_LATM_MCP0) { 166 /* AudioMuxElement::useSameStreamMux Flag */ 167 bitDemand+=1; 168 169 if( insertSetupData ) { 170 bitDemand += hAss->streamMuxConfigBits; 171 } 172 } 173 174 /* AudioMuxElement::otherDataBits */ 175 bitDemand += 8*hAss->otherDataLenBytes; 176 177 /* AudioMuxElement::ByteAlign */ 178 if ( bitDemand % 8 ) { 179 hAss->fillBits = 8 - (bitDemand % 8); 180 bitDemand += hAss->fillBits ; 181 } else { 182 hAss->fillBits = 0; 183 } 184 } 185 186 return bitDemand ; 187} 188 189static 190UINT transportEnc_LatmCountVarBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength ) 191{ 192 int bitDemand = 0; 193 int prog, layer; 194 195 /* Payload Length Info*/ 196 if( hAss->allStreamsSameTimeFraming ) { 197 for( prog=0; prog<hAss->noProgram; prog++ ) { 198 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) { 199 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]); 200 201 if( p_linfo->streamID >= 0 ) { 202 switch( p_linfo->frameLengthType ) { 203 case 0: 204 if ( streamDataLength > 0 ) { 205 streamDataLength -= bitDemand ; 206 while( streamDataLength >= (255<<3) ) { 207 bitDemand+=8; 208 streamDataLength -= (255<<3); 209 } 210 bitDemand += 8; 211 } 212 break; 213 214 case 1: 215 case 4: 216 case 6: 217 bitDemand += 2; 218 break; 219 220 default: 221 return 0; 222 } 223 } 224 } 225 } 226 } else { 227 /* there are many possibilities to use this mechanism. */ 228 switch( hAss->varMode ) { 229 case LATMVAR_SIMPLE_SEQUENCE: { 230 /* Use the sequence generated by the encoder */ 231 //int streamCntPosition = transportEnc_SetWritePointer( hAss->hAssemble, 0 ); 232 //int streamCntPosition = FDKgetValidBits( hAss->hAssemble ); 233 bitDemand+=4; 234 235 hAss->varStreamCnt = 0; 236 for( prog=0; prog<hAss->noProgram; prog++ ) { 237 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) { 238 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]); 239 240 if( p_linfo->streamID >= 0 ) { 241 242 bitDemand+=4; /* streamID */ 243 switch( p_linfo->frameLengthType ) { 244 case 0: 245 streamDataLength -= bitDemand ; 246 while( streamDataLength >= (255<<3) ) { 247 bitDemand+=8; 248 streamDataLength -= (255<<3); 249 } 250 251 bitDemand += 8; 252 break; 253 /*bitDemand += 1; endFlag 254 break;*/ 255 256 case 1: 257 case 4: 258 case 6: 259 260 break; 261 262 default: 263 return 0; 264 } 265 hAss->varStreamCnt++; 266 } 267 } 268 } 269 bitDemand+=4; 270 //transportEnc_UpdateBitstreamField( hAss->hAssemble, streamCntPosition, hAss->varStreamCnt-1, 4 ); 271 //UINT pos = streamCntPosition-FDKgetValidBits(hAss->hAssemble); 272 //FDKpushBack( hAss->hAssemble, pos); 273 //FDKwriteBits( hAss->hAssemble, hAss->varStreamCnt-1, 4); 274 //FDKpushFor( hAss->hAssemble, pos-4); 275 } 276 break; 277 278 default: 279 return 0; 280 } 281 } 282 283 return bitDemand ; 284} 285 286TRANSPORTENC_ERROR 287CreateStreamMuxConfig( 288 HANDLE_LATM_STREAM hAss, 289 HANDLE_FDK_BITSTREAM hBs, 290 int bufferFullness, 291 CSTpCallBacks *cb 292 ) 293{ 294 INT streamIDcnt, tmp; 295 int layer, prog; 296 297 USHORT coreFrameOffset=0; 298 299 hAss->audioMuxVersionA = 0; /* for future extensions */ 300 hAss->streamMuxConfigBits = 0; 301 302 FDKwriteBits( hBs, hAss->audioMuxVersion, 1 ); /* audioMuxVersion */ 303 hAss->streamMuxConfigBits += 1; 304 305 if ( hAss->audioMuxVersion == 1 ) { 306 FDKwriteBits( hBs, hAss->audioMuxVersionA, 1 ); /* audioMuxVersionA */ 307 hAss->streamMuxConfigBits+=1; 308 } 309 310 if ( hAss->audioMuxVersionA == 0 ) 311 { 312 if ( hAss->audioMuxVersion == 1 ) { 313 hAss->streamMuxConfigBits+= transportEnc_LatmWriteValue( hBs, hAss->taraBufferFullness );/* taraBufferFullness */ 314 } 315 FDKwriteBits( hBs, hAss->allStreamsSameTimeFraming ? 1:0, 1 ); /* allStreamsSameTimeFraming */ 316 FDKwriteBits( hBs, hAss->noSubframes-1, 6 ); /* Number of Subframes */ 317 FDKwriteBits( hBs, hAss->noProgram-1, 4 ); /* Number of Programs */ 318 319 hAss->streamMuxConfigBits+=11; 320 321 streamIDcnt = 0; 322 for( prog=0; prog<hAss->noProgram; prog++ ) { 323 int transLayer = 0; 324 325 FDKwriteBits( hBs, hAss->noLayer[prog]-1, 3 ); 326 hAss->streamMuxConfigBits+=3; 327 328 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) { 329 LATM_LAYER_INFO *p_linfo = &(hAss->m_linfo[prog][layer]); 330 CODER_CONFIG *p_lci = hAss->config[prog][layer]; 331 332 p_linfo->streamID = -1; 333 334 if( hAss->config[prog][layer] != NULL ) { 335 int useSameConfig = 0; 336 337 if( transLayer > 0 ) { 338 FDKwriteBits( hBs, useSameConfig ? 1 : 0, 1 ); 339 hAss->streamMuxConfigBits+=1; 340 } 341 if( (useSameConfig == 0) || (transLayer==0) ) { 342 UINT bits; 343 344 if ( hAss->audioMuxVersion == 1 ) { 345 FDKpushFor(hBs, 2); /* align to ASC, even if we do not know the length of the "ascLen" field yet */ 346 } 347 348 bits = FDKgetValidBits( hBs ); 349 350 transportEnc_writeASC( 351 hBs, 352 hAss->config[prog][layer], 353 cb 354 ); 355 356 bits = FDKgetValidBits( hBs ) - bits; 357 358 if ( hAss->audioMuxVersion == 1 ) { 359 FDKpushBack(hBs, bits+2); 360 hAss->streamMuxConfigBits += transportEnc_LatmWriteValue( hBs, bits ); 361 transportEnc_writeASC( 362 hBs, 363 hAss->config[prog][layer], 364 cb 365 ); 366 } 367 368 hAss->streamMuxConfigBits += bits; /* add asc length to smc summary */ 369 } 370 transLayer++; 371 372 if( !hAss->allStreamsSameTimeFraming ) { 373 if( streamIDcnt >= LATM_MAX_STREAM_ID ) 374 return TRANSPORTENC_INVALID_CONFIG; 375 } 376 p_linfo->streamID = streamIDcnt++; 377 378 switch( p_lci->aot ) { 379 case AOT_AAC_MAIN : 380 case AOT_AAC_LC : 381 case AOT_AAC_SSR : 382 case AOT_AAC_LTP : 383 case AOT_AAC_SCAL : 384 case AOT_ER_AAC_LD : 385 case AOT_ER_AAC_ELD : 386 case AOT_USAC: 387 case AOT_RSVD50: 388 p_linfo->frameLengthType = 0; 389 390 FDKwriteBits( hBs, p_linfo->frameLengthType, 3 ); /* frameLengthType */ 391 FDKwriteBits( hBs, bufferFullness, 8 ); /* bufferFullness */ 392 hAss->streamMuxConfigBits+=11; 393 394 if ( !hAss->allStreamsSameTimeFraming ) { 395 CODER_CONFIG *p_lci_prev = hAss->config[prog][layer-1]; 396 if ( ((p_lci->aot == AOT_AAC_SCAL) || (p_lci->aot == AOT_ER_AAC_SCAL)) && 397 ((p_lci_prev->aot == AOT_CELP) || (p_lci_prev->aot == AOT_ER_CELP)) ) { 398 FDKwriteBits( hBs, coreFrameOffset, 6 ); /* coreFrameOffset */ 399 hAss->streamMuxConfigBits+=6; 400 } 401 } 402 break; 403 404 case AOT_TWIN_VQ: 405 p_linfo->frameLengthType = 1; 406 tmp = ( (p_lci->bitsFrame+7) >> 3 ) - 20; /* transmission frame length in bytes */ 407 if( (tmp < 0) ) { 408 return TRANSPORTENC_INVALID_TRANSMISSION_FRAME_LENGTH; 409 } 410 FDKwriteBits( hBs, p_linfo->frameLengthType, 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, 3 ); /* frameLengthType */ 420 hAss->streamMuxConfigBits+=3; 421 { 422 int i; 423 for( i=0; i<62; i++ ) { 424 if( celpFrameLengthTable[i] == p_lci->bitsFrame ) 425 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, 3 ); /* frameLengthType */ 440 hAss->streamMuxConfigBits+=3; 441 { 442 int i; 443 444 if( p_lci->bitsFrame == 40 ) { 445 i = 0; 446 } else if( p_lci->bitsFrame == 80 ) { 447 i = 1; 448 } else { 449 return TRANSPORTENC_INVALID_FRAME_BITS; 450 } 451 FDKwriteBits( hBs, i, 1 ); /* HVXCframeLengthTableIndex */ 452 hAss->streamMuxConfigBits+=1; 453 } 454 p_linfo->frameLengthBits = p_lci->bitsFrame; 455 break; 456 457 case AOT_NULL_OBJECT: 458 default: 459 return TRANSPORTENC_INVALID_AOT; 460 } 461 } 462 } 463 } 464 465 FDKwriteBits( hBs, (hAss->otherDataLenBytes>0) ? 1:0, 1 ); /* otherDataPresent */ 466 hAss->streamMuxConfigBits+=1; 467 468 if( hAss->otherDataLenBytes > 0 ) { 469 470 INT otherDataLenTmp = hAss->otherDataLenBytes; 471 INT escCnt = 0; 472 INT otherDataLenEsc = 1; 473 474 while(otherDataLenTmp) { 475 otherDataLenTmp >>= 8; 476 escCnt ++; 477 } 478 479 do { 480 otherDataLenTmp = (hAss->otherDataLenBytes>>(escCnt*8)) & 0xFF; 481 escCnt--; 482 otherDataLenEsc = escCnt>0; 483 484 FDKwriteBits( hBs, otherDataLenEsc, 1 ); 485 FDKwriteBits( hBs, otherDataLenTmp, 8 ); 486 hAss->streamMuxConfigBits+=9; 487 } while(otherDataLenEsc); 488 } 489 490 { 491 USHORT crcCheckPresent=0; 492 USHORT crcCheckSum=0; 493 494 FDKwriteBits( hBs, crcCheckPresent, 1 ); /* crcCheckPresent */ 495 hAss->streamMuxConfigBits+=1; 496 if ( crcCheckPresent ){ 497 FDKwriteBits( hBs, crcCheckSum, 8 ); /* crcCheckSum */ 498 hAss->streamMuxConfigBits+=8; 499 } 500 } 501 502 } else { /* if ( audioMuxVersionA == 0 ) */ 503 504 /* for future extensions */ 505 506 } 507 508 return TRANSPORTENC_OK; 509} 510 511 512static TRANSPORTENC_ERROR 513WriteAuPayloadLengthInfo( HANDLE_FDK_BITSTREAM hBitStream, int AuLengthBits ) 514{ 515 int restBytes; 516 517 if( AuLengthBits % 8 ) 518 return TRANSPORTENC_INVALID_AU_LENGTH; 519 520 while( AuLengthBits >= 255*8 ) { 521 FDKwriteBits( hBitStream, 255, 8 ); /* 255 shows incomplete AU */ 522 AuLengthBits -= (255*8); 523 } 524 525 restBytes = (AuLengthBits) >> 3; 526 FDKwriteBits( hBitStream, restBytes, 8 ); 527 528 return TRANSPORTENC_OK; 529} 530 531static 532TRANSPORTENC_ERROR transportEnc_LatmSetNrOfSubframes( HANDLE_LATM_STREAM hAss, 533 INT noSubframes_next) /* nr of access units / payloads within a latm frame */ 534{ 535 /* sanity chk */ 536 if (noSubframes_next < 1 || noSubframes_next > MAX_NR_OF_SUBFRAMES) { 537 return TRANSPORTENC_LATM_INVALID_NR_OF_SUBFRAMES; 538 } 539 540 hAss->noSubframes_next = noSubframes_next; 541 542 /* if at start then we can take over the value immediately, otherwise we have to wait for the next SMC */ 543 if ( (hAss->subFrameCnt == 0) && (hAss->latmFrameCounter == 0) ) { 544 hAss->noSubframes = noSubframes_next; 545 } 546 547 return TRANSPORTENC_OK; 548} 549 550static 551int allStreamsSameTimeFraming( HANDLE_LATM_STREAM hAss, UCHAR noProgram, UCHAR noLayer[] /* return */ ) 552{ 553 int prog, layer; 554 555 signed int lastNoSamples = -1; 556 signed int minFrameSamples = FDK_INT_MAX; 557 signed int maxFrameSamples = 0; 558 559 signed int highestSamplingRate = -1; 560 561 for( prog=0; prog<noProgram; prog++ ) { 562 noLayer[prog] = 0; 563 564 for( layer=0; layer<LATM_MAX_LAYERS; layer++ ) 565 { 566 if( hAss->config[prog][layer] != NULL ) 567 { 568 INT hsfSamplesFrame; 569 570 noLayer[prog]++; 571 572 if( highestSamplingRate < 0 ) 573 highestSamplingRate = hAss->config[prog][layer]->samplingRate; 574 575 hsfSamplesFrame = hAss->config[prog][layer]->samplesPerFrame * highestSamplingRate / hAss->config[prog][layer]->samplingRate; 576 577 if( hsfSamplesFrame <= minFrameSamples ) minFrameSamples = hsfSamplesFrame; 578 if( hsfSamplesFrame >= maxFrameSamples ) maxFrameSamples = hsfSamplesFrame; 579 580 if( lastNoSamples == -1 ) { 581 lastNoSamples = hsfSamplesFrame; 582 } else { 583 if( hsfSamplesFrame != lastNoSamples ) { 584 return 0; 585 } 586 } 587 } 588 } 589 } 590 591 return 1; 592} 593 594/** 595 * Initialize LATM/LOAS Stream and add layer 0 at program 0. 596 */ 597static 598TRANSPORTENC_ERROR transportEnc_InitLatmStream( HANDLE_LATM_STREAM hAss, 599 int fractDelayPresent, 600 signed int muxConfigPeriod, /* insert setup data every muxConfigPeriod frames */ 601 UINT audioMuxVersion, 602 TRANSPORT_TYPE tt 603 ) 604{ 605 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK; 606 607 if (hAss == NULL) 608 return TRANSPORTENC_INVALID_PARAMETER; 609 610 hAss->tt = tt; 611 612 hAss->noProgram = 1; 613 614 hAss->audioMuxVersion = audioMuxVersion; 615 616 /* Fill noLayer array using hAss->config */ 617 hAss->allStreamsSameTimeFraming = allStreamsSameTimeFraming( hAss, hAss->noProgram, hAss->noLayer ); 618 /* Only allStreamsSameTimeFraming==1 is supported */ 619 FDK_ASSERT(hAss->allStreamsSameTimeFraming); 620 621 hAss->fractDelayPresent = fractDelayPresent; 622 hAss->otherDataLenBytes = 0; 623 624 hAss->varMode = LATMVAR_SIMPLE_SEQUENCE; 625 626 /* initialize counters */ 627 hAss->subFrameCnt = 0; 628 hAss->noSubframes = DEFAULT_LATM_NR_OF_SUBFRAMES; 629 hAss->noSubframes_next = DEFAULT_LATM_NR_OF_SUBFRAMES; 630 631 /* sync layer related */ 632 hAss->audioMuxLengthBytes = 0; 633 634 hAss->latmFrameCounter = 0; 635 hAss->muxConfigPeriod = muxConfigPeriod; 636 637 return ErrorStatus; 638} 639 640 641/** 642 * 643 */ 644UINT transportEnc_LatmCountTotalBitDemandHeader ( HANDLE_LATM_STREAM hAss , unsigned int streamDataLength ) 645{ 646 UINT bitDemand = 0; 647 648 switch (hAss->tt) { 649 case TT_MP4_LOAS: 650 case TT_MP4_LATM_MCP0: 651 case TT_MP4_LATM_MCP1: 652 if (hAss->subFrameCnt == 0) { 653 bitDemand = transportEnc_LatmCountFixBitDemandHeader ( hAss ); 654 } 655 bitDemand += transportEnc_LatmCountVarBitDemandHeader ( hAss , streamDataLength /*- bitDemand*/); 656 break; 657 default: 658 break; 659 } 660 661 return bitDemand; 662} 663 664static TRANSPORTENC_ERROR 665AdvanceAudioMuxElement ( 666 HANDLE_LATM_STREAM hAss, 667 HANDLE_FDK_BITSTREAM hBs, 668 int auBits, 669 int bufferFullness, 670 CSTpCallBacks *cb 671 ) 672{ 673 TRANSPORTENC_ERROR ErrorStatus = TRANSPORTENC_OK; 674 int insertMuxSetup; 675 676 /* Insert setup data to assemble Buffer */ 677 if (hAss->subFrameCnt == 0) 678 { 679 if (hAss->muxConfigPeriod > 0) { 680 insertMuxSetup = (hAss->latmFrameCounter == 0); 681 } else { 682 insertMuxSetup = 0; 683 } 684 685 if (hAss->tt != TT_MP4_LATM_MCP0) { 686 if( insertMuxSetup ) { 687 FDKwriteBits( hBs, 0, 1 ); /* useSameStreamMux useNewStreamMux */ 688 CreateStreamMuxConfig(hAss, hBs, bufferFullness, cb); 689 if (ErrorStatus != TRANSPORTENC_OK) 690 return ErrorStatus; 691 } else { 692 FDKwriteBits( hBs, 1, 1 ); /* useSameStreamMux */ 693 } 694 } 695 } 696 697 /* PayloadLengthInfo */ 698 { 699 int prog, layer; 700 701 for (prog = 0; prog < hAss->noProgram; prog++) { 702 for (layer = 0; layer < hAss->noLayer[prog]; layer++) { 703 ErrorStatus = WriteAuPayloadLengthInfo( hBs, auBits ); 704 if (ErrorStatus != TRANSPORTENC_OK) 705 return ErrorStatus; 706 } 707 } 708 } 709 /* At this point comes the access unit. */ 710 711 return TRANSPORTENC_OK; 712} 713 714TRANSPORTENC_ERROR 715transportEnc_LatmWrite ( 716 HANDLE_LATM_STREAM hAss, 717 HANDLE_FDK_BITSTREAM hBs, 718 int auBits, 719 int bufferFullness, 720 CSTpCallBacks *cb 721 ) 722{ 723 TRANSPORTENC_ERROR ErrorStatus; 724 725 if (hAss->subFrameCnt == 0) { 726 /* Start new frame */ 727 FDKresetBitbuffer(hBs, BS_WRITER); 728 } 729 730 hAss->latmSubframeStart = FDKgetValidBits(hBs); 731 732 /* Insert syncword and syncword distance 733 - only if loas 734 - we must update the syncword distance (=audiomuxlengthbytes) later 735 */ 736 if( hAss->tt == TT_MP4_LOAS && hAss->subFrameCnt == 0) 737 { 738 /* Start new LOAS frame */ 739 FDKwriteBits( hBs, 0x2B7, 11 ); 740 hAss->audioMuxLengthBytes = 0; 741 hAss->audioMuxLengthBytesPos = FDKgetValidBits( hBs ); /* store read pointer position */ 742 FDKwriteBits( hBs, hAss->audioMuxLengthBytes, 13 ); 743 } 744 745 ErrorStatus = AdvanceAudioMuxElement( 746 hAss, 747 hBs, 748 auBits, 749 bufferFullness, 750 cb 751 ); 752 753 if (ErrorStatus != TRANSPORTENC_OK) 754 return ErrorStatus; 755 756 return ErrorStatus; 757} 758 759void transportEnc_LatmAdjustSubframeBits(HANDLE_LATM_STREAM hAss, 760 int *bits) 761{ 762 /* Substract bits from possible previous subframe */ 763 *bits -= hAss->latmSubframeStart; 764 /* Add fill bits */ 765 if (hAss->subFrameCnt == 0) 766 *bits += hAss->fillBits; 767} 768 769 770void transportEnc_LatmGetFrame(HANDLE_LATM_STREAM hAss, 771 HANDLE_FDK_BITSTREAM hBs, 772 int *bytes) 773{ 774 775 hAss->subFrameCnt++; 776 if (hAss->subFrameCnt >= hAss->noSubframes) 777 { 778 779 /* Add LOAS frame length if required. */ 780 if (hAss->tt == TT_MP4_LOAS) 781 { 782 int latmBytes; 783 784 latmBytes = (FDKgetValidBits(hBs)+7) >> 3; 785 786 /* write length info into assembler buffer */ 787 hAss->audioMuxLengthBytes = latmBytes - 3; /* 3=Syncword + length */ 788 { 789 FDK_BITSTREAM tmpBuf; 790 791 FDKinitBitStream( &tmpBuf, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER ) ; 792 FDKpushFor( &tmpBuf, hAss->audioMuxLengthBytesPos ); 793 FDKwriteBits( &tmpBuf, hAss->audioMuxLengthBytes, 13 ); 794 FDKsyncCache( &tmpBuf ); 795 } 796 } 797 798 /* Write AudioMuxElement byte alignment fill bits */ 799 FDKwriteBits(hBs, 0, hAss->fillBits); 800 801 FDK_ASSERT( (FDKgetValidBits(hBs) % 8) == 0); 802 803 hAss->subFrameCnt = 0; 804 805 FDKsyncCache(hBs); 806 *bytes = (FDKgetValidBits(hBs) + 7)>>3; 807 //FDKfetchBuffer(hBs, buffer, (UINT*)bytes); 808 809 if (hAss->muxConfigPeriod > 0) 810 { 811 hAss->latmFrameCounter++; 812 813 if (hAss->latmFrameCounter >= hAss->muxConfigPeriod) { 814 hAss->latmFrameCounter = 0; 815 hAss->noSubframes = hAss->noSubframes_next; 816 } 817 } 818 } else { 819 /* No data this time */ 820 *bytes = 0; 821 } 822} 823 824/** 825 * Init LATM/LOAS 826 */ 827TRANSPORTENC_ERROR transportEnc_Latm_Init( 828 HANDLE_LATM_STREAM hAss, 829 HANDLE_FDK_BITSTREAM hBs, 830 CODER_CONFIG *layerConfig, 831 UINT audioMuxVersion, 832 TRANSPORT_TYPE tt, 833 CSTpCallBacks *cb 834 ) 835{ 836 TRANSPORTENC_ERROR ErrorStatus; 837 int fractDelayPresent = 0; 838 int prog, layer; 839 840 int setupDataDistanceFrames = layerConfig->headerPeriod; 841 842 FDK_ASSERT(setupDataDistanceFrames>=0); 843 844 for (prog=0; prog<LATM_MAX_PROGRAMS; prog++) { 845 for (layer=0; layer<LATM_MAX_LAYERS; layer++) { 846 hAss->config[prog][layer] = NULL; 847 hAss->m_linfo[prog][layer].streamID = -1; 848 } 849 } 850 851 hAss->config[0][0] = layerConfig; 852 hAss->m_linfo[0][0].streamID = 0; 853 854 ErrorStatus = transportEnc_InitLatmStream( hAss, 855 fractDelayPresent, 856 setupDataDistanceFrames, 857 (audioMuxVersion)?1:0, 858 tt 859 ); 860 if (ErrorStatus != TRANSPORTENC_OK) 861 goto bail; 862 863 ErrorStatus = transportEnc_LatmSetNrOfSubframes( 864 hAss, 865 layerConfig->nSubFrames 866 ); 867 if (ErrorStatus != TRANSPORTENC_OK) 868 goto bail; 869 870 /* Get the size of the StreamMuxConfig somehow */ 871 AdvanceAudioMuxElement(hAss, hBs, 0, 0, cb); 872 //CreateStreamMuxConfig(hAss, hBs, 0); 873 874bail: 875 return ErrorStatus; 876} 877 878 879 880 881 882 883