From 6cfabd35363c3ef5e3b209b867169a500b3ccc3c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Mon, 26 Feb 2018 20:17:00 +0100 Subject: Upgrade to FDKv2 Bug: 71430241 Test: CTS DecoderTest and DecoderTestAacDrc original-Change-Id: Iaa20f749b8a04d553b20247cfe1a8930ebbabe30 Apply clang-format also on header files. original-Change-Id: I14de1ef16bbc79ec0283e745f98356a10efeb2e4 Fixes for MPEG-D DRC original-Change-Id: If1de2d74bbbac84b3f67de3b88b83f6a23b8a15c Catch unsupported tw_mdct at an early stage original-Change-Id: Ied9dd00d754162a0e3ca1ae3e6b854315d818afe Fixing PVC transition frames original-Change-Id: Ib75725abe39252806c32d71176308f2c03547a4e Move qmf bands sanity check original-Change-Id: Iab540c3013c174d9490d2ae100a4576f51d8dbc4 Initialize scaling variable original-Change-Id: I3c4087101b70e998c71c1689b122b0d7762e0f9e Add 16 qmf band configuration to getSlotNrgHQ() original-Change-Id: I49a5d30f703a1b126ff163df9656db2540df21f1 Always apply byte alignment at the end of the AudioMuxElement original-Change-Id: I42d560287506d65d4c3de8bfe3eb9a4ebeb4efc7 Setup SBR element only if no parse error exists original-Change-Id: I1915b73704bc80ab882b9173d6bec59cbd073676 Additional array index check in HCR original-Change-Id: I18cc6e501ea683b5009f1bbee26de8ddd04d8267 Fix fade-in index selection in concealment module original-Change-Id: Ibf802ed6ed8c05e9257e1f3b6d0ac1162e9b81c1 Enable explicit backward compatible parser for AAC_LD original-Change-Id: I27e9c678dcb5d40ed760a6d1e06609563d02482d Skip spatial specific config in explicit backward compatible ASC original-Change-Id: Iff7cc365561319e886090cedf30533f562ea4d6e Update flags description in decoder API original-Change-Id: I9a5b4f8da76bb652f5580cbd3ba9760425c43830 Add QMF domain reset function original-Change-Id: I4f89a8a2c0277d18103380134e4ed86996e9d8d6 DRC upgrade v2.1.0 original-Change-Id: I5731c0540139dab220094cd978ef42099fc45b74 Fix integer overflow in sqrtFixp_lookup() original-Change-Id: I429a6f0d19aa2cc957e0f181066f0ca73968c914 Fix integer overflow in invSqrtNorm2() original-Change-Id: I84de5cbf9fb3adeb611db203fe492fabf4eb6155 Fix integer overflow in GenerateRandomVector() original-Change-Id: I3118a641008bd9484d479e5b0b1ee2b5d7d44d74 Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I29d503c247c5c8282349b79df940416a512fb9d5 Fix integer overflow in FDKsbrEnc_codeEnvelope() original-Change-Id: I6b34b61ebb9d525b0c651ed08de2befc1f801449 Follow-up on: Fix integer overflow in adjustTimeSlot_EldGrid() original-Change-Id: I6f8f578cc7089e5eb7c7b93e580b72ca35ad689a Fix integer overflow in get_pk_v2() original-Change-Id: I63375bed40d45867f6eeaa72b20b1f33e815938c Fix integer overflow in Syn_filt_zero() original-Change-Id: Ie0c02fdfbe03988f9d3b20d10cd9fe4c002d1279 Fix integer overflow in CFac_CalcFacSignal() original-Change-Id: Id2d767c40066c591b51768e978eb8af3b803f0c5 Fix integer overflow in FDKaacEnc_FDKaacEnc_calcPeNoAH() original-Change-Id: Idcbd0f4a51ae2550ed106aa6f3d678d1f9724841 Fix integer overflow in sbrDecoder_calculateGainVec() original-Change-Id: I7081bcbe29c5cede9821b38d93de07c7add2d507 Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4a95ddc18de150102352d4a1845f06094764c881 Fix integer overflow in Pred_Lt4() original-Change-Id: I4dbd012b2de7d07c3e70a47b92e3bfae8dbc750a Fix integer overflow in FDKsbrEnc_InitSbrFastTransientDetector() original-Change-Id: I788cbec1a4a00f44c2f3a72ad7a4afa219807d04 Fix unsigned integer overflow in FDKaacEnc_WriteBitstream() original-Change-Id: I68fc75166e7d2cd5cd45b18dbe3d8c2a92f1822a Fix unsigned integer overflow in FDK_MetadataEnc_Init() original-Change-Id: Ie8d025f9bcdb2442c704bd196e61065c03c10af4 Fix overflow in pseudo random number generators original-Change-Id: I3e2551ee01356297ca14e3788436ede80bd5513c Fix unsigned integer overflow in sbrDecoder_Parse() original-Change-Id: I3f231b2f437e9c37db4d5b964164686710eee971 Fix unsigned integer overflow in longsub() original-Change-Id: I73c2bc50415cac26f1f5a29e125bbe75f9180a6e Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: Ifce2db4b1454b46fa5f887e9d383f1cc43b291e4 Fix overflow at CLpdChannelStream_Read() original-Change-Id: Idb9d822ce3a4272e4794b643644f5434e2d4bf3f Fix unsigned integer overflow in Hcr_State_BODY_SIGN_ESC__ESC_WORD() original-Change-Id: I1ccf77c0015684b85534c5eb97162740a870b71c Fix unsigned integer overflow in UsacConfig_Parse() original-Change-Id: Ie6d27f84b6ae7eef092ecbff4447941c77864d9f Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I713f28e883eea3d70b6fa56a7b8f8c22bcf66ca0 Fix unsigned integer overflow in aacDecoder_drcReadCompression() original-Change-Id: Ia34dfeb88c4705c558bce34314f584965cafcf7a Fix unsigned integer overflow in CDataStreamElement_Read() original-Change-Id: Iae896cc1d11f0a893d21be6aa90bd3e60a2c25f0 Fix unsigned integer overflow in transportDec_AdjustEndOfAccessUnit() original-Change-Id: I64cf29a153ee784bb4a16fdc088baabebc0007dc Fix unsigned integer overflow in transportDec_GetAuBitsRemaining() original-Change-Id: I975b3420faa9c16a041874ba0db82e92035962e4 Fix unsigned integer overflow in extractExtendedData() original-Change-Id: I2a59eb09e2053cfb58dfb75fcecfad6b85a80a8f Fix signed integer overflow in CAacDecoder_ExtPayloadParse() original-Change-Id: I4ad5ca4e3b83b5d964f1c2f8c5e7b17c477c7929 Fix unsigned integer overflow in CAacDecoder_DecodeFrame() original-Change-Id: I29a39df77d45c52a0c9c5c83c1ba81f8d0f25090 Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I8fb194ffc073a3432a380845be71036a272d388f Fix signed integer overflow in _interpolateDrcGain() original-Change-Id: I879ec9ab14005069a7c47faf80e8bc6e03d22e60 Fix unsigned integer overflow in FDKreadBits() original-Change-Id: I1f47a6a8037ff70375aa8844947d5681bb4287ad Fix unsigned integer overflow in FDKbyteAlign() original-Change-Id: Id5f3a11a0c9e50fc6f76ed6c572dbd4e9f2af766 Fix unsigned integer overflow in FDK_get32() original-Change-Id: I9d33b8e97e3d38cbb80629cb859266ca0acdce96 Fix unsigned integer overflow in FDK_pushBack() original-Change-Id: Ic87f899bc8c6acf7a377a8ca7f3ba74c3a1e1c19 Fix unsigned integer overflow in FDK_pushForward() original-Change-Id: I3b754382f6776a34be1602e66694ede8e0b8effc Fix unsigned integer overflow in ReadPsData() original-Change-Id: I25361664ba8139e32bbbef2ca8c106a606ce9c37 Fix signed integer overflow in E_UTIL_residu() original-Change-Id: I8c3abd1f437ee869caa8fb5903ce7d3d641b6aad REVERT: Follow-up on: Integer overflow in CLpc_SynthesisLattice(). original-Change-Id: I3d340099acb0414795c8dfbe6362bc0a8f045f9b Follow-up on: Fix integer overflow in CLpc_SynthesisLattice() original-Change-Id: I4aedb8b3a187064e9f4d985175aa55bb99cc7590 Follow-up on: Fix unsigned integer overflow in aacDecoder_drcParse() original-Change-Id: I2aa2e13916213bf52a67e8b0518e7bf7e57fb37d Fix integer overflow in acelp original-Change-Id: Ie6390c136d84055f8b728aefbe4ebef6e029dc77 Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters() original-Change-Id: I391ffd97ddb0b2c184cba76139bfb356a3b4d2e2 Adjust concealment default settings original-Change-Id: I6a95db935a327c47df348030bcceafcb29f54b21 Saturate estimatedStartPos original-Change-Id: I27be2085e0ae83ec9501409f65e003f6bcba1ab6 Negative shift exponent in _interpolateDrcGain() original-Change-Id: I18edb26b26d002aafd5e633d4914960f7a359c29 Negative shift exponent in calculateICC() original-Change-Id: I3dcd2ae98d2eb70ee0d59750863cbb2a6f4f8aba Too large shift exponent in FDK_put() original-Change-Id: Ib7d9aaa434d2d8de4a13b720ca0464b31ca9b671 Too large shift exponent in CalcInvLdData() original-Change-Id: I43e6e78d4cd12daeb1dcd5d82d1798bdc2550262 Member access within null pointer of type SBR_CHANNEL original-Change-Id: Idc5e4ea8997810376d2f36bbdf628923b135b097 Member access within null pointer of type CpePersistentData original-Change-Id: Ib6c91cb0d37882768e5baf63324e429589de0d9d Member access within null pointer FDKaacEnc_psyMain() original-Change-Id: I7729b7f4479970531d9dc823abff63ca52e01997 Member access within null pointer FDKaacEnc_GetPnsParam() original-Change-Id: I9aa3b9f3456ae2e0f7483dbd5b3dde95fc62da39 Member access within null pointer FDKsbrEnc_EnvEncodeFrame() original-Change-Id: I67936f90ea714e90b3e81bc0dd1472cc713eb23a Add HCR sanity check original-Change-Id: I6c1d9732ebcf6af12f50b7641400752f74be39f7 Fix memory issue for HBE edge case with 8:3 SBR original-Change-Id: I11ea58a61e69fbe8bf75034b640baee3011e63e9 Additional SBR parametrization sanity check for ELD original-Change-Id: Ie26026fbfe174c2c7b3691f6218b5ce63e322140 Add MPEG-D DRC channel layout check original-Change-Id: Iea70a74f171b227cce636a9eac4ba662777a2f72 Additional out-of-bounds checks in MPEG-D DRC original-Change-Id: Ife4a8c3452c6fde8a0a09e941154a39a769777d4 Change-Id: Ic63cb2f628720f54fe9b572b0cb528e2599c624e --- libMpegTPDec/src/tpdec_latm.cpp | 693 +++++++++++++++++++++++++++------------- 1 file changed, 466 insertions(+), 227 deletions(-) (limited to 'libMpegTPDec/src/tpdec_latm.cpp') diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index 5710d77..b4f7372 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,91 +90,151 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/******************* MPEG transport format decoder library ********************* Author(s): Daniel Homm + Description: -******************************************************************************/ +*******************************************************************************/ #include "tpdec_latm.h" - #include "FDK_bitstream.h" +#define TPDEC_TRACKINDEX(p, l) (1 * (p) + (l)) -#define TPDEC_TRACKINDEX(p,l) (2*(p) + (l)) - -static -UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) -{ +static UINT CLatmDemux_GetValue(HANDLE_FDK_BITSTREAM bs) { UCHAR bytesForValue = 0, tmp = 0; int value = 0; - bytesForValue = (UCHAR) FDKreadBits(bs,2); + bytesForValue = (UCHAR)FDKreadBits(bs, 2); - for (UINT i=0; i<=bytesForValue; i++) { + for (UINT i = 0; i <= bytesForValue; i++) { value <<= 8; - tmp = (UCHAR) FDKreadBits(bs,8); + tmp = (UCHAR)FDKreadBits(bs, 8); value += tmp; } return value; } - -static -TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( - HANDLE_FDK_BITSTREAM bs, - CLatmDemux *pLatmDemux, - int m_muxConfigPresent, - CSTpCallBacks *pTpDecCallbacks, - CSAudioSpecificConfig *pAsc, - int *pfConfigFound - ) -{ +static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( + HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, int m_muxConfigPresent, + CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, + int *pfConfigFound) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; + UCHAR applyAsc = pLatmDemux->applyAsc; if (m_muxConfigPresent) { - pLatmDemux->m_useSameStreamMux = FDKreadBits(bs,1); + pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1); if (!pLatmDemux->m_useSameStreamMux) { - if ((ErrorStatus = CLatmDemux_ReadStreamMuxConfig(bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound))) { - return (ErrorStatus); + int i; + UCHAR configChanged = 0; + UCHAR configMode = 0; + + FDK_BITSTREAM bsAnchor; + + FDK_BITSTREAM bsAnchorDummyParse; + + if (!pLatmDemux->applyAsc) { + bsAnchorDummyParse = *bs; + pLatmDemux->newCfgHasAudioPreRoll = 0; + /* do dummy-parsing of ASC to determine if there is an audioPreRoll */ + configMode |= AC_CM_DET_CFG_CHANGE; + if (TRANSPORTDEC_OK != + (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( + bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, + configMode, configChanged))) { + goto bail; + } + + if (pLatmDemux->newCfgHasAudioPreRoll) { + pLatmDemux->newCfgHasAudioPreRoll = 0; + /* with audioPreRoll we must flush before applying new cfg */ + pLatmDemux->applyAsc = 0; + } else { + *bs = bsAnchorDummyParse; + pLatmDemux->applyAsc = 1; /* apply new config immediate */ + } + } + + if (pLatmDemux->applyAsc) { + for (i = 0; i < 2; i++) { + configMode = 0; + + if (i == 0) { + configMode |= AC_CM_DET_CFG_CHANGE; + bsAnchor = *bs; + } else { + configMode |= AC_CM_ALLOC_MEM; + *bs = bsAnchor; + } + + if (TRANSPORTDEC_OK != + (ErrorStatus = CLatmDemux_ReadStreamMuxConfig( + bs, pLatmDemux, pTpDecCallbacks, pAsc, pfConfigFound, + configMode, configChanged))) { + goto bail; + } + + if (ErrorStatus == TRANSPORTDEC_OK) { + if ((i == 0) && (pAsc->AacConfigChanged || pAsc->SbrConfigChanged || + pAsc->SacConfigChanged)) { + int errC; + + configChanged = 1; + errC = pTpDecCallbacks->cbFreeMem(pTpDecCallbacks->cbFreeMemData, + pAsc); + if (errC != 0) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + } + } + } } } } - /* If there was no configuration read, its not possible to parse PayloadLengthInfo below. */ - if (! *pfConfigFound) { - return TRANSPORTDEC_SYNC_ERROR; + /* If there was no configuration read, its not possible to parse + * PayloadLengthInfo below. */ + if (!*pfConfigFound) { + ErrorStatus = TRANSPORTDEC_SYNC_ERROR; + goto bail; } if (pLatmDemux->m_AudioMuxVersionA == 0) { /* Do only once per call, because parsing and decoding is done in-line. */ - if ((ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs,pLatmDemux))) { - return (ErrorStatus); + if (TRANSPORTDEC_OK != + (ErrorStatus = CLatmDemux_ReadPayloadLengthInfo(bs, pLatmDemux))) { + *pfConfigFound = 0; + goto bail; } } else { /* audioMuxVersionA > 0 is reserved for future extensions */ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; + *pfConfigFound = 0; + goto bail; + } + +bail: + if (ErrorStatus != TRANSPORTDEC_OK) { + pLatmDemux->applyAsc = applyAsc; } return (ErrorStatus); } -TRANSPORTDEC_ERROR CLatmDemux_Read( - HANDLE_FDK_BITSTREAM bs, - CLatmDemux *pLatmDemux, - TRANSPORT_TYPE tt, - CSTpCallBacks *pTpDecCallbacks, - CSAudioSpecificConfig *pAsc, - int *pfConfigFound, - const INT ignoreBufferFullness - ) -{ +TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, + CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, + CSTpCallBacks *pTpDecCallbacks, + CSAudioSpecificConfig *pAsc, + int *pfConfigFound, + const INT ignoreBufferFullness) { UINT cntBits; UINT cmpBufferFullness; UINT audioMuxLengthBytesLast = 0; @@ -175,29 +246,27 @@ TRANSPORTDEC_ERROR CLatmDemux_Read( return TRANSPORTDEC_NOT_ENOUGH_BITS; } - if ((ErrorStatus = CLatmDemux_ReadAudioMuxElement(bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0), pTpDecCallbacks, pAsc, pfConfigFound))) + if (TRANSPORTDEC_OK != (ErrorStatus = CLatmDemux_ReadAudioMuxElement( + bs, pLatmDemux, (tt != TT_MP4_LATM_MCP0), + pTpDecCallbacks, pAsc, pfConfigFound))) return (ErrorStatus); - if (!ignoreBufferFullness) - { - cmpBufferFullness = 24+audioMuxLengthBytesLast*8 - + pLatmDemux->m_linfo[0][0].m_bufferFullness* pAsc[TPDEC_TRACKINDEX(0,0)].m_channelConfiguration*32; + if (!ignoreBufferFullness) { + cmpBufferFullness = + 24 + audioMuxLengthBytesLast * 8 + + pLatmDemux->m_linfo[0][0].m_bufferFullness * + pAsc[TPDEC_TRACKINDEX(0, 0)].m_channelConfiguration * 32; /* evaluate buffer fullness */ - if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) - { - if (!pLatmDemux->BufferFullnessAchieved) - { - if (cntBits < cmpBufferFullness) - { + if (pLatmDemux->m_linfo[0][0].m_bufferFullness != 0xFF) { + if (!pLatmDemux->BufferFullnessAchieved) { + if (cntBits < cmpBufferFullness) { /* condition for start of decoding is not fulfilled */ /* the current frame will not be decoded */ return TRANSPORTDEC_NOT_ENOUGH_BITS; - } - else - { + } else { pLatmDemux->BufferFullnessAchieved = 1; } } @@ -207,227 +276,397 @@ TRANSPORTDEC_ERROR CLatmDemux_Read( return (ErrorStatus); } - TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig( - HANDLE_FDK_BITSTREAM bs, - CLatmDemux *pLatmDemux, - CSTpCallBacks *pTpDecCallbacks, - CSAudioSpecificConfig *pAsc, - int * pfConfigFound - ) -{ + HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, + CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, + int *pfConfigFound, UCHAR configMode, UCHAR configChanged) { + CSAudioSpecificConfig ascDummy; /* the actual config is needed for flushing, + after that new config can be parsed */ + CSAudioSpecificConfig *pAscDummy; + pAscDummy = &ascDummy; + pLatmDemux->usacExplicitCfgChanged = 0; LATM_LAYER_INFO *p_linfo = NULL; TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; + UCHAR updateConfig[1 * 1] = {0}; - pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs,1); + pLatmDemux->m_AudioMuxVersion = FDKreadBits(bs, 1); if (pLatmDemux->m_AudioMuxVersion == 0) { pLatmDemux->m_AudioMuxVersionA = 0; } else { - pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs,1); + pLatmDemux->m_AudioMuxVersionA = FDKreadBits(bs, 1); } if (pLatmDemux->m_AudioMuxVersionA == 0) { if (pLatmDemux->m_AudioMuxVersion == 1) { pLatmDemux->m_taraBufferFullness = CLatmDemux_GetValue(bs); } - pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs,1); - pLatmDemux->m_noSubFrames = FDKreadBits(bs,6) + 1; - pLatmDemux->m_numProgram = FDKreadBits(bs,4) + 1; + pLatmDemux->m_allStreamsSameTimeFraming = FDKreadBits(bs, 1); + pLatmDemux->m_noSubFrames = FDKreadBits(bs, 6) + 1; + pLatmDemux->m_numProgram = FDKreadBits(bs, 4) + 1; - if (pLatmDemux->m_numProgram > 1) { - return TRANSPORTDEC_UNSUPPORTED_FORMAT; + if (pLatmDemux->m_numProgram > LATM_MAX_PROG) { + ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; + goto bail; } int idCnt = 0; for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { - pLatmDemux->m_numLayer = FDKreadBits(bs,3) + 1; - if (pLatmDemux->m_numLayer > 2) { - return TRANSPORTDEC_UNSUPPORTED_FORMAT; + pLatmDemux->m_numLayer[prog] = FDKreadBits(bs, 3) + 1; + if (pLatmDemux->m_numLayer[prog] > LATM_MAX_LAYER) { + ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; + goto bail; } - for (UINT lay = 0; lay < pLatmDemux->m_numLayer; lay++) { + for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { + int useSameConfig; p_linfo = &pLatmDemux->m_linfo[prog][lay]; p_linfo->m_streamID = idCnt++; p_linfo->m_frameLengthInBits = 0; - if( (prog == 0) && (lay == 0) ) { - pLatmDemux->m_useSameConfig = 0; + if ((prog == 0) && (lay == 0)) { + useSameConfig = 0; } else { - pLatmDemux->m_useSameConfig = FDKreadBits(bs,1); + useSameConfig = FDKreadBits(bs, 1); } - if (pLatmDemux->m_useSameConfig) { - if (lay > 1) { - FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog,lay)], &pAsc[TPDEC_TRACKINDEX(prog,lay-1)], sizeof(CSAudioSpecificConfig)); + if (useSameConfig) { + if (lay > 0) { + FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)], + &pAsc[TPDEC_TRACKINDEX(prog, lay - 1)], + sizeof(CSAudioSpecificConfig)); } else { - return TRANSPORTDEC_PARSE_ERROR; + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; } } else { - if (pLatmDemux->m_AudioMuxVersion == 1) - { + UINT usacConfigLengthPrev = 0; + UCHAR usacConfigPrev[TP_USAC_MAX_CONFIG_LEN]; + + if (!(pLatmDemux->applyAsc) && + (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_USAC)) { + usacConfigLengthPrev = + (UINT)(pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfigBits + + 7) >> + 3; /* store previous USAC config length */ + if (usacConfigLengthPrev > TP_USAC_MAX_CONFIG_LEN) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + FDKmemclear(usacConfigPrev, TP_USAC_MAX_CONFIG_LEN); + FDKmemcpy( + usacConfigPrev, + &pAsc[TPDEC_TRACKINDEX(prog, lay)].m_sc.m_usacConfig.UsacConfig, + usacConfigLengthPrev); /* store previous USAC config */ + } + if (pLatmDemux->m_AudioMuxVersion == 1) { FDK_BITSTREAM tmpBs; - UINT ascStartPos, ascLen=0; - + UINT ascLen = 0; ascLen = CLatmDemux_GetValue(bs); - ascStartPos = FDKgetValidBits(bs); + /* The ascLen could be wrong, so check if validBits<=bufBits*/ + if (ascLen > FDKgetValidBits(bs)) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + FDKsyncCache(bs); tmpBs = *bs; - FDKsyncCache(&tmpBs); tmpBs.hBitBuf.ValidBits = ascLen; - + /* Read ASC */ - if ((ErrorStatus = AudioSpecificConfig_Parse(&pAsc[TPDEC_TRACKINDEX(prog,lay)], &tmpBs, 1, pTpDecCallbacks))) { - return (ErrorStatus); + if (pLatmDemux->applyAsc) { + if (TRANSPORTDEC_OK != + (ErrorStatus = AudioSpecificConfig_Parse( + &pAsc[TPDEC_TRACKINDEX(prog, lay)], &tmpBs, 1, + pTpDecCallbacks, configMode, configChanged, + AOT_NULL_OBJECT))) + goto bail; + } else { + if (TRANSPORTDEC_OK != + (ErrorStatus = AudioSpecificConfig_Parse( + pAscDummy, &tmpBs, 1, pTpDecCallbacks, configMode, + configChanged, AOT_NULL_OBJECT))) + goto bail; } - *pfConfigFound = 1; /* The field p_linfo->m_ascLen could be wrong, so check if */ - if ( 0 > (INT)FDKgetValidBits(&tmpBs)) { - return TRANSPORTDEC_PARSE_ERROR; + if (0 > (INT)FDKgetValidBits(&tmpBs)) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; } FDKpushFor(bs, ascLen); /* position bitstream after ASC */ - } - else { + } else { /* Read ASC */ - if ((ErrorStatus = AudioSpecificConfig_Parse(&pAsc[TPDEC_TRACKINDEX(prog,lay)], bs, 0, pTpDecCallbacks))) { - return (ErrorStatus); + if (pLatmDemux->applyAsc) { + if (TRANSPORTDEC_OK != (ErrorStatus = AudioSpecificConfig_Parse( + &pAsc[TPDEC_TRACKINDEX(prog, lay)], + bs, 0, pTpDecCallbacks, configMode, + configChanged, AOT_NULL_OBJECT))) + goto bail; + } else { + if (TRANSPORTDEC_OK != + (ErrorStatus = AudioSpecificConfig_Parse( + pAscDummy, bs, 0, pTpDecCallbacks, configMode, + configChanged, AOT_NULL_OBJECT))) + goto bail; } } - { - int cbError; + if (!pLatmDemux->applyAsc) { + updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 0; + } else { + updateConfig[TPDEC_TRACKINDEX(prog, lay)] = 1; + } - cbError = pTpDecCallbacks->cbUpdateConfig(pTpDecCallbacks->cbUpdateConfigData, &pAsc[TPDEC_TRACKINDEX(prog,lay)]); - if (cbError != 0) { - return TRANSPORTDEC_UNKOWN_ERROR; + if (!pLatmDemux->applyAsc) { + if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)].m_aot == + AOT_USAC) { /* flush in case SMC has changed */ + const UINT usacConfigLength = + (UINT)(pAscDummy->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3; + if (usacConfigLength > TP_USAC_MAX_CONFIG_LEN) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + if (usacConfigLength != usacConfigLengthPrev) { + FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfig, + TP_USAC_MAX_CONFIG_LEN); + FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfig, + &pAscDummy->m_sc.m_usacConfig.UsacConfig, + usacConfigLength); /* store new USAC config */ + pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfigBits = + pAscDummy->m_sc.m_usacConfig.UsacConfigBits; + pLatmDemux->usacExplicitCfgChanged = 1; + } else { + if (FDKmemcmp(usacConfigPrev, + pAscDummy->m_sc.m_usacConfig.UsacConfig, + usacConfigLengthPrev)) { + FDKmemclear(&pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfig, + TP_USAC_MAX_CONFIG_LEN); + FDKmemcpy(&pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfig, + &pAscDummy->m_sc.m_usacConfig.UsacConfig, + usacConfigLength); /* store new USAC config */ + pAsc[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.UsacConfigBits = + pAscDummy->m_sc.m_usacConfig.UsacConfigBits; + pLatmDemux->usacExplicitCfgChanged = 1; + } + } + + if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.m_usacNumElements) { + if (pAscDummy[TPDEC_TRACKINDEX(prog, lay)] + .m_sc.m_usacConfig.element[0] + .extElement.usacExtElementHasAudioPreRoll) { + pLatmDemux->newCfgHasAudioPreRoll = + 1; /* if dummy parsed cfg has audioPreRoll we first flush + before applying new cfg */ + } + } } - *pfConfigFound = 1; } } - p_linfo->m_frameLengthType = FDKreadBits(bs,3); - switch( p_linfo->m_frameLengthType ) { - case 0: - p_linfo->m_bufferFullness = FDKreadBits(bs,8); - - if (!pLatmDemux->m_allStreamsSameTimeFraming) { - if ((lay > 0) && (pAsc[TPDEC_TRACKINDEX(prog,lay)].m_aot == AOT_AAC_SCAL || pAsc[TPDEC_TRACKINDEX(prog,lay)].m_aot == AOT_ER_AAC_SCAL)) { - return TRANSPORTDEC_UNSUPPORTED_FORMAT; + p_linfo->m_frameLengthType = FDKreadBits(bs, 3); + switch (p_linfo->m_frameLengthType) { + case 0: + p_linfo->m_bufferFullness = FDKreadBits(bs, 8); + + if (!pLatmDemux->m_allStreamsSameTimeFraming) { + if ((lay > 0) && + (pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == AOT_AAC_SCAL || + pAsc[TPDEC_TRACKINDEX(prog, lay)].m_aot == + AOT_ER_AAC_SCAL) && + (pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == AOT_CELP || + pAsc[TPDEC_TRACKINDEX(prog, lay - 1)].m_aot == + AOT_ER_CELP)) { /* The layer maybe + ignored later so + read it anyway: */ + /* coreFrameOffset = */ FDKreadBits(bs, 6); + } } - } - break; - case 1: - /* frameLength = FDKreadBits(bs,9); */ - case 3: - case 4: - case 5: - /* CELP */ - case 6: - case 7: - /* HVXC */ - default: - return TRANSPORTDEC_PARSE_ERROR; //_LATM_INVALIDFRAMELENGTHTYPE; - - } /* switch framelengthtype*/ - - } /* layer loop */ - } /* prog loop */ - - pLatmDemux->m_otherDataPresent = FDKreadBits(bs,1); - pLatmDemux->m_otherDataLength = 0; + break; + case 1: + p_linfo->m_frameLengthInBits = FDKreadBits(bs, 9); + break; + case 3: + case 4: + case 5: + /* CELP */ + case 6: + case 7: + /* HVXC */ + default: + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } /* switch framelengthtype*/ + + } /* layer loop */ + } /* prog loop */ + + pLatmDemux->m_otherDataPresent = FDKreadBits(bs, 1); + pLatmDemux->m_otherDataLength = 0; if (pLatmDemux->m_otherDataPresent) { - int otherDataLenEsc = 0; - do { - pLatmDemux->m_otherDataLength <<= 8; // *= 256 - otherDataLenEsc = FDKreadBits(bs,1); - pLatmDemux->m_otherDataLength += FDKreadBits(bs,8); - } while (otherDataLenEsc); + if (pLatmDemux->m_AudioMuxVersion == 1) { + pLatmDemux->m_otherDataLength = CLatmDemux_GetValue(bs); + } else { + int otherDataLenEsc = 0; + do { + pLatmDemux->m_otherDataLength <<= 8; // *= 256 + otherDataLenEsc = FDKreadBits(bs, 1); + pLatmDemux->m_otherDataLength += FDKreadBits(bs, 8); + } while (otherDataLenEsc); + } + if (pLatmDemux->m_audioMuxLengthBytes < + (pLatmDemux->m_otherDataLength >> 3)) { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } } - pLatmDemux->m_crcCheckPresent = FDKreadBits(bs,1); - pLatmDemux->m_crcCheckSum = 0; + pLatmDemux->m_crcCheckPresent = FDKreadBits(bs, 1); if (pLatmDemux->m_crcCheckPresent) { - pLatmDemux->m_crcCheckSum = FDKreadBits(bs,8); + FDKreadBits(bs, 8); } - } - else { + } else { /* audioMuxVersionA > 0 is reserved for future extensions */ ErrorStatus = TRANSPORTDEC_UNSUPPORTED_FORMAT; } + + /* Configure source decoder: */ + if (ErrorStatus == TRANSPORTDEC_OK) { + UINT prog; + for (prog = 0; prog < pLatmDemux->m_numProgram; prog++) { + UINT lay; + for (lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { + if (updateConfig[TPDEC_TRACKINDEX(prog, lay)] != 0) { + int cbError; + cbError = pTpDecCallbacks->cbUpdateConfig( + pTpDecCallbacks->cbUpdateConfigData, + &pAsc[TPDEC_TRACKINDEX(prog, lay)], + pAsc[TPDEC_TRACKINDEX(prog, lay)].configMode, + &pAsc[TPDEC_TRACKINDEX(prog, lay)].AacConfigChanged); + if (cbError == TRANSPORTDEC_NEED_TO_RESTART) { + *pfConfigFound = 0; + ErrorStatus = TRANSPORTDEC_NEED_TO_RESTART; + goto bail; + } + if (cbError != 0) { + *pfConfigFound = 0; + if (lay == 0) { + ErrorStatus = TRANSPORTDEC_SYNC_ERROR; + goto bail; + } + } else { + *pfConfigFound = 1; + } + } else { + *pfConfigFound = 1; + } + } + } + } + +bail: + if (ErrorStatus != TRANSPORTDEC_OK) { + UCHAR applyAsc = pLatmDemux->applyAsc; + FDKmemclear(pLatmDemux, sizeof(CLatmDemux)); /* reset structure */ + pLatmDemux->applyAsc = applyAsc; + } else { + /* no error and config parsing is finished */ + if (configMode == AC_CM_ALLOC_MEM) pLatmDemux->applyAsc = 0; + } + return (ErrorStatus); } -TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux) -{ +TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, + CLatmDemux *pLatmDemux) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; int totalPayloadBits = 0; - if( pLatmDemux->m_allStreamsSameTimeFraming == 1 ) { - for (UINT prog=0; progm_numProgram; prog++ ) { - for (UINT lay=0; laym_numLayer; lay++ ) { + if (pLatmDemux->m_allStreamsSameTimeFraming == 1) { + FDK_ASSERT(pLatmDemux->m_numProgram <= LATM_MAX_PROG); + for (UINT prog = 0; prog < pLatmDemux->m_numProgram; prog++) { + FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); + for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; - switch (p_linfo->m_frameLengthType ) { - case 0: - p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); - totalPayloadBits += p_linfo->m_frameLengthInBits; - break; - case 3: - case 5: - case 7: - default: - return TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE; + switch (p_linfo->m_frameLengthType) { + case 0: + p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); + totalPayloadBits += p_linfo->m_frameLengthInBits; + break; + case 3: + case 5: + case 7: + default: + return TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_INVALIDFRAMELENGTHTYPE; } } } + } else { + ErrorStatus = TRANSPORTDEC_PARSE_ERROR; // AAC_DEC_LATM_TIMEFRAMING; } - else { - ErrorStatus = TRANSPORTDEC_PARSE_ERROR; //AAC_DEC_LATM_TIMEFRAMING; - } - if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 && totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes*8) { + if (pLatmDemux->m_audioMuxLengthBytes > (UINT)0 && + totalPayloadBits > (int)pLatmDemux->m_audioMuxLengthBytes * 8) { return TRANSPORTDEC_PARSE_ERROR; } + return (ErrorStatus); } -int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) -{ +int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { UCHAR endFlag; int len = 0; do { - UCHAR tmp = (UCHAR) FDKreadBits(bs,8); + UCHAR tmp = (UCHAR)FDKreadBits(bs, 8); endFlag = (tmp < 255); len += tmp; - } while( endFlag == 0 ); + } while (endFlag == 0); - len <<= 3; /* convert from bytes to bits */ + len <<= 3; /* convert from bytes to bits */ return len; } -int CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux) -{ - return pLatmDemux->m_linfo[0][0].m_frameLengthInBits; +UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, + const UINT layer) { + UINT nFrameLenBits = 0; + if (prog < pLatmDemux->m_numProgram) { + if (layer < pLatmDemux->m_numLayer[prog]) { + nFrameLenBits = pLatmDemux->m_linfo[prog][layer].m_frameLengthInBits; + } + } + return nFrameLenBits; } -int CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) -{ +UINT CLatmDemux_GetOtherDataPresentFlag(CLatmDemux *pLatmDemux) { return pLatmDemux->m_otherDataPresent ? 1 : 0; } -int CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) -{ +UINT CLatmDemux_GetOtherDataLength(CLatmDemux *pLatmDemux) { return pLatmDemux->m_otherDataLength; } -UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) -{ +UINT CLatmDemux_GetNrOfSubFrames(CLatmDemux *pLatmDemux) { return pLatmDemux->m_noSubFrames; } +UINT CLatmDemux_GetNrOfLayers(CLatmDemux *pLatmDemux, const UINT prog) { + UINT numLayer = 0; + if (prog < pLatmDemux->m_numProgram) { + numLayer = pLatmDemux->m_numLayer[prog]; + } + return numLayer; +} -- cgit v1.2.3 From 9ab67882eca7454dc001e158bc1e6e2219d6650b Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 4 May 2018 15:51:23 +0200 Subject: FDKv2 additional fixes Bug: 71430241 Bug: 79220129 Test: cts-tradefed run commandAndExit cts-dev -m CtsMediaTestCases -t android.media.cts.DecoderTestXheAac cts-tradefed run commandAndExit cts-dev -m CtsMediaTestCases -t android.media.cts.DecoderTestAacDrc Add restriction to call intensity stereo tool only for applicable configurations Change-Id: I30ec6640bd484c56cc9d5b8b35186fc1c875e021 Fix high band energy calculation in sbr encoder Change-Id: I964dd46fab2ed797c440a983512bbab7e1aff98a Fix out-of-bounds read access in noiseless coder Change-Id: I9a669435dbdca421ff9e4affec57811002d75b3b Use temporary buffer for dummy parsing to check presence of audioPreroll data Change-Id: I2d42c5c8deddde34351c3d2858b9fe196b3a0906 Set applyAsc to 1 in case that the ASC parsing fails Change-Id: I552a8b960270bc18cae459ad28a3ba241035668e Parametric stereo together with mps not supported Change-Id: Icde14a2774a4303bb0c41046861a59d04b624365 Align ssc callback error path for drm Change-Id: Ie8ecbfa42c702e6df81c1aec532a9ff1e653dac9 Ensure that the bit counter starts at a multiple of TPDEC_SYNCSKIP Change-Id: I08d69ec361b2e2ed800282e333fd248b4b3ca245 Allow flushing only when audioPreroll is enabled in current and new config Change-Id: I52e95d75de4bbed692be922a59a23bda58870625 Omit reverse channel mapping in pass through mode Change-Id: I335e209c29a700cc091be069f1d08e4288b40793 --- libAACdec/src/aacdecoder_lib.cpp | 11 ++++++----- libAACdec/src/channel.cpp | 21 ++++++++++++--------- libAACdec/src/channelinfo.h | 4 +--- libAACdec/src/stereo.cpp | 5 ++--- libMpegTPDec/src/tpdec_asc.cpp | 2 +- libMpegTPDec/src/tpdec_latm.cpp | 10 +++++++--- libMpegTPDec/src/tpdec_lib.cpp | 6 ++++++ libSACdec/src/sac_dec_lib.cpp | 15 +++++++++++---- libSACenc/src/sacenc_nlc_enc.cpp | 10 ++++++++-- libSBRenc/src/tran_det.cpp | 2 +- 10 files changed, 55 insertions(+), 31 deletions(-) (limited to 'libMpegTPDec/src/tpdec_latm.cpp') diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index b7ea8df..e62d187 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -396,7 +396,8 @@ static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, /* MPS found but invalid or not decodable by this instance */ hAacDecoder->mpsEnableCurr = 0; hAacDecoder->mpsApplicable = 0; - if ((coreCodec == AOT_USAC) || IS_LOWDELAY(coreCodec)) { + if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) || + IS_LOWDELAY(coreCodec)) { errTp = TRANSPORTDEC_PARSE_ERROR; } else { errTp = TRANSPORTDEC_OK; @@ -1654,14 +1655,14 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, self->streamInfo.frameSize; for (ch = 0; ch < self->streamInfo.numChannels; ch++) { - int mapValue = FDK_chMapDescr_getMapValue( + UCHAR mapValue = FDK_chMapDescr_getMapValue( &self->mapDescr, (UCHAR)ch, self->chMapIndex); - reverseInChannelMap[mapValue] = ch; + if (mapValue < (8)) reverseInChannelMap[mapValue] = ch; } for (ch = 0; ch < (int)numDrcOutChannels; ch++) { - int mapValue = FDK_chMapDescr_getMapValue( + UCHAR mapValue = FDK_chMapDescr_getMapValue( &self->mapDescr, (UCHAR)ch, numDrcOutChannels); - reverseOutChannelMap[mapValue] = ch; + if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch; } /* The output of SBR and MPS is interleaved. Deinterleaving may be diff --git a/libAACdec/src/channel.cpp b/libAACdec/src/channel.cpp index dbbf58a..cfffd57 100644 --- a/libAACdec/src/channel.cpp +++ b/libAACdec/src/channel.cpp @@ -225,15 +225,18 @@ void CChannelElement_Decode( /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb */ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) { - CJointStereo_ApplyIS( - pAacDecoderChannelInfo, - GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo, - pSamplingRateInfo), - GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo), - GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), - GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo), - pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ? 1 - : 0); + if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow == + 1) && + (el_channels == 2)) { + CJointStereo_ApplyIS( + pAacDecoderChannelInfo, + GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo, + pSamplingRateInfo), + GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo), + GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), + GetScaleFactorBandsTransmitted( + &pAacDecoderChannelInfo[L]->icsInfo)); + } } } /* maybe_stereo */ diff --git a/libAACdec/src/channelinfo.h b/libAACdec/src/channelinfo.h index 7c95e12..45a288f 100644 --- a/libAACdec/src/channelinfo.h +++ b/libAACdec/src/channelinfo.h @@ -478,15 +478,13 @@ void CJointStereo_ApplyMS( \param pWindowGroupLength pointer to window group length array. \param windowGroups number of window groups. \param scaleFactorBandsTransmitted number of transmitted scalefactor bands. - \param CommonWindow common window bit. \return none */ void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], const short *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength, const int windowGroups, - const int scaleFactorBandsTransmitted, - const UINT CommonWindow); + const int scaleFactorBandsTransmitted); /* aacdec_pns.cpp */ int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band); diff --git a/libAACdec/src/stereo.cpp b/libAACdec/src/stereo.cpp index bb4f050..eed826b 100644 --- a/libAACdec/src/stereo.cpp +++ b/libAACdec/src/stereo.cpp @@ -1177,8 +1177,7 @@ void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength, const int windowGroups, - const int scaleFactorBandsTransmitted, - const UINT CommonWindow) { + const int scaleFactorBandsTransmitted) { CJointStereoData *pJointStereoData = &pAacDecoderChannelInfo[L]->pComData->jointStereoData; @@ -1228,7 +1227,7 @@ void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], rightScale[band] = leftScale[band] + msb + 1; - if (CommonWindow && (pJointStereoData->MsUsed[band] & groupMask)) { + if (pJointStereoData->MsUsed[band] & groupMask) { if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */ { scale = -scale; diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index abe66e5..74beaa6 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -2488,7 +2488,7 @@ TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse( switch (audioCoding) { case 0: /* AAC */ - if (coderField >> 2) { + if ((coderField >> 2) && (audioMode != 1)) { self->m_aot = AOT_DRM_SURROUND; /* Set pseudo AOT for Drm Surround */ } else { self->m_aot = AOT_DRM_AAC; /* Set pseudo AOT for Drm AAC */ diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index b4f7372..2edf055 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -126,7 +126,6 @@ static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( CSTpCallBacks *pTpDecCallbacks, CSAudioSpecificConfig *pAsc, int *pfConfigFound) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; - UCHAR applyAsc = pLatmDemux->applyAsc; if (m_muxConfigPresent) { pLatmDemux->m_useSameStreamMux = FDKreadBits(bs, 1); @@ -152,7 +151,12 @@ static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( goto bail; } - if (pLatmDemux->newCfgHasAudioPreRoll) { + /* Allow flushing only when audioPreroll functionality is enabled in + * current and new config otherwise the new config can be applied + * immediately. */ + if (pAsc->m_sc.m_usacConfig.element[0] + .extElement.usacExtElementHasAudioPreRoll && + pLatmDemux->newCfgHasAudioPreRoll) { pLatmDemux->newCfgHasAudioPreRoll = 0; /* with audioPreRoll we must flush before applying new cfg */ pLatmDemux->applyAsc = 0; @@ -223,7 +227,7 @@ static TRANSPORTDEC_ERROR CLatmDemux_ReadAudioMuxElement( bail: if (ErrorStatus != TRANSPORTDEC_OK) { - pLatmDemux->applyAsc = applyAsc; + pLatmDemux->applyAsc = 1; } return (ErrorStatus); diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 10e3352..306bec0 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1151,6 +1151,12 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, &syncLayerFrameBits, &fConfigFound, &headerBits); if (TPDEC_IS_FATAL_ERROR(err)) { + /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead + * next time. Ensure that the bit amount lands at a multiple of + * TPDEC_SYNCSKIP. */ + FDKpushBiDirectional( + hBs, -headerBits + TPDEC_SYNCSKIP + (bitsAvail % TPDEC_SYNCSKIP)); + goto bail; } } diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index 56d8693..ebf9bee 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_lib.cpp @@ -698,6 +698,7 @@ SACDEC_ERROR mpegSurroundDecoder_Config( INT coreSbrFrameLengthIndex, INT configBytes, const UCHAR configMode, UCHAR *configChanged) { SACDEC_ERROR err = MPS_OK; + SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; switch (coreCodec) { case AOT_DRM_USAC: @@ -705,7 +706,6 @@ SACDEC_ERROR mpegSurroundDecoder_Config( if (configMode == AC_CM_DET_CFG_CHANGE) { /* In config detection mode write spatial specific config parameters * into temporarily allocated structure */ - SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; err = SpatialDecParseMps212Config( hBs, &spatialSpecificConfig, samplingRate, coreCodec, stereoConfigIndex, coreSbrFrameLengthIndex); @@ -718,9 +718,16 @@ SACDEC_ERROR mpegSurroundDecoder_Config( break; case AOT_ER_AAC_ELD: case AOT_ER_AAC_LD: - err = SpatialDecParseSpecificConfig( - hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, configBytes, - coreCodec); + if (configMode == AC_CM_DET_CFG_CHANGE) { + /* In config detection mode write spatial specific config parameters + * into temporarily allocated structure */ + err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig, + configBytes, coreCodec); + } else { + err = SpatialDecParseSpecificConfig( + hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, + configBytes, coreCodec); + } break; default: err = MPS_UNSUPPORTED_FORMAT; diff --git a/libSACenc/src/sacenc_nlc_enc.cpp b/libSACenc/src/sacenc_nlc_enc.cpp index ecb89b7..0ba6cc9 100644 --- a/libSACenc/src/sacenc_nlc_enc.cpp +++ b/libSACenc/src/sacenc_nlc_enc.cpp @@ -379,16 +379,22 @@ static UINT huff_enc_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type, switch (data_type) { case t_CLD: - part0 = fdk_sacenc_huffPart0Tab.cld[in_data[0]]; pHuffTab = fdk_sacenc_huffCLDTab.h1D[dim1]; break; case t_ICC: - part0 = fdk_sacenc_huffPart0Tab.icc[in_data[0]]; pHuffTab = fdk_sacenc_huffICCTab.h1D[dim1]; break; } if (p0_flag) { + switch (data_type) { + case t_CLD: + part0 = fdk_sacenc_huffPart0Tab.cld[in_data[0]]; + break; + case t_ICC: + part0 = fdk_sacenc_huffPart0Tab.icc[in_data[0]]; + break; + } huffBits += FDKwriteBits(strm, HUFF_VALUE(part0), HUFF_LENGTH(part0)); offset = 1; } diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp index ba9ae68..b6f1b9f 100644 --- a/libSBRenc/src/tran_det.cpp +++ b/libSBRenc/src/tran_det.cpp @@ -366,7 +366,7 @@ static FIXP_DBL addHighbandEnergies( accu += (EnergiesM[slotOut][j] >> scale[0]); } } - nrgTotal = accu >> (scaleEnergies[1] - scale[1]); + nrgTotal = fAddSaturate(nrgTotal, accu >> (scaleEnergies[1] - scale[1])); } return (nrgTotal); -- cgit v1.2.3