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 decoder library ********************* 96 97 Author(s): Daniel Homm 98 99 Description: 100 101 *******************************************************************************/ 102 103 #include "tpdec_latm.h" 104 105 #include "FDK_bitstream.h" 106 107 #define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l)) 108 109 static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) { 110 UCHAR bytesForValue = 0, tmp = 0; 111 int value = 0; 112 113 bytesForValue = (UCHAR)FDKreadBits(bs, 2); 114 115 for (UINT i = 0; i <= bytesForValue; i++) { 116 value <<= 8; 117 tmp = (UCHAR)FDKreadBits(bs, 8); 118 value += tmp; 119 } 120 121 return value; 122 } 123 124 static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( 125 HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent, 126 CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, 127 int *pfConfigFound) { 128 TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; 129 130 if (m_muxConfigPresent) { 131 pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1); 132 133 if (!pLatmDemux->m_useSameStreamMux) { 134 int i; 135 UCHAR configChanged = 0; 136 UCHAR configMode = 0; 137 138 FDK_BITSTREAM bsAnchor; 139 140 FDK_BITSTREAM bsAnchorDummyParse; 141 142 if (!pLatmDemux->applyAsc) { 143 bsAnchorDummyParse = *bs; 144 pLatmDemux->newCfgHasAudioPreRoll = 0; 145 /* do dummy-parsing of ASC to determine if there is an audioPreRoll */ 146 configMode |= AC_CM_DET_CFG_CHANGE; 147 if (TRANSPORTDEC_OK != 148 (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( 149 bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, 150 configMode, configChanged))) { 151 goto bail; 152 } 153 154 /* Allow flushing only when audioPreroll functionality is enabled in 155 * current and new config otherwise the new config can be applied 156 * immediately. */ 157 if (pAsc->m_sc.m_usacConfig.element[0] 158 .extElement.usacExtElementHasAudioPreRoll && 159 pLatmDemux->newCfgHasAudioPreRoll) { 160 pLatmDemux->newCfgHasAudioPreRoll = 0; 161 /* with audioPreRoll we must flush before applying new cfg */ 162 pLatmDemux->applyAsc = 0; 163 } else { 164 *bs = bsAnchorDummyParse; 165 pLatmDemux->applyAsc = 1; /* apply new config immediate */ 166 } 167 } 168 169 if (pLatmDemux->applyAsc) { 170 for (i = 0; i < 2; i++) { 171 configMode = 0; 172 173 if (i == 0) { 174 configMode |= AC_CM_DET_CFG_CHANGE; 175 bsAnchor = *bs; 176 } else { 177 configMode |= AC_CM_ALLOC_MEM; 178 *bs = bsAnchor; 179 } 180 181 if (TRANSPORTDEC_OK != 182 (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( 183 bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, 184 configMode, configChanged))) { 185 goto bail; 186 } 187 188 if (ErrorStatus == TRANSPORTDEC_OK) { 189 if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged || 190 pAsc->SacConfigChanged)) { 191 int errC; 192 193 configChanged = 1; 194 errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData, 195 pAsc); 196 if (errC != 0) { 197 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 198 goto bail; 199 } 200 } 201 } 202 } 203 } 204 } 205 } 206 207 /* If there was no configuration read, its not possible to parse 208 * PayloadLengthInfo below. */ 209 if (!*pfConfigFound) { 210 ErrorStatus = TRANSPORTDEC_SYNC_ERROR; 211 goto bail; 212 } 213 214 if (pLatmDemux->m_AudioMuxVersionA == 0) { 215 /* Do only once per call, because parsing and decoding is done in-line. */ 216 if (TRANSPORTDEC_OK != 217 (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) { 218 *pfConfigFound = 0; 219 goto bail; 220 } 221 } else { 222 /* audioMuxVersionA > 0 is reserved for future extensions */ 223 ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; 224 *pfConfigFound = 0; 225 goto bail; 226 } 227 228 bail: 229 if (ErrorStatus != TRANSPORTDEC_OK) { 230 pLatmDemux->applyAsc = 1; 231 } 232 233 return (ErrorStatus); 234 } 235 236 TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, 237 CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, 238 CSTpCallBacks *pTpDecCallbacks, 239 CSAudioSpecificConfig *pAsc, 240 int *pfConfigFound, 241 const INT ignoreBufferFullness) { 242 UINT cntBits; 243 UINT cmpBufferFullness; 244 UINT audioMuxLengthBytesLast = 0; 245 TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; 246 247 cntBits = FDKgetValidBits(bs); 248 249 if ((INT)cntBits < MIN_LATM_HEADERLENGTH) { 250 return TRANSPORTDEC_NOT_ENOUGH_BITS; 251 } 252 253 if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement( 254 bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0), 255 pTpDecCallbacks, pAsc, pfConfigFound))) 256 return (ErrorStatus); 257 258 if (!ignoreBufferFullness) { 259 cmpBufferFullness = 260 24 + audioMuxLengthBytesLast * 8 + 261 pLatmDemux->m_linfo[0][0].m_bufferFullness * 262 pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32; 263 264 /* evaluate buffer fullness */ 265 266 if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) { 267 if (!pLatmDemux->BufferFullnessAchieved) { 268 if (cntBits < cmpBufferFullness) { 269 /* condition for start of decoding is not fulfilled */ 270 271 /* the current frame will not be decoded */ 272 return TRANSPORTDEC_NOT_ENOUGH_BITS; 273 } else { 274 pLatmDemux->BufferFullnessAchieved = 1; 275 } 276 } 277 } 278 } 279 280 return (ErrorStatus); 281 } 282 283 TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig( 284 HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, 285 CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, 286 int *pfConfigFound, UCHAR configMode, UCHAR configChanged) { 287 CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing, 288 after that new config can be parsed */ 289 CSAudioSpecificConfig *pAscDummy; 290 pAscDummy = &ascDummy; 291 pLatmDemux->usacExplicitCfgChanged = 0; 292 LATM_LAYER_INFO *p_linfo = NULL; 293 TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; 294 UCHAR updateConfig[1 * 1] = {0}; 295 296 pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1); 297 298 if (pLatmDemux->m_AudioMuxVersion == 0) { 299 pLatmDemux->m_AudioMuxVersionA = 0; 300 } else { 301 pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1); 302 } 303 304 if (pLatmDemux->m_AudioMuxVersionA == 0) { 305 if (pLatmDemux->m_AudioMuxVersion == 1) { 306 pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs); 307 } 308 pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1); 309 pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1; 310 pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1; 311 312 if (pLatmDemux->m_numProgram > LATM_MAX_PROG) { 313 ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; 314 goto bail; 315 } 316 317 int idCnt = 0; 318 for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { 319 pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1; 320 if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) { 321 ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; 322 goto bail; 323 } 324 325 for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { 326 int useSameConfig; 327 p_linfo = &pLatmDemux->m_linfo[prog][lay]; 328 329 p_linfo->m_streamID = idCnt++; 330 p_linfo->m_frameLengthInBits = 0; 331 332 if ((prog == 0) && (lay == 0)) { 333 useSameConfig = 0; 334 } else { 335 useSameConfig = FDKreadBits(bs, 1); 336 } 337 338 if (useSameConfig) { 339 if (lay > 0) { 340 FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)], 341 &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)], 342 sizeof(CSAudioSpecificConfig)); 343 } else { 344 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 345 goto bail; 346 } 347 } else { 348 UINT usacConfigLengthPrev = 0; 349 UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN]; 350 351 if (!(pLatmDemux->applyAsc) && 352 (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) { 353 usacConfigLengthPrev = 354 (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)] 355 .m_sc.m_usacConfig.UsacConfigBits + 356 7) >> 357 3; /* store previous USAC config length */ 358 if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) { 359 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 360 goto bail; 361 } 362 FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN); 363 FDKmemcpy( 364 usacConfigPrev, 365 &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig, 366 usacConfigLengthPrev); /* store previous USAC config */ 367 } 368 if (pLatmDemux->m_AudioMuxVersion == 1) { 369 FDK_BITSTREAM tmpBs; 370 UINT ascLen = 0; 371 ascLen = CLatmDemux_GetValue(bs); 372 /* The ascLen could be wrong, so check if validBits<=bufBits*/ 373 if (ascLen > FDKgetValidBits(bs)) { 374 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 375 goto bail; 376 } 377 FDKsyncCache(bs); 378 tmpBs = *bs; 379 tmpBs.hBitBuf.ValidBits = ascLen; 380 381 /* Read ASC */ 382 if (pLatmDemux->applyAsc) { 383 if (TRANSPORTDEC_OK != 384 (ErrorStatus = AudioSpecificConfig_Parse( 385 &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1, 386 pTpDecCallbacks, configMode, configChanged, 387 AOT_NULL_OBJECT))) 388 goto bail; 389 } else { 390 if (TRANSPORTDEC_OK != 391 (ErrorStatus = AudioSpecificConfig_Parse( 392 pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode, 393 configChanged, AOT_NULL_OBJECT))) 394 goto bail; 395 } 396 397 /* The field p_linfo->m_ascLen could be wrong, so check if */ 398 if (0 > (INT)FDKgetValidBits(&tmpBs)) { 399 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 400 goto bail; 401 } 402 FDKpushFor(bs, ascLen); /* position bitstream after ASC */ 403 } else { 404 /* Read ASC */ 405 if (pLatmDemux->applyAsc) { 406 if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse( 407 &pAsc[TPDEC_TRACKINDEX(prog, lay)], 408 bs, 0, pTpDecCallbacks, configMode, 409 configChanged, AOT_NULL_OBJECT))) 410 goto bail; 411 } else { 412 if (TRANSPORTDEC_OK != 413 (ErrorStatus = AudioSpecificConfig_Parse( 414 pAscDummy, bs, 0, pTpDecCallbacks, configMode, 415 configChanged, AOT_NULL_OBJECT))) 416 goto bail; 417 } 418 } 419 if (!pLatmDemux->applyAsc) { 420 updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0; 421 } else { 422 updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1; 423 } 424 425 if (!pLatmDemux->applyAsc) { 426 if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot == 427 AOT_USAC) { /* flush in case SMC has changed */ 428 const UINT usacConfigLength = 429 (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3; 430 if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) { 431 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 432 goto bail; 433 } 434 if (usacConfigLength != usacConfigLengthPrev) { 435 FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] 436 .m_sc.m_usacConfig.UsacConfig, 437 TP_USAC_MAX_CONFIG_LEN); 438 FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] 439 .m_sc.m_usacConfig.UsacConfig, 440 &pAscDummy->m_sc.m_usacConfig.UsacConfig, 441 usacConfigLength); /* store new USAC config */ 442 pAsc[TPDEC_TRACKINDEX(prog, lay)] 443 .m_sc.m_usacConfig.UsacConfigBits = 444 pAscDummy->m_sc.m_usacConfig.UsacConfigBits; 445 pLatmDemux->usacExplicitCfgChanged = 1; 446 } else { 447 if (FDKmemcmp(usacConfigPrev, 448 pAscDummy->m_sc.m_usacConfig.UsacConfig, 449 usacConfigLengthPrev)) { 450 FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] 451 .m_sc.m_usacConfig.UsacConfig, 452 TP_USAC_MAX_CONFIG_LEN); 453 FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] 454 .m_sc.m_usacConfig.UsacConfig, 455 &pAscDummy->m_sc.m_usacConfig.UsacConfig, 456 usacConfigLength); /* store new USAC config */ 457 pAsc[TPDEC_TRACKINDEX(prog, lay)] 458 .m_sc.m_usacConfig.UsacConfigBits = 459 pAscDummy->m_sc.m_usacConfig.UsacConfigBits; 460 pLatmDemux->usacExplicitCfgChanged = 1; 461 } 462 } 463 464 if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] 465 .m_sc.m_usacConfig.m_usacNumElements) { 466 if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] 467 .m_sc.m_usacConfig.element[0] 468 .extElement.usacExtElementHasAudioPreRoll) { 469 pLatmDemux->newCfgHasAudioPreRoll = 470 1; /* if dummy parsed cfg has audioPreRoll we first flush 471 before applying new cfg */ 472 } 473 } 474 } 475 } 476 } 477 478 p_linfo->m_frameLengthType = FDKreadBits(bs, 3); 479 switch (p_linfo->m_frameLengthType) { 480 case 0: 481 p_linfo->m_bufferFullness = FDKreadBits(bs, 8); 482 483 if (!pLatmDemux->m_allStreamsSameTimeFraming) { 484 if ((lay > 0) && 485 (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL || 486 pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == 487 AOT_ER_AAC_SCAL) && 488 (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP || 489 pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == 490 AOT_ER_CELP)) { /* The layer maybe 491 ignored later so 492 read it anyway: */ 493 /* coreFrameOffset = */ FDKreadBits(bs, 6); 494 } 495 } 496 break; 497 case 1: 498 p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9); 499 break; 500 case 3: 501 case 4: 502 case 5: 503 /* CELP */ 504 case 6: 505 case 7: 506 /* HVXC */ 507 default: 508 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 509 goto bail; 510 } /* switch framelengthtype*/ 511 512 } /* layer loop */ 513 } /* prog loop */ 514 515 pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1); 516 pLatmDemux->m_otherDataLength = 0; 517 518 if (pLatmDemux->m_otherDataPresent) { 519 if (pLatmDemux->m_AudioMuxVersion == 1) { 520 pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs); 521 } else { 522 int otherDataLenEsc = 0; 523 do { 524 pLatmDemux->m_otherDataLength <<= 8; // *= 256 525 otherDataLenEsc = FDKreadBits(bs, 1); 526 pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8); 527 } while (otherDataLenEsc); 528 } 529 if (pLatmDemux->m_audioMuxLengthBytes < 530 (pLatmDemux->m_otherDataLength >> 3)) { 531 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; 532 goto bail; 533 } 534 } 535 536 pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1); 537 538 if (pLatmDemux->m_crcCheckPresent) { 539 FDKreadBits(bs, 8); 540 } 541 542 } else { 543 /* audioMuxVersionA > 0 is reserved for future extensions */ 544 ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; 545 } 546 547 /* Configure source decoder: */ 548 if (ErrorStatus == TRANSPORTDEC_OK) { 549 UINT prog; 550 for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) { 551 UINT lay; 552 for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { 553 if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) { 554 int cbError; 555 cbError = pTpDecCallbacks->cbUpdateConfig( 556 pTpDecCallbacks->cbUpdateConfigData, 557 &pAsc[TPDEC_TRACKINDEX(prog, lay)], 558 pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode, 559 &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged); 560 if (cbError == TRANSPORTDEC_NEED_TO_RESTART) { 561 *pfConfigFound = 0; 562 ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART; 563 goto bail; 564 } 565 if (cbError != 0) { 566 *pfConfigFound = 0; 567 if (lay == 0) { 568 ErrorStatus = TRANSPORTDEC_SYNC_ERROR; 569 goto bail; 570 } 571 } else { 572 *pfConfigFound = 1; 573 } 574 } else { 575 *pfConfigFound = 1; 576 } 577 } 578 } 579 } 580 581 bail: 582 if (ErrorStatus != TRANSPORTDEC_OK) { 583 UCHAR applyAsc = pLatmDemux->applyAsc; 584 FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */ 585 pLatmDemux->applyAsc = applyAsc; 586 } else { 587 /* no error and config parsing is finished */ 588 if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0; 589 } 590 591 return (ErrorStatus); 592 } 593 594 TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, 595 CLatmDemux *pLatmDemux) { 596 TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; 597 int totalPayloadBits = 0; 598 599 if (pLatmDemux->m_allStreamsSameTimeFraming == 1) { 600 FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG); 601 for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { 602 FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); 603 for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { 604 LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; 605 606 switch (p_linfo->m_frameLengthType) { 607 case 0: 608 p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); 609 totalPayloadBits += p_linfo->m_frameLengthInBits; 610 break; 611 case 3: 612 case 5: 613 case 7: 614 default: 615 return TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE; 616 } 617 } 618 } 619 } else { 620 ErrorStatus = TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_TIMEFRAMING; 621 } 622 if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 && 623 totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) { 624 return TRANSPORTDEC_PARSE_ERROR; 625 } 626 627 return (ErrorStatus); 628 } 629 630 int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { 631 UCHAR endFlag; 632 int len = 0; 633 634 do { 635 UCHAR tmp = (UCHAR)FDKreadBits(bs, 8); 636 endFlag = (tmp < 255); 637 638 len += tmp; 639 640 } while (endFlag == 0); 641 642 len <<= 3; /* convert from bytes to bits */ 643 644 return len; 645 } 646 647 UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, 648 const UINT layer) { 649 UINT nFrameLenBits = 0; 650 if (prog < pLatmDemux->m_numProgram) { 651 if (layer < pLatmDemux->m_numLayer[prog]) { 652 nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits; 653 } 654 } 655 return nFrameLenBits; 656 } 657 658 UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) { 659 return pLatmDemux->m_otherDataPresent ? 1 : 0; 660 } 661 662 UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) { 663 return pLatmDemux->m_otherDataLength; 664 } 665 666 UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) { 667 return pLatmDemux->m_noSubFrames; 668 } 669 670 UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) { 671 UINT numLayer = 0; 672 if (prog < pLatmDemux->m_numProgram) { 673 numLayer = pLatmDemux->m_numLayer[prog]; 674 } 675 return numLayer; 676 } 677