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_lib.cpp | 1501 ++++++++++++++++++++++++++-------------- 1 file changed, 980 insertions(+), 521 deletions(-) (limited to 'libMpegTPDec/src/tpdec_lib.cpp') diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 24f755b..10e3352 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 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,20 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/******************* MPEG transport format decoder library ********************* -/************************** MPEG-4 Transport Decoder ************************ + Author(s): Manuel Jander - Author(s): Manuel Jander Description: MPEG Transport decoder -******************************************************************************/ +*******************************************************************************/ #include "tpdec_lib.h" /* library version */ -#include "version" - +#include "tp_version.h" #include "tp_data.h" @@ -104,6 +115,7 @@ amm-info@iis.fraunhofer.de #include "tpdec_drm.h" +#include "FDK_crc.h" #define MODULE_NAME "transportDec" @@ -118,51 +130,70 @@ typedef union { } transportdec_parser_t; -struct TRANSPORTDEC -{ - TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */ - - CSTpCallBacks callbacks; /*!< Struct holding callback and its data */ - - FDK_BITSTREAM bitStream[2]; /* Bitstream reader */ - UCHAR *bsBuffer; /* Internal bitstreamd data buffer (unallocated in case of TT_MP4_RAWPACKETS) */ - - transportdec_parser_t parser; /* Format specific parser structs. */ - - CSAudioSpecificConfig asc[(1*2)]; /* Audio specific config from the last config found. */ - UINT globalFramePos; /* Global transport frame reference bit position. */ - UINT accessUnitAnchor[2]; /* Current access unit start bit position. */ - INT auLength[2]; /* Length of current access unit. */ - INT numberOfRawDataBlocks; /* Current number of raw data blocks contained remaining from the current transport frame. */ - UINT avgBitRate; /* Average bit rate used for frame loss estimation. */ - UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame loss estimation */ - INT remainder; /* Reminder in division during lost access unit estimation. */ - INT missingAccessUnits; /* Estimated missing access units. */ - UINT burstPeriod; /* Data burst period in mili seconds. */ - UINT holdOffFrames; /* Amount of frames that were already hold off due to buffer fullness condition not being met. */ - UINT flags; /* Flags. */ +#define MHAS_CONFIG_PRESENT 0x001 +#define MHAS_UI_PRESENT 0x002 + +struct TRANSPORTDEC { + TRANSPORT_TYPE transportFmt; /*!< MPEG4 transportDec type. */ + + CSTpCallBacks callbacks; /*!< Struct holding callback and its data */ + + FDK_BITSTREAM bitStream[1]; /* Bitstream reader */ + UCHAR *bsBuffer; /* Internal bitstreamd data buffer */ + + transportdec_parser_t parser; /* Format specific parser structs. */ + + CSAudioSpecificConfig asc[(1 * 1) + 1]; /* Audio specific config from the last + config found. One additional + CSAudioSpecificConfig is used + temporarily for parsing. */ + CCtrlCFGChange ctrlCFGChange[(1 * 1)]; /* Controls config change */ + + UINT globalFramePos; /* Global transport frame reference bit position. */ + UINT accessUnitAnchor[1]; /* Current access unit start bit position. */ + INT auLength[1]; /* Length of current access unit. */ + INT numberOfRawDataBlocks; /* Current number of raw data blocks contained + remaining from the current transport frame. */ + UINT avgBitRate; /* Average bit rate used for frame loss estimation. */ + UINT lastValidBufferFullness; /* Last valid buffer fullness value for frame + loss estimation */ + INT remainder; /* Reminder in division during lost access unit estimation. */ + INT missingAccessUnits; /* Estimated missing access units. */ + UINT burstPeriod; /* Data burst period in mili seconds. */ + UINT holdOffFrames; /* Amount of frames that were already hold off due to + buffer fullness condition not being met. */ + UINT flags; /* Flags. */ + INT targetLayout; /* CICP target layout. */ + UINT *pLoudnessInfoSetPosition; /* Reference and start position (bits) and + length (bytes) of loudnessInfoSet within + rsv603daConfig. */ }; /* Flag bitmasks for "flags" member of struct TRANSPORTDEC */ -#define TPDEC_SYNCOK 1 -#define TPDEC_MINIMIZE_DELAY 2 +#define TPDEC_SYNCOK 1 +#define TPDEC_MINIMIZE_DELAY 2 #define TPDEC_IGNORE_BUFFERFULLNESS 4 -#define TPDEC_EARLY_CONFIG 8 -#define TPDEC_LOST_FRAMES_PENDING 16 -#define TPDEC_CONFIG_FOUND 32 +#define TPDEC_EARLY_CONFIG 8 +#define TPDEC_LOST_FRAMES_PENDING 16 +#define TPDEC_CONFIG_FOUND 32 +#define TPDEC_USE_ELEM_SKIPPING 64 -C_ALLOC_MEM(Ram_TransportDecoder, TRANSPORTDEC, 1) -C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, TRANSPORTDEC_INBUF_SIZE) +/* force config/content change */ +#define TPDEC_FORCE_CONFIG_CHANGE 1 +#define TPDEC_FORCE_CONTENT_CHANGE 2 +/* skip packet */ +#define TPDEC_SKIP_PACKET 1 +C_ALLOC_MEM(Ram_TransportDecoder, struct TRANSPORTDEC, 1) +C_ALLOC_MEM(Ram_TransportDecoderBuffer, UCHAR, (8192 * 4)) - -HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const UINT flags) -{ +HANDLE_TRANSPORTDEC transportDec_Open(const TRANSPORT_TYPE transportFmt, + const UINT flags, const UINT nrOfLayers) { HANDLE_TRANSPORTDEC hInput; hInput = GetRam_TransportDecoder(0); - if ( hInput == NULL ) { + if (hInput == NULL) { return NULL; } @@ -170,106 +201,355 @@ HANDLE_TRANSPORTDEC transportDec_Open( const TRANSPORT_TYPE transportFmt, const hInput->transportFmt = transportFmt; switch (transportFmt) { + case TT_MP4_ADIF: + break; + + case TT_MP4_ADTS: + if (flags & TP_FLAG_MPEG4) + hInput->parser.adts.decoderCanDoMpeg4 = 1; + else + hInput->parser.adts.decoderCanDoMpeg4 = 0; + adtsRead_CrcInit(&hInput->parser.adts); + hInput->parser.adts.BufferFullnesStartFlag = 1; + hInput->numberOfRawDataBlocks = 0; + break; + + case TT_DRM: + drmRead_CrcInit(&hInput->parser.drm); + break; + + case TT_MP4_LATM_MCP0: + case TT_MP4_LATM_MCP1: + hInput->parser.latm.usacExplicitCfgChanged = 0; + hInput->parser.latm.applyAsc = 1; + break; + case TT_MP4_LOAS: + hInput->parser.latm.usacExplicitCfgChanged = 0; + hInput->parser.latm.applyAsc = 1; + break; + case TT_MP4_RAW: + break; - case TT_MP4_ADIF: - break; - - case TT_MP4_ADTS: - if (flags & TP_FLAG_MPEG4) - hInput->parser.adts.decoderCanDoMpeg4 = 1; - else - hInput->parser.adts.decoderCanDoMpeg4 = 0; - adtsRead_CrcInit(&hInput->parser.adts); - hInput->parser.adts.BufferFullnesStartFlag = 1; - hInput->numberOfRawDataBlocks = 0; - break; - - case TT_DRM: - drmRead_CrcInit(&hInput->parser.drm); - break; - - case TT_MP4_LATM_MCP0: - case TT_MP4_LATM_MCP1: - case TT_MP4_LOAS: - case TT_MP4_RAW: - break; - - default: - FreeRam_TransportDecoder(&hInput); - hInput = NULL; - break; + default: + FreeRam_TransportDecoder(&hInput); + hInput = NULL; + break; } if (hInput != NULL) { /* Create bitstream */ - if ( TT_IS_PACKET(transportFmt) ) { - hInput->bsBuffer = NULL; - } else { + { hInput->bsBuffer = GetRam_TransportDecoderBuffer(0); if (hInput->bsBuffer == NULL) { - transportDec_Close( &hInput ); - return NULL; + transportDec_Close(&hInput); + return NULL; + } + if (nrOfLayers > 1) { + transportDec_Close(&hInput); + return NULL; + } + for (UINT i = 0; i < nrOfLayers; i++) { + FDKinitBitStream(&hInput->bitStream[i], hInput->bsBuffer, (8192 * 4), 0, + BS_READER); } - FDKinitBitStream(&hInput->bitStream[0], hInput->bsBuffer, TRANSPORTDEC_INBUF_SIZE, 0, BS_READER); } - hInput->burstPeriod = 0; } return hInput; } -TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR *conf, const UINT length, UINT layer ) -{ - TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; +TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, + UCHAR *conf, const UINT length, + UINT layer) { + int i; - FDK_BITSTREAM bs; - HANDLE_FDK_BITSTREAM hBs = &bs; + TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; - FDKinitBitStream(hBs, conf, 0x10000000, length<<3, BS_READER); + FDK_BITSTREAM bs; + HANDLE_FDK_BITSTREAM hBs = &bs; int fConfigFound = 0; - /* config transport decoder */ - switch (hTp->transportFmt) { - case TT_MP4_LATM_MCP0: - case TT_MP4_LATM_MCP1: - case TT_MP4_LOAS: - { + UCHAR configChanged = 0; + UCHAR configMode = AC_CM_DET_CFG_CHANGE; + + UCHAR tmpConf[1024]; + if (length > 1024) { + return TRANSPORTDEC_UNSUPPORTED_FORMAT; + } + FDKmemcpy(tmpConf, conf, length); + FDKinitBitStream(hBs, tmpConf, 1024, length << 3, BS_READER); + + for (i = 0; i < 2; i++) { + if (i > 0) { + FDKpushBack(hBs, length * 8 - FDKgetValidBits(hBs)); + configMode = AC_CM_ALLOC_MEM; + } + + /* config transport decoder */ + switch (hTp->transportFmt) { + case TT_MP4_LATM_MCP0: + case TT_MP4_LATM_MCP1: + case TT_MP4_LOAS: { if (layer != 0) { return TRANSPORTDEC_INVALID_PARAMETER; } CLatmDemux *pLatmDemux = &hTp->parser.latm; - err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks, hTp->asc, &fConfigFound); + err = CLatmDemux_ReadStreamMuxConfig(hBs, pLatmDemux, &hTp->callbacks, + hTp->asc, &fConfigFound, + configMode, configChanged); if (err != TRANSPORTDEC_OK) { return err; } - } - break; - default: - fConfigFound = 1; - err = AudioSpecificConfig_Parse(&hTp->asc[layer], hBs, 1, &hTp->callbacks); - if (err == TRANSPORTDEC_OK) { + } break; + default: + fConfigFound = 1; + err = AudioSpecificConfig_Parse(&hTp->asc[(1 * 1)], hBs, 1, + &hTp->callbacks, configMode, + configChanged, AOT_NULL_OBJECT); + if (err == TRANSPORTDEC_OK) { + int errC; + + hTp->asc[layer] = hTp->asc[(1 * 1)]; + errC = hTp->callbacks.cbUpdateConfig( + hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer], + hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + break; + case TT_DRM: + fConfigFound = 1; + err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs, &hTp->callbacks, + configMode, configChanged); + if (err == TRANSPORTDEC_OK) { + int errC; + + errC = hTp->callbacks.cbUpdateConfig( + hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer], + hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + break; + } + + if (err == TRANSPORTDEC_OK) { + if ((i == 0) && (hTp->asc[layer].AacConfigChanged || + hTp->asc[layer].SbrConfigChanged || + hTp->asc[layer].SacConfigChanged)) { int errC; - errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]); + configChanged = 1; + errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData, + &hTp->asc[layer]); if (errC != 0) { err = TRANSPORTDEC_PARSE_ERROR; } } - break; - case TT_DRM: + } + } + + if (err == TRANSPORTDEC_OK && fConfigFound) { + hTp->flags |= TPDEC_CONFIG_FOUND; + } + + return err; +} + +TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp, + UCHAR *newConfig, + const UINT newConfigLength, + const UCHAR buildUpStatus, + UCHAR *configChanged, UINT layer, + UCHAR *implicitExplicitCfgDiff) { + int errC; + FDK_BITSTREAM bs; + HANDLE_FDK_BITSTREAM hBs = &bs; + TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; + int fConfigFound = 0; + UCHAR configMode = AC_CM_ALLOC_MEM; + *implicitExplicitCfgDiff = 0; + + FDK_ASSERT(hTp->asc->m_aot == AOT_USAC); + + FDKinitBitStream(hBs, newConfig, TP_USAC_MAX_CONFIG_LEN, newConfigLength << 3, + BS_READER); + + if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) && + (hTp->ctrlCFGChange[layer].buildUpStatus != + TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) { + if (hTp->asc->m_aot == AOT_USAC) { + if ((UINT)(hTp->asc->m_sc.m_usacConfig.UsacConfigBits + 7) >> 3 == + newConfigLength) { + if (0 == FDKmemcmp(newConfig, hTp->asc->m_sc.m_usacConfig.UsacConfig, + newConfigLength)) { + if (hTp->parser.latm.usacExplicitCfgChanged) { /* configChange from + LOAS/LATM parser */ + hTp->parser.latm.usacExplicitCfgChanged = 0; + hTp->ctrlCFGChange[layer].flushCnt = 0; + hTp->ctrlCFGChange[layer].flushStatus = + TPDEC_USAC_DASH_IPF_FLUSH_ON; + hTp->ctrlCFGChange[layer].buildUpCnt = 0; + hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF; + } else { + *configChanged = 0; + return err; + } + } else { + *implicitExplicitCfgDiff = 1; + } + } else { + *implicitExplicitCfgDiff = 1; + } + /* ISO/IEC 23003-3:2012/FDAM 3:2016(E) Annex F.2: explicit and implicit + * config shall be identical. */ + if (*implicitExplicitCfgDiff) { + switch (hTp->transportFmt) { + case TT_MP4_LATM_MCP0: + case TT_MP4_LATM_MCP1: + case TT_MP4_LOAS: + /* reset decoder to initial state to achieve definite behavior after + * error in config */ + hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData, + &hTp->asc[layer]); + hTp->parser.latm.usacExplicitCfgChanged = 0; + hTp->parser.latm.applyAsc = 1; + err = TRANSPORTDEC_PARSE_ERROR; + goto bail; + default: + break; + } + } + } + } + + { + if ((hTp->ctrlCFGChange[layer].flushStatus == TPDEC_FLUSH_OFF) && + (hTp->ctrlCFGChange[layer].buildUpStatus != + TPDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) { + hTp->ctrlCFGChange[layer].flushCnt = 0; + hTp->ctrlCFGChange[layer].buildUpCnt = 0; + hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF; + if (hTp->asc->m_aot == AOT_USAC) { + hTp->ctrlCFGChange[layer].flushStatus = TPDEC_USAC_DASH_IPF_FLUSH_ON; + } + } + + if ((hTp->ctrlCFGChange[layer].flushStatus == + TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) || + (hTp->ctrlCFGChange[layer].flushStatus == + TPDEC_USAC_DASH_IPF_FLUSH_ON)) { + SCHAR counter = 0; + if (hTp->asc->m_aot == AOT_USAC) { + counter = TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES; + } + if (hTp->ctrlCFGChange[layer].flushCnt >= counter) { + hTp->ctrlCFGChange[layer].flushCnt = 0; + hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF; + hTp->ctrlCFGChange[layer].forceCfgChange = 0; + if (hTp->asc->m_aot == AOT_USAC) { + hTp->ctrlCFGChange[layer].buildUpCnt = + TPDEC_USAC_NUM_CONFIG_CHANGE_FRAMES - 1; + hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_USAC_BUILD_UP_ON; + } + } + + /* Activate flush mode. After that continue with build up mode in core */ + if (hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData, + &hTp->ctrlCFGChange[layer]) != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + + if ((hTp->ctrlCFGChange[layer].flushStatus == + TPDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) || + (hTp->ctrlCFGChange[layer].flushStatus == + TPDEC_USAC_DASH_IPF_FLUSH_ON)) { + hTp->ctrlCFGChange[layer].flushCnt++; + return err; + } + } + + if (hTp->asc->m_aot == AOT_USAC) { fConfigFound = 1; - err = DrmRawSdcAudioConfig_Parse(&hTp->asc[layer], hBs); + if (err == TRANSPORTDEC_OK) { - int errC; + *configChanged = 0; + configMode = AC_CM_DET_CFG_CHANGE; - errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer]); - if (errC != 0) { - err = TRANSPORTDEC_PARSE_ERROR; + for (int i = 0; i < 2; i++) { + if (i > 0) { + FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs)); + configMode = AC_CM_ALLOC_MEM; + } + /* config transport decoder */ + err = AudioSpecificConfig_Parse( + &hTp->asc[(1 * 1)], hBs, 0, &hTp->callbacks, configMode, + *configChanged, hTp->asc[layer].m_aot); + if (err == TRANSPORTDEC_OK) { + hTp->asc[layer] = hTp->asc[(1 * 1)]; + errC = hTp->callbacks.cbUpdateConfig( + hTp->callbacks.cbUpdateConfigData, &hTp->asc[layer], + hTp->asc[layer].configMode, &hTp->asc[layer].AacConfigChanged); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + + if (err == TRANSPORTDEC_OK) { + if ((i == 0) && (hTp->asc[layer].AacConfigChanged || + hTp->asc[layer].SbrConfigChanged || + hTp->asc[layer].SacConfigChanged)) { + *configChanged = 1; + errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData, + &hTp->asc[layer]); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } + } + + /* if an error is detected terminate config parsing to avoid that an + * invalid config is accepted in the second pass */ + if (err != TRANSPORTDEC_OK) { + break; + } } } - break; + } + + bail: + /* save new config */ + if (err == TRANSPORTDEC_OK) { + if (hTp->asc->m_aot == AOT_USAC) { + hTp->asc->m_sc.m_usacConfig.UsacConfigBits = newConfigLength << 3; + FDKmemcpy(hTp->asc->m_sc.m_usacConfig.UsacConfig, newConfig, + newConfigLength); + /* in case of USAC reset transportDecoder variables here because + * otherwise without IPF they are not reset */ + hTp->ctrlCFGChange[layer].flushCnt = 0; + hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF; + hTp->ctrlCFGChange[layer].buildUpCnt = 0; + hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF; + } + } else { + hTp->numberOfRawDataBlocks = 0; + + /* If parsing error while config found, clear ctrlCFGChange-struct */ + hTp->ctrlCFGChange[layer].flushCnt = 0; + hTp->ctrlCFGChange[layer].flushStatus = TPDEC_FLUSH_OFF; + hTp->ctrlCFGChange[layer].buildUpCnt = 0; + hTp->ctrlCFGChange[layer].buildUpStatus = TPDEC_BUILD_UP_OFF; + hTp->ctrlCFGChange[layer].cfgChanged = 0; + hTp->ctrlCFGChange[layer].contentChanged = 0; + hTp->ctrlCFGChange[layer].forceCfgChange = 0; + + hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData, + &hTp->ctrlCFGChange[layer]); + } } if (err == TRANSPORTDEC_OK && fConfigFound) { @@ -279,8 +559,9 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, UCHAR * return err; } -int transportDec_RegisterAscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbUpdateConfig_t cbUpdateConfig, void* user_data) -{ +int transportDec_RegisterAscCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbUpdateConfig_t cbUpdateConfig, + void *user_data) { if (hTpDec == NULL) { return -1; } @@ -289,8 +570,30 @@ int transportDec_RegisterAscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbUpdate return 0; } -int transportDec_RegisterSscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSsc_t cbSsc, void* user_data) -{ +int transportDec_RegisterFreeMemCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbFreeMem_t cbFreeMem, + void *user_data) { + if (hTpDec == NULL) { + return -1; + } + hTpDec->callbacks.cbFreeMem = cbFreeMem; + hTpDec->callbacks.cbFreeMemData = user_data; + return 0; +} + +int transportDec_RegisterCtrlCFGChangeCallback( + HANDLE_TRANSPORTDEC hTpDec, const cbCtrlCFGChange_t cbCtrlCFGChange, + void *user_data) { + if (hTpDec == NULL) { + return -1; + } + hTpDec->callbacks.cbCtrlCFGChange = cbCtrlCFGChange; + hTpDec->callbacks.cbCtrlCFGChangeData = user_data; + return 0; +} + +int transportDec_RegisterSscCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbSsc_t cbSsc, void *user_data) { if (hTpDec == NULL) { return -1; } @@ -299,8 +602,8 @@ int transportDec_RegisterSscCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSsc_t return 0; } -int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t cbSbr, void* user_data) -{ +int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbSbr_t cbSbr, void *user_data) { if (hTpDec == NULL) { return -1; } @@ -309,65 +612,86 @@ int transportDec_RegisterSbrCallback( HANDLE_TRANSPORTDEC hTpDec, const cbSbr_t return 0; } -TRANSPORTDEC_ERROR transportDec_FillData( - const HANDLE_TRANSPORTDEC hTp, - UCHAR *pBuffer, - const UINT bufferSize, - UINT *pBytesValid, - const INT layer ) -{ - HANDLE_FDK_BITSTREAM hBs; +int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbUsac_t cbUsac, void *user_data) { + if (hTpDec == NULL) { + return -1; + } + hTpDec->callbacks.cbUsac = cbUsac; + hTpDec->callbacks.cbUsacData = user_data; + return 0; +} - if ( (hTp == NULL) - || (layer >= 2) ) { - return TRANSPORTDEC_INVALID_PARAMETER; +int transportDec_RegisterUniDrcConfigCallback(HANDLE_TRANSPORTDEC hTpDec, + const cbUniDrc_t cbUniDrc, + void *user_data, + UINT *pLoudnessInfoSetPosition) { + if (hTpDec == NULL) { + return -1; } - if (*pBytesValid == 0) { - /* nothing to do */ - return TRANSPORTDEC_OK; + hTpDec->callbacks.cbUniDrc = cbUniDrc; + hTpDec->callbacks.cbUniDrcData = user_data; + + hTpDec->pLoudnessInfoSetPosition = pLoudnessInfoSetPosition; + return 0; +} + +TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp, + UCHAR *pBuffer, const UINT bufferSize, + UINT *pBytesValid, const INT layer) { + HANDLE_FDK_BITSTREAM hBs; + + if ((hTp == NULL) || (layer >= 1)) { + return TRANSPORTDEC_INVALID_PARAMETER; } /* set bitbuffer shortcut */ hBs = &hTp->bitStream[layer]; - if ( TT_IS_PACKET(hTp->transportFmt) ) { + if (TT_IS_PACKET(hTp->transportFmt)) { if (hTp->numberOfRawDataBlocks == 0) { - /* For packet based transport, pass input buffer to bitbuffer without copying the data. - Unfortunately we do not know the actual buffer size. And the FDK bit buffer implementation - needs a number 2^x. So we assume the maximum of 48 channels with 6144 bits per channel - and round it up to the next power of 2 => 65536 bytes */ - FDKinitBitStream(hBs, pBuffer, 0x10000, (*pBytesValid)<<3, BS_READER); - *pBytesValid = 0; + FDKresetBitbuffer(hBs); + FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid); + if (*pBytesValid != 0) { + return TRANSPORTDEC_TOO_MANY_BITS; + } } } else { /* ... else feed bitbuffer with new stream data (append). */ + + if (*pBytesValid == 0) { + /* nothing to do */ + return TRANSPORTDEC_OK; + } + if (hTp->numberOfRawDataBlocks <= 0) { - FDKfeedBuffer (hBs, pBuffer, bufferSize, pBytesValid) ; + FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid); } } return TRANSPORTDEC_OK; } -HANDLE_FDK_BITSTREAM transportDec_GetBitstream( const HANDLE_TRANSPORTDEC hTp, const UINT layer ) -{ +HANDLE_FDK_BITSTREAM transportDec_GetBitstream(const HANDLE_TRANSPORTDEC hTp, + const UINT layer) { return &hTp->bitStream[layer]; } -TRANSPORT_TYPE transportDec_GetFormat( const HANDLE_TRANSPORTDEC hTp ) -{ +TRANSPORT_TYPE transportDec_GetFormat(const HANDLE_TRANSPORTDEC hTp) { return hTp->transportFmt; } -INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp ) -{ +INT transportDec_GetBufferFullness(const HANDLE_TRANSPORTDEC hTp) { INT bufferFullness = -1; switch (hTp->transportFmt) { case TT_MP4_ADTS: if (hTp->parser.adts.bs.adts_fullness != 0x7ff) { - bufferFullness = hTp->parser.adts.bs.frame_length*8 + hTp->parser.adts.bs.adts_fullness * 32 * getNumberOfEffectiveChannels(hTp->parser.adts.bs.channel_config); + bufferFullness = hTp->parser.adts.bs.frame_length * 8 + + hTp->parser.adts.bs.adts_fullness * 32 * + getNumberOfEffectiveChannels( + hTp->parser.adts.bs.channel_config); } break; case TT_MP4_LOAS: @@ -389,31 +713,37 @@ INT transportDec_GetBufferFullness( const HANDLE_TRANSPORTDEC hTp ) * \param hTp transport decoder handle. * \return error code. */ -static -TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp) -{ +static TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit( + HANDLE_TRANSPORTDEC hTp) { HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0]; TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; switch (hTp->transportFmt) { + case TT_MP4_ADIF: + /* Do byte align at the end of raw_data_block() because UsacFrame() is not + * byte aligned. */ + FDKbyteAlign(hBs, hTp->accessUnitAnchor[0]); + break; case TT_MP4_LOAS: case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP1: - if ( hTp->numberOfRawDataBlocks == 0 ) - { + if (hTp->numberOfRawDataBlocks == 0) { /* Do byte align at the end of AudioMuxElement. */ FDKbyteAlign(hBs, hTp->globalFramePos); /* Check global frame length */ - if (hTp->transportFmt == TT_MP4_LOAS && hTp->parser.latm.m_audioMuxLengthBytes > 0) - { + if (hTp->transportFmt == TT_MP4_LOAS && + hTp->parser.latm.m_audioMuxLengthBytes > 0) { int loasOffset; - loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes*8 + FDKgetValidBits(hBs)) - hTp->globalFramePos; + loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes * 8 + + FDKgetValidBits(hBs)) - + hTp->globalFramePos; if (loasOffset != 0) { FDKpushBiDirectional(hBs, loasOffset); - /* For ELD and other payloads there is an unknown amount of padding, so ignore unread bits, but - throw an error only if too many bits where read. */ + /* For ELD and other payloads there is an unknown amount of padding, + so ignore unread bits, but throw an error only if too many bits + where read. */ if (loasOffset < 0) { err = TRANSPORTDEC_PARSE_ERROR; } @@ -423,28 +753,34 @@ TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp) break; case TT_MP4_ADTS: - if (hTp->parser.adts.bs.protection_absent == 0) - { + if (hTp->parser.adts.bs.protection_absent == 0) { int offset; /* Calculate offset to end of AU */ - offset = hTp->parser.adts.rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks]<<3; - /* CAUTION: The PCE (if available) is declared to be a part of the header! */ - offset -= hTp->accessUnitAnchor[0] - FDKgetValidBits(hBs) + 16 + hTp->parser.adts.bs.num_pce_bits; + offset = hTp->parser.adts + .rawDataBlockDist[hTp->parser.adts.bs.num_raw_blocks - + hTp->numberOfRawDataBlocks] + << 3; + /* CAUTION: The PCE (if available) is declared to be a part of the + * header! */ + offset -= (INT)hTp->accessUnitAnchor[0] - (INT)FDKgetValidBits(hBs) + + 16 + hTp->parser.adts.bs.num_pce_bits; FDKpushBiDirectional(hBs, offset); } - if (hTp->parser.adts.bs.num_raw_blocks > 0 && hTp->parser.adts.bs.protection_absent == 0) { - /* Note this CRC read currently happens twice because of transportDec_CrcCheck() */ + if (hTp->parser.adts.bs.num_raw_blocks > 0 && + hTp->parser.adts.bs.protection_absent == 0) { + /* Note this CRC read currently happens twice because of + * transportDec_CrcCheck() */ hTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16); } - if ( hTp->numberOfRawDataBlocks == 0 ) - { + if (hTp->numberOfRawDataBlocks == 0) { /* Check global frame length */ - if (hTp->parser.adts.bs.protection_absent == 0) - { + if (hTp->parser.adts.bs.protection_absent == 0) { int offset; - offset = (hTp->parser.adts.bs.frame_length*8 - ADTS_SYNCLENGTH + FDKgetValidBits(hBs)) - hTp->globalFramePos; + offset = (hTp->parser.adts.bs.frame_length * 8 - ADTS_SYNCLENGTH + + (INT)FDKgetValidBits(hBs)) - + (INT)hTp->globalFramePos; if (offset != 0) { FDKpushBiDirectional(hBs, offset); } @@ -459,41 +795,39 @@ TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp) return err; } - /** - * \brief Determine additional buffer fullness contraint due to burst data reception. - * The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a precondition. + * \brief Determine additional buffer fullness contraint due to burst data + * reception. The parameter TPDEC_PARAM_BURSTPERIOD must have been set as a + * precondition. * \param hTp transport decoder handle. - * \param bufferFullness the buffer fullness value of the first frame to be decoded. - * \param bitsAvail the amount of available bits at the end of the first frame to be decoded. + * \param bufferFullness the buffer fullness value of the first frame to be + * decoded. + * \param bitsAvail the amount of available bits at the end of the first frame + * to be decoded. * \return error code */ -static -TRANSPORTDEC_ERROR additionalHoldOffNeeded( - HANDLE_TRANSPORTDEC hTp, - INT bufferFullness, - INT bitsAvail - ) -{ +static TRANSPORTDEC_ERROR additionalHoldOffNeeded(HANDLE_TRANSPORTDEC hTp, + INT bufferFullness, + INT bitsAvail) { INT checkLengthBits, avgBitsPerFrame; INT maxAU; /* maximum number of frames per Master Frame */ INT samplesPerFrame = hTp->asc->m_samplesPerFrame; INT samplingFrequency = (INT)hTp->asc->m_samplingFrequency; - if ( (hTp->avgBitRate == 0) || (hTp->burstPeriod == 0) ) { + if ((hTp->avgBitRate == 0) || (hTp->burstPeriod == 0)) { return TRANSPORTDEC_OK; } - if ( (samplesPerFrame == 0 ) || (samplingFrequency == 0) ) { + if ((samplesPerFrame == 0) || (samplingFrequency == 0)) { return TRANSPORTDEC_NOT_ENOUGH_BITS; } /* One Master Frame is sent every hTp->burstPeriod ms */ - maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame*1000 - 1); - maxAU = maxAU / (samplesPerFrame*1000); + maxAU = hTp->burstPeriod * samplingFrequency + (samplesPerFrame * 1000 - 1); + maxAU = maxAU / (samplesPerFrame * 1000); /* Subtract number of frames which were already held off. */ maxAU -= hTp->holdOffFrames; - avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency-1); + avgBitsPerFrame = hTp->avgBitRate * samplesPerFrame + (samplingFrequency - 1); avgBitsPerFrame = avgBitsPerFrame / samplingFrequency; /* Consider worst case of bufferFullness quantization. */ @@ -505,41 +839,35 @@ TRANSPORTDEC_ERROR additionalHoldOffNeeded( case TT_MP4_LATM_MCP1: bufferFullness += 31; break; - default: - break; + default: /* added to avoid compiler warning */ + break; /* added to avoid compiler warning */ } - checkLengthBits = bufferFullness + (maxAU-1)*avgBitsPerFrame; + checkLengthBits = bufferFullness + (maxAU - 1) * avgBitsPerFrame; /* Check if buffer is big enough to fullfill buffer fullness condition */ - if ( (checkLengthBits /*+headerBits*/) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) { + if ((checkLengthBits /*+headerBits*/) > (((8192 * 4) << 3) - 7)) { return TRANSPORTDEC_SYNC_ERROR; } - if ( bitsAvail < checkLengthBits ) { + if (bitsAvail < checkLengthBits) { return TRANSPORTDEC_NOT_ENOUGH_BITS; - } - else { + } else { return TRANSPORTDEC_OK; } } static TRANSPORTDEC_ERROR transportDec_readHeader( - HANDLE_TRANSPORTDEC hTp, - HANDLE_FDK_BITSTREAM hBs, - int syncLength, - int ignoreBufferFullness, - int *pRawDataBlockLength, - int *pfTraverseMoreFrames, - int *pSyncLayerFrameBits, - int *pfConfigFound, - int *pHeaderBits - ) -{ + HANDLE_TRANSPORTDEC hTp, HANDLE_FDK_BITSTREAM hBs, int syncLength, + int ignoreBufferFullness, int *pRawDataBlockLength, + int *pfTraverseMoreFrames, int *pSyncLayerFrameBits, int *pfConfigFound, + int *pHeaderBits) { TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; int rawDataBlockLength = *pRawDataBlockLength; - int fTraverseMoreFrames = (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0; - int syncLayerFrameBits = (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0; + int fTraverseMoreFrames = + (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0; + int syncLayerFrameBits = + (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0; int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0; int startPos; @@ -547,46 +875,74 @@ static TRANSPORTDEC_ERROR transportDec_readHeader( switch (hTp->transportFmt) { case TT_MP4_ADTS: - if (hTp->numberOfRawDataBlocks <= 0) - { - int errC; + if (hTp->numberOfRawDataBlocks <= 0) { + int i, errC; hTp->globalFramePos = FDKgetValidBits(hBs); - /* Parse ADTS header */ - err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness ); - if (err != TRANSPORTDEC_OK) { - if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) { - err = TRANSPORTDEC_SYNC_ERROR; + UCHAR configChanged = 0; + UCHAR configMode = AC_CM_DET_CFG_CHANGE; + + for (i = 0; i < 2; i++) { + if (i > 0) { + FDKpushBack(hBs, + (INT)hTp->globalFramePos - (INT)FDKgetValidBits(hBs)); + configMode = AC_CM_ALLOC_MEM; } - } else { - errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]); - if (errC != 0) { - if (errC == TRANSPORTDEC_NEED_TO_RESTART) { - err = TRANSPORTDEC_NEED_TO_RESTART; - goto bail; - } else { + + /* Parse ADTS header */ + err = adtsRead_DecodeHeader(&hTp->parser.adts, &hTp->asc[0], hBs, + ignoreBufferFullness); + if (err != TRANSPORTDEC_OK) { + if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) { err = TRANSPORTDEC_SYNC_ERROR; } } else { - fConfigFound = 1; - hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1; + errC = hTp->callbacks.cbUpdateConfig( + hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode, + &configChanged); + if (errC != 0) { + if (errC == TRANSPORTDEC_NEED_TO_RESTART) { + err = TRANSPORTDEC_NEED_TO_RESTART; + goto bail; + } else { + err = TRANSPORTDEC_SYNC_ERROR; + } + } else { + fConfigFound = 1; + hTp->numberOfRawDataBlocks = + hTp->parser.adts.bs.num_raw_blocks + 1; + } + } + + if (err == TRANSPORTDEC_OK) { + if ((i == 0) && configChanged) { + errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData, + &hTp->asc[0]); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } } } - } - else { - /* Reset CRC because the next bits are the beginning of a raw_data_block() */ + } else { + /* Reset CRC because the next bits are the beginning of a + * raw_data_block() */ FDKcrcReset(&hTp->parser.adts.crcInfo); hTp->parser.adts.bs.num_pce_bits = 0; } if (err == TRANSPORTDEC_OK) { hTp->numberOfRawDataBlocks--; - rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks)); + rawDataBlockLength = adtsRead_GetRawDataBlockLength( + &hTp->parser.adts, + (hTp->parser.adts.bs.num_raw_blocks - hTp->numberOfRawDataBlocks)); if (rawDataBlockLength <= 0) { /* No further frame traversal possible. */ fTraverseMoreFrames = 0; } - syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength; + syncLayerFrameBits = (hTp->parser.adts.bs.frame_length << 3) - + ((INT)startPos - (INT)FDKgetValidBits(hBs)) - + syncLength; if (syncLayerFrameBits <= 0) { err = TRANSPORTDEC_SYNC_ERROR; } @@ -595,35 +951,30 @@ static TRANSPORTDEC_ERROR transportDec_readHeader( } break; case TT_MP4_LOAS: - if (hTp->numberOfRawDataBlocks <= 0) - { + if (hTp->numberOfRawDataBlocks <= 0) { syncLayerFrameBits = FDKreadBits(hBs, 13); hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits; syncLayerFrameBits <<= 3; } case TT_MP4_LATM_MCP1: case TT_MP4_LATM_MCP0: - if (hTp->numberOfRawDataBlocks <= 0) - { + if (hTp->numberOfRawDataBlocks <= 0) { hTp->globalFramePos = FDKgetValidBits(hBs); - err = CLatmDemux_Read( - hBs, - &hTp->parser.latm, - hTp->transportFmt, - &hTp->callbacks, - hTp->asc, - &fConfigFound, - ignoreBufferFullness); + err = CLatmDemux_Read(hBs, &hTp->parser.latm, hTp->transportFmt, + &hTp->callbacks, hTp->asc, &fConfigFound, + ignoreBufferFullness); if (err != TRANSPORTDEC_OK) { - if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) { + if ((err != TRANSPORTDEC_NOT_ENOUGH_BITS) && + !TPDEC_IS_FATAL_ERROR(err)) { err = TRANSPORTDEC_SYNC_ERROR; } } else { - hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm); + hTp->numberOfRawDataBlocks = + CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm); if (hTp->transportFmt == TT_MP4_LOAS) { - syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13); + syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13); } } } else { @@ -633,17 +984,20 @@ static TRANSPORTDEC_ERROR transportDec_readHeader( } } if (err == TRANSPORTDEC_OK) { - rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm); + int layer; + rawDataBlockLength = 0; + for (layer = 0; + layer < (int)CLatmDemux_GetNrOfLayers(&hTp->parser.latm, 0); + layer += 1) { + rawDataBlockLength += + CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm, 0, layer); + } hTp->numberOfRawDataBlocks--; } else { hTp->numberOfRawDataBlocks = 0; } break; - default: - { - syncLayerFrameBits = 0; - } - break; + default: { syncLayerFrameBits = 0; } break; } bail: @@ -653,6 +1007,24 @@ bail: if (pHeaderBits != NULL) { *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs); } + + for (int i = 0; i < (1 * 1); i++) { + /* If parsing error while config found, clear ctrlCFGChange-struct */ + if (hTp->ctrlCFGChange[i].cfgChanged && err != TRANSPORTDEC_OK) { + hTp->numberOfRawDataBlocks = 0; + hTp->ctrlCFGChange[i].flushCnt = 0; + hTp->ctrlCFGChange[i].flushStatus = TPDEC_FLUSH_OFF; + hTp->ctrlCFGChange[i].buildUpCnt = 0; + hTp->ctrlCFGChange[i].buildUpStatus = TPDEC_BUILD_UP_OFF; + hTp->ctrlCFGChange[i].cfgChanged = 0; + hTp->ctrlCFGChange[i].contentChanged = 0; + hTp->ctrlCFGChange[i].forceCfgChange = 0; + + hTp->callbacks.cbCtrlCFGChange(hTp->callbacks.cbCtrlCFGChangeData, + &hTp->ctrlCFGChange[i]); + } + } + if (pfConfigFound != NULL) { *pfConfigFound = fConfigFound; } @@ -660,12 +1032,9 @@ bail: if (pfTraverseMoreFrames != NULL) { *pfTraverseMoreFrames = fTraverseMoreFrames; } - if (pSyncLayerFrameBits != NULL) { + if (pSyncLayerFrameBits != NULL) { *pSyncLayerFrameBits = syncLayerFrameBits; } - if (pfConfigFound != NULL) { - *pfConfigFound = fConfigFound; - } return err; } @@ -673,12 +1042,8 @@ bail: /* How many bits to advance for synchronization search. */ #define TPDEC_SYNCSKIP 8 -static -TRANSPORTDEC_ERROR synchronization( - HANDLE_TRANSPORTDEC hTp, - INT *pHeaderBits - ) -{ +static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, + INT *pHeaderBits) { TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK; HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0]; @@ -686,14 +1051,20 @@ TRANSPORTDEC_ERROR synchronization( INT rawDataBlockLength = 0, rawDataBlockLengthPrevious; INT totalBits; INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious; - INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1; - INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0; - INT ignoreBufferFullness = hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK); + INT numFramesTraversed = 0, fTraverseMoreFrames, + fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1; + INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, + globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0; + INT ignoreBufferFullness = + hTp->flags & + (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK); + UINT endTpFrameBitsPrevious = 0; /* Synch parameters */ - INT syncLength; /* Length of sync word in bits */ - UINT syncWord; /* Sync word to be found */ - UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one bit less) */ + INT syncLength; /* Length of sync word in bits */ + UINT syncWord; /* Sync word to be found */ + UINT syncMask; /* Mask for sync word (for adding one bit, so comprising one + bit less) */ C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1); totalBits = (INT)FDKgetValidBits(hBs); @@ -703,7 +1074,9 @@ TRANSPORTDEC_ERROR synchronization( goto bail; } - fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK); + fTraverseMoreFrames = + (hTp->flags & (TPDEC_MINIMIZE_DELAY | TPDEC_EARLY_CONFIG)) && + !(hTp->flags & TPDEC_SYNCOK); /* Set transport specific sync parameters */ switch (hTp->transportFmt) { @@ -721,12 +1094,13 @@ TRANSPORTDEC_ERROR synchronization( break; } - syncMask = (1<numberOfRawDataBlocks == 0) { /* search synchword */ - FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0); + FDK_ASSERT((bitsAvail % TPDEC_SYNCSKIP) == 0); - if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) { + if ((bitsAvail - syncLength) < TPDEC_SYNCSKIP) { err = TRANSPORTDEC_NOT_ENOUGH_BITS; headerBits = 0; } else { - synch = FDKreadBits(hBs, syncLength); - if ( !(hTp->flags & TPDEC_SYNCOK) ) { - for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) { + if (!(hTp->flags & TPDEC_SYNCOK)) { + for (; (bitsAvail - syncLength) >= TPDEC_SYNCSKIP; + bitsAvail -= TPDEC_SYNCSKIP) { if (synch == syncWord) { break; } - synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP); + synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | + FDKreadBits(hBs, TPDEC_SYNCSKIP); } } if (synch != syncWord) { @@ -770,44 +1145,40 @@ TRANSPORTDEC_ERROR synchronization( /* Parse transport header (raw data block granularity) */ - if (err == TRANSPORTDEC_OK ) - { - err = transportDec_readHeader( - hTp, - hBs, - syncLength, - ignoreBufferFullness, - &rawDataBlockLength, - &fTraverseMoreFrames, - &syncLayerFrameBits, - &fConfigFound, - &headerBits - ); + if (err == TRANSPORTDEC_OK) { + err = transportDec_readHeader(hTp, hBs, syncLength, ignoreBufferFullness, + &rawDataBlockLength, &fTraverseMoreFrames, + &syncLayerFrameBits, &fConfigFound, + &headerBits); + if (TPDEC_IS_FATAL_ERROR(err)) { + goto bail; + } } bitsAvail -= headerBits; - checkLengthBits = syncLayerFrameBits; + checkLengthBits = syncLayerFrameBits; /* Check if the whole frame would fit the bitstream buffer */ if (err == TRANSPORTDEC_OK) { - if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) { + if ((checkLengthBits + headerBits) > (((8192 * 4) << 3) - 7)) { /* We assume that the size of the transport bit buffer has been chosen to meet all system requirements, thus this condition is considered a synchronisation error. */ err = TRANSPORTDEC_SYNC_ERROR; } else { - if ( bitsAvail < checkLengthBits ) { + if (bitsAvail < checkLengthBits) { err = TRANSPORTDEC_NOT_ENOUGH_BITS; } } } if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { + /* Enforce reading of new data */ + hTp->numberOfRawDataBlocks = 0; break; } - if (err == TRANSPORTDEC_SYNC_ERROR) { int bits; @@ -816,38 +1187,39 @@ TRANSPORTDEC_ERROR synchronization( /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */ bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP; - /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */ + /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead + * next time. */ FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits); - bitsAvail += headerBits - TPDEC_SYNCSKIP - bits; headerBits = 0; } /* Frame traversal */ - if ( fTraverseMoreFrames ) - { + if (fTraverseMoreFrames) { /* Save parser context for early config discovery "rewind all frames" */ - if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY)) - { - /* ignore buffer fullness if just traversing additional frames for ECD */ + if ((hTp->flags & TPDEC_EARLY_CONFIG) && + !(hTp->flags & TPDEC_MINIMIZE_DELAY)) { + /* ignore buffer fullness if just traversing additional frames for ECD + */ ignoreBufferFullness = 1; /* Save context in order to return later */ - if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) { + if (err == TRANSPORTDEC_OK && startPosFirstFrame == -1) { startPosFirstFrame = FDKgetValidBits(hBs); numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks; globalFramePosFirstFrame = hTp->globalFramePos; rawDataBlockLengthFirstFrame = rawDataBlockLength; headerBitsFirstFrame = headerBits; errFirstFrame = err; - FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t)); + FDKmemcpy(contextFirstFrame, &hTp->parser, + sizeof(transportdec_parser_t)); } - /* Break when config was found or it is not possible anymore to find a config */ - if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) - { + /* Break when config was found or it is not possible anymore to find a + * config */ + if (startPosFirstFrame != -1 && + (fConfigFound || err != TRANSPORTDEC_OK)) { /* In case of ECD and sync error, do not rewind anywhere. */ - if (err == TRANSPORTDEC_SYNC_ERROR) - { + if (err == TRANSPORTDEC_SYNC_ERROR) { startPosFirstFrame = -1; fConfigFound = 0; numFramesTraversed = 0; @@ -858,16 +1230,18 @@ TRANSPORTDEC_ERROR synchronization( if (err == TRANSPORTDEC_OK) { FDKpushFor(hBs, rawDataBlockLength); - bitsAvail -= rawDataBlockLength; numFramesTraversed++; + endTpFrameBitsPrevious = (INT)FDKgetValidBits(hBs); /* Ignore error here itentionally. */ transportDec_AdjustEndOfAccessUnit(hTp); + endTpFrameBitsPrevious -= FDKgetValidBits(hBs); } } - } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK))); + } while (fTraverseMoreFrames || + (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK))); /* Restore context in case of ECD frame traversal */ - if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) { + if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) { FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame); FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t)); hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame; @@ -876,32 +1250,35 @@ TRANSPORTDEC_ERROR synchronization( headerBits = headerBitsFirstFrame; err = errFirstFrame; numFramesTraversed = 0; - } + } /* Additional burst data mode buffer fullness check. */ - if ( !(hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) { - err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits); + if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | + TPDEC_SYNCOK)) && + err == TRANSPORTDEC_OK) { + err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), + FDKgetValidBits(hBs) - syncLayerFrameBits); if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { hTp->holdOffFrames++; } } - + /* Rewind for retry because of not enough bits */ if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { FDKpushBack(hBs, headerBits); headerBits = 0; - } - else { + } else { /* reset hold off frame counter */ hTp->holdOffFrames = 0; } /* Return to last good frame in case of frame traversal but not ECD. */ if (numFramesTraversed > 0) { - FDKpushBack(hBs, rawDataBlockLengthPrevious); + FDKpushBack(hBs, rawDataBlockLengthPrevious + endTpFrameBitsPrevious); if (err != TRANSPORTDEC_OK) { hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious; headerBits = headerBitsPrevious; + rawDataBlockLength = rawDataBlockLengthPrevious; } err = TRANSPORTDEC_OK; } @@ -909,10 +1286,13 @@ TRANSPORTDEC_ERROR synchronization( bail: hTp->auLength[0] = rawDataBlockLength; - /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, were the bit buffer is already full, - or no new burst packet fits. Recover by advancing the bit buffer. */ - if ( (TRANSPORTDEC_NOT_ENOUGH_BITS == err) && (FDKgetValidBits(hBs) >= ((TRANSPORTDEC_INBUF_SIZE*8 - ((hTp->avgBitRate*hTp->burstPeriod)/1000)) - 7)) ) - { + /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, where the bit + buffer is already full, or no new burst packet fits. Recover by advancing + the bit buffer. */ + if ((totalBits > 0) && (TRANSPORTDEC_NOT_ENOUGH_BITS == err) && + (FDKgetValidBits(hBs) >= + (((8192 * 4) * 8 - ((hTp->avgBitRate * hTp->burstPeriod) / 1000)) - + 7))) { FDKpushFor(hBs, TPDEC_SYNCSKIP); err = TRANSPORTDEC_SYNC_ERROR; } @@ -939,16 +1319,14 @@ bail: } /** - * \brief Synchronize to stream and estimate the amount of missing access units due - * to a current synchronization error in case of constant average bit rate. + * \brief Synchronize to stream and estimate the amount of missing access units + * due to a current synchronization error in case of constant average bit rate. */ -static -TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT layer ) -{ - +static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp, + const UINT layer) { TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK; HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer]; - INT nAU = -1; + INT headerBits; INT bitDistance, bfDelta; @@ -957,16 +1335,16 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT error = synchronization(hTp, &headerBits); bitDistance -= FDKgetValidBits(hBs); - FDK_ASSERT(bitDistance >= 0); - if (error == TRANSPORTDEC_SYNC_ERROR || (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) - { + INT nAU = -1; + + if (error == TRANSPORTDEC_SYNC_ERROR || + (hTp->flags & TPDEC_LOST_FRAMES_PENDING)) { /* Check if estimating lost access units is feasible. */ - if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 && hTp->asc[0].m_samplingFrequency > 0) - { - if (error == TRANSPORTDEC_OK) - { + if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 && + hTp->asc[0].m_samplingFrequency > 0) { + if (error == TRANSPORTDEC_OK) { int aj; aj = transportDec_GetBufferFullness(hTp); @@ -978,15 +1356,15 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT /* sync was ok: last of a series of bad access units. */ hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING; /* Add up bitDistance until end of the current frame. Later we substract - this frame from the grand total, since this current successfully synchronized - frame should not be skipped of course; but it must be accounted into the - bufferfulness math. */ + this frame from the grand total, since this current successfully + synchronized frame should not be skipped of course; but it must be + accounted into the bufferfulness math. */ bitDistance += hTp->auLength[0]; } else { - if ( !(hTp->flags & TPDEC_LOST_FRAMES_PENDING) ) { + if (!(hTp->flags & TPDEC_LOST_FRAMES_PENDING)) { /* sync not ok: one of many bad access units. */ hTp->flags |= TPDEC_LOST_FRAMES_PENDING; - bfDelta = - (INT)hTp->lastValidBufferFullness; + bfDelta = -(INT)hTp->lastValidBufferFullness; } else { bfDelta = 0; } @@ -996,7 +1374,8 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT int num, denom; /* Obtain estimate of number of lost frames */ - num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder; + num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + + hTp->remainder; denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame; if (num > 0) { nAU = num / denom; @@ -1005,23 +1384,20 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT hTp->remainder = num; } - if (error == TRANSPORTDEC_OK) - { - /* Final adjustment of remainder, taken -1 into account because current - frame should not be skipped, thus substract -1 or do nothing instead - of +1-1 accordingly. */ - if ( (denom - hTp->remainder) >= hTp->remainder ) { + if (error == TRANSPORTDEC_OK) { + /* Final adjustment of remainder, taken -1 into account because + current frame should not be skipped, thus substract -1 or do + nothing instead of +1-1 accordingly. */ + if ((denom - hTp->remainder) >= hTp->remainder) { nAU--; } - + if (nAU < 0) { - /* There was one frame too much concealed, so unfortunately we will have to skip one good frame. */ + /* There was one frame too much concealed, so unfortunately we will + * have to skip one good frame. */ transportDec_EndAccessUnit(hTp); - error = synchronization(hTp, &headerBits); + error = synchronization(hTp, &headerBits); nAU = -1; -#ifdef DEBUG - FDKprintf("ERROR: Bufferfullness accounting failed. remainder=%d, nAU=%d\n", hTp->remainder, nAU); -#endif } hTp->remainder = 0; /* Enforce last missed frames to be concealed. */ @@ -1033,9 +1409,10 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT } } - /* Be sure that lost frames are handled correctly. This is necessary due to some - sync error sequences where later it turns out that there is not enough data, but - the bits upto the sync word are discarded, thus causing a value of nAU > 0 */ + /* Be sure that lost frames are handled correctly. This is necessary due to + some sync error sequences where later it turns out that there is not enough + data, but the bits upto the sync word are discarded, thus causing a value + of nAU > 0 */ if (nAU > 0) { error = TRANSPORTDEC_SYNC_ERROR; } @@ -1046,8 +1423,8 @@ TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT } /* returns error code */ -TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, const UINT layer ) -{ +TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp, + const UINT layer) { TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; HANDLE_FDK_BITSTREAM hBs; @@ -1058,41 +1435,66 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c hBs = &hTp->bitStream[layer]; if ((INT)FDKgetValidBits(hBs) <= 0) { + /* This is only relevant for RAW and ADIF cases. + * For streaming formats err will get overwritten. */ err = TRANSPORTDEC_NOT_ENOUGH_BITS; + hTp->numberOfRawDataBlocks = 0; } switch (hTp->transportFmt) { - case TT_MP4_ADIF: /* Read header if not already done */ - if (!(hTp->flags & TPDEC_CONFIG_FOUND)) - { + if (!(hTp->flags & TPDEC_CONFIG_FOUND)) { + int i; CProgramConfig *pce; + INT bsStart = FDKgetValidBits(hBs); + UCHAR configChanged = 0; + UCHAR configMode = AC_CM_DET_CFG_CHANGE; + + for (i = 0; i < 2; i++) { + if (i > 0) { + FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs)); + configMode = AC_CM_ALLOC_MEM; + } - AudioSpecificConfig_Init(&hTp->asc[0]); - pce = &hTp->asc[0].m_progrConfigElement; - err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs); - if (err) - goto bail; - - /* Map adif header to ASC */ - hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1); - hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex; - hTp->asc[0].m_samplingFrequency = SamplingRateTable[pce->SamplingFrequencyIndex]; - hTp->asc[0].m_channelConfiguration = 0; - hTp->asc[0].m_samplesPerFrame = 1024; - hTp->avgBitRate = hTp->parser.adif.BitRate; - - /* Call callback to decoder. */ - { - int errC; + AudioSpecificConfig_Init(&hTp->asc[0]); + pce = &hTp->asc[0].m_progrConfigElement; + err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs); + if (err) goto bail; + + /* Map adif header to ASC */ + hTp->asc[0].m_aot = (AUDIO_OBJECT_TYPE)(pce->Profile + 1); + hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex; + hTp->asc[0].m_samplingFrequency = + SamplingRateTable[pce->SamplingFrequencyIndex]; + hTp->asc[0].m_channelConfiguration = 0; + hTp->asc[0].m_samplesPerFrame = 1024; + hTp->avgBitRate = hTp->parser.adif.BitRate; + + /* Call callback to decoder. */ + { + int errC; - errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]); - if (errC == 0) { - hTp->flags |= TPDEC_CONFIG_FOUND; - } else { - err = TRANSPORTDEC_PARSE_ERROR; - goto bail; + errC = hTp->callbacks.cbUpdateConfig( + hTp->callbacks.cbUpdateConfigData, &hTp->asc[0], configMode, + &configChanged); + if (errC == 0) { + hTp->flags |= TPDEC_CONFIG_FOUND; + } else { + err = TRANSPORTDEC_PARSE_ERROR; + goto bail; + } + } + + if (err == TRANSPORTDEC_OK) { + if ((i == 0) && configChanged) { + int errC; + errC = hTp->callbacks.cbFreeMem(hTp->callbacks.cbFreeMemData, + &hTp->asc[0]); + if (errC != 0) { + err = TRANSPORTDEC_PARSE_ERROR; + } + } } } } @@ -1109,9 +1511,10 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, c case TT_MP4_LATM_MCP0: case TT_MP4_LATM_MCP1: - { + if (err == TRANSPORTDEC_OK) { int fConfigFound = hTp->flags & TPDEC_CONFIG_FOUND; - err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer], NULL, NULL, &fConfigFound, NULL); + err = transportDec_readHeader(hTp, hBs, 0, 1, &hTp->auLength[layer], + NULL, NULL, &fConfigFound, NULL); if (fConfigFound) { hTp->flags |= TPDEC_CONFIG_FOUND; } @@ -1138,12 +1541,29 @@ bail: return err; } -INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer ) -{ +TRANSPORTDEC_ERROR transportDec_GetAsc(const HANDLE_TRANSPORTDEC hTp, + const UINT layer, + CSAudioSpecificConfig *asc) { + TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; + + if (hTp != NULL) { + *asc = hTp->asc[layer]; + err = TRANSPORTDEC_OK; + } else { + err = TRANSPORTDEC_INVALID_PARAMETER; + } + return err; +} + +INT transportDec_GetAuBitsRemaining(const HANDLE_TRANSPORTDEC hTp, + const UINT layer) { INT bits; if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) { - bits = hTp->auLength[layer] - (hTp->accessUnitAnchor[layer] - FDKgetValidBits(&hTp->bitStream[layer])); + bits = (INT)FDKgetValidBits(&hTp->bitStream[layer]); + if (bits >= 0) { + bits = hTp->auLength[layer] - ((INT)hTp->accessUnitAnchor[layer] - bits); + } } else { bits = FDKgetValidBits(&hTp->bitStream[layer]); } @@ -1151,23 +1571,55 @@ INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT l return bits; } -INT transportDec_GetAuBitsTotal( const HANDLE_TRANSPORTDEC hTp, const UINT layer ) -{ +INT transportDec_GetAuBitsTotal(const HANDLE_TRANSPORTDEC hTp, + const UINT layer) { return hTp->auLength[layer]; } -TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount ( INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp ) -{ +TRANSPORTDEC_ERROR transportDec_GetMissingAccessUnitCount( + INT *pNAccessUnits, HANDLE_TRANSPORTDEC hTp) { *pNAccessUnits = hTp->missingAccessUnits; return TRANSPORTDEC_OK; } /* Inform the transportDec layer that reading of access unit has finished. */ -TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) -{ +TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) { TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK; + switch (hTp->transportFmt) { + case TT_MP4_LOAS: + case TT_MP4_LATM_MCP0: + case TT_MP4_LATM_MCP1: { + HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0]; + if (hTp->numberOfRawDataBlocks == 0) { + /* Read other data if available. */ + if (CLatmDemux_GetOtherDataPresentFlag(&hTp->parser.latm)) { + int otherDataLen = CLatmDemux_GetOtherDataLength(&hTp->parser.latm); + + if ((INT)FDKgetValidBits(hBs) >= otherDataLen) { + FDKpushFor(hBs, otherDataLen); + } else { + /* Do byte align at the end of AudioMuxElement. */ + if (hTp->numberOfRawDataBlocks == 0) { + FDKbyteAlign(hBs, hTp->globalFramePos); + } + return TRANSPORTDEC_NOT_ENOUGH_BITS; + } + } + } else { + /* If bit buffer has not more bits but hTp->numberOfRawDataBlocks > 0 + then too many bits were read and obviously no more RawDataBlocks can + be read. Set numberOfRawDataBlocks to zero to attempt a new sync + attempt. */ + if ((INT)FDKgetValidBits(hBs) <= 0) { + hTp->numberOfRawDataBlocks = 0; + } + } + } break; + default: + break; + } err = transportDec_AdjustEndOfAccessUnit(hTp); @@ -1179,12 +1631,15 @@ TRANSPORTDEC_ERROR transportDec_EndAccessUnit(HANDLE_TRANSPORTDEC hTp) return err; } -TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp, - const TPDEC_PARAM param, - const INT value) -{ +TRANSPORTDEC_ERROR transportDec_SetParam(const HANDLE_TRANSPORTDEC hTp, + const TPDEC_PARAM param, + const INT value) { TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK; + if (hTp == NULL) { + return TRANSPORTDEC_INVALID_PARAMETER; + } + switch (param) { case TPDEC_PARAM_MINIMIZE_DELAY: if (value) { @@ -1213,25 +1668,36 @@ TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp, case TPDEC_PARAM_BURST_PERIOD: hTp->burstPeriod = value; break; - case TPDEC_PARAM_RESET: - { - int i; + case TPDEC_PARAM_RESET: { + int i; - for (i=0; i<(1*2); i++) { - FDKresetBitbuffer(&hTp->bitStream[i]); - hTp->auLength[i] = 0; - hTp->accessUnitAnchor[i] = 0; - } - hTp->flags &= ~(TPDEC_SYNCOK|TPDEC_LOST_FRAMES_PENDING); - if (hTp->transportFmt != TT_MP4_ADIF) { - hTp->flags &= ~TPDEC_CONFIG_FOUND; - } - hTp->remainder = 0; - hTp->avgBitRate = 0; - hTp->missingAccessUnits = 0; - hTp->numberOfRawDataBlocks = 0; - hTp->globalFramePos = 0; - hTp->holdOffFrames = 0; + for (i = 0; i < (1 * 1); i++) { + FDKresetBitbuffer(&hTp->bitStream[i]); + hTp->auLength[i] = 0; + hTp->accessUnitAnchor[i] = 0; + } + hTp->flags &= ~(TPDEC_SYNCOK | TPDEC_LOST_FRAMES_PENDING); + if (hTp->transportFmt != TT_MP4_ADIF) { + hTp->flags &= ~TPDEC_CONFIG_FOUND; + } + hTp->remainder = 0; + hTp->avgBitRate = 0; + hTp->missingAccessUnits = 0; + hTp->numberOfRawDataBlocks = 0; + hTp->globalFramePos = 0; + hTp->holdOffFrames = 0; + } break; + case TPDEC_PARAM_TARGETLAYOUT: + hTp->targetLayout = value; + break; + case TPDEC_PARAM_FORCE_CONFIG_CHANGE: + hTp->ctrlCFGChange[value].forceCfgChange = TPDEC_FORCE_CONFIG_CHANGE; + break; + case TPDEC_PARAM_USE_ELEM_SKIPPING: + if (value) { + hTp->flags |= TPDEC_USE_ELEM_SKIPPING; + } else { + hTp->flags &= ~TPDEC_USE_ELEM_SKIPPING; } break; } @@ -1239,38 +1705,30 @@ TRANSPORTDEC_ERROR transportDec_SetParam ( const HANDLE_TRANSPORTDEC hTp, return error; } -UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) -{ +UINT transportDec_GetNrOfSubFrames(HANDLE_TRANSPORTDEC hTp) { UINT nSubFrames = 0; - if (hTp == NULL) - return 0; + if (hTp == NULL) return 0; - if (hTp->transportFmt==TT_MP4_LATM_MCP1 || hTp->transportFmt==TT_MP4_LATM_MCP0 || hTp->transportFmt==TT_MP4_LOAS) + if (hTp->transportFmt == TT_MP4_LATM_MCP1 || + hTp->transportFmt == TT_MP4_LATM_MCP0 || hTp->transportFmt == TT_MP4_LOAS) nSubFrames = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm); - else if (hTp->transportFmt==TT_MP4_ADTS) + else if (hTp->transportFmt == TT_MP4_ADTS) nSubFrames = hTp->parser.adts.bs.num_raw_blocks; return nSubFrames; } -void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) -{ - if (phTp != NULL) - { +void transportDec_Close(HANDLE_TRANSPORTDEC *phTp) { + if (phTp != NULL) { if (*phTp != NULL) { - if ( ! TT_IS_PACKET((*phTp)->transportFmt) ) { - FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer); - } - if (*phTp != NULL) { - FreeRam_TransportDecoder(phTp); - } + FreeRam_TransportDecoderBuffer(&(*phTp)->bsBuffer); + FreeRam_TransportDecoder(phTp); } } } -TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ) -{ +TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) { int i; if (info == NULL) { @@ -1284,7 +1742,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ) if (i == FDK_MODULE_LAST) return TRANSPORTDEC_UNKOWN_ERROR; info += i; - info->module_id = FDK_TPDEC; + info->module_id = FDK_TPDEC; #ifdef __ANDROID__ info->build_date = ""; info->build_time = ""; @@ -1292,63 +1750,64 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo( LIB_INFO *info ) info->build_date = __DATE__; info->build_time = __TIME__; #endif - info->title = TP_LIB_TITLE; - info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); + info->title = TP_LIB_TITLE; + info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); LIB_VERSION_STRING(info); - info->flags = 0 - | CAPF_ADIF - | CAPF_ADTS - | CAPF_LATM - | CAPF_LOAS - | CAPF_RAWPACKETS - | CAPF_DRM - ; + info->flags = 0 | CAPF_ADIF | CAPF_ADTS | CAPF_LATM | CAPF_LOAS | + CAPF_RAWPACKETS | CAPF_DRM; return TRANSPORTDEC_OK; /* FDKERR_NOERROR; */ } - -int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) -{ +int transportDec_CrcStartReg(HANDLE_TRANSPORTDEC pTp, INT mBits) { switch (pTp->transportFmt) { - case TT_MP4_ADTS: - return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits); - case TT_DRM: - return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits); - default: - return 0; + case TT_MP4_ADTS: + return adtsRead_CrcStartReg(&pTp->parser.adts, &pTp->bitStream[0], mBits); + case TT_DRM: + return drmRead_CrcStartReg(&pTp->parser.drm, &pTp->bitStream[0], mBits); + default: + return -1; } } -void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) -{ +void transportDec_CrcEndReg(HANDLE_TRANSPORTDEC pTp, INT reg) { switch (pTp->transportFmt) { - case TT_MP4_ADTS: - adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg); - break; - case TT_DRM: - drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg); - break; - default: - break; + case TT_MP4_ADTS: + adtsRead_CrcEndReg(&pTp->parser.adts, &pTp->bitStream[0], reg); + break; + case TT_DRM: + drmRead_CrcEndReg(&pTp->parser.drm, &pTp->bitStream[0], reg); + break; + default: + break; } } -TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) -{ +TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp) { switch (pTp->transportFmt) { - case TT_MP4_ADTS: - if ( (pTp->parser.adts.bs.num_raw_blocks > 0) && (pTp->parser.adts.bs.protection_absent == 0) ) - { - HANDLE_FDK_BITSTREAM hBs = &pTp->bitStream[0]; - - transportDec_AdjustEndOfAccessUnit(pTp); - } - return adtsRead_CrcCheck(&pTp->parser.adts); - case TT_DRM: - return drmRead_CrcCheck(&pTp->parser.drm); - break; - default: - return TRANSPORTDEC_OK; + case TT_MP4_ADTS: + if ((pTp->parser.adts.bs.num_raw_blocks > 0) && + (pTp->parser.adts.bs.protection_absent == 0)) { + transportDec_AdjustEndOfAccessUnit(pTp); + } + return adtsRead_CrcCheck(&pTp->parser.adts); + case TT_DRM: + return drmRead_CrcCheck(&pTp->parser.drm); + default: + return TRANSPORTDEC_OK; } } + +TRANSPORTDEC_ERROR transportDec_DrmRawSdcAudioConfig_Check(UCHAR *conf, + const UINT length) { + CSAudioSpecificConfig asc; + FDK_BITSTREAM bs; + HANDLE_FDK_BITSTREAM hBs = &bs; + + FDKinitBitStream(hBs, conf, BUFSIZE_DUMMY_VALUE, length << 3, BS_READER); + + TRANSPORTDEC_ERROR err = + DrmRawSdcAudioConfig_Parse(&asc, hBs, NULL, (UCHAR)AC_CM_ALLOC_MEM, 0); + + return err; +} -- 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_lib.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 From 44ac411683e7cfbfdb1f58e02d54377d709c8dd4 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 9 May 2018 13:32:45 +0200 Subject: FDK patches: fix overflows in decoder out-of-band config 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 Unsigned Integer Overflows in CDataStreamElement_Read() Change-Id: Ic2f5b3ae111bf984d4d0db664823798957b0a979 Unsigned Integer Overflow in CProgramConfig_ReadHeightExt() Change-Id: Iaebc458bb59504203e604a28ed6d5cecaa875c42 Unsigned Integer Overflow in transportDec_OutOfBandConfig() Change-Id: I24a4b32d736f28c55147f0e2ca06fe5537da19c2 Unsigned Integer Overflows in CDKcrcEndReg() & crcCalc() Change-Id: I6ebbe541a4d3b6bacbd5ace17264972951de7ca8 Unsigned Integer Overflows in ReadPsData() Change-Id: Id36576fe545236860a06f17971494ecd4484c494 Unsigned Integer Overflow in SpatialDecParseSpecificConfig() Change-Id: Ib468f129a951c69776b88468407f008ab4cfd2c7 Unsigned Integer Overflows in _readUniDrcConfigExtension() & _readLoudnessInfoSetExtension() Change-Id: Ibcf7c6a23af49239206ea9301c58adac36e3ceba --- libAACdec/src/aacdecoder.cpp | 12 ++++++------ libDRCdec/src/drcDec_reader.cpp | 14 ++++++++------ libFDK/include/FDK_crc.h | 4 ++-- libFDK/src/FDK_crc.cpp | 10 +++++----- libMpegTPDec/src/tpdec_asc.cpp | 4 ++-- libMpegTPDec/src/tpdec_lib.cpp | 2 +- libSACdec/src/sac_bitdec.cpp | 4 ++-- libSBRdec/src/psbitdec.cpp | 4 ++-- 8 files changed, 28 insertions(+), 26 deletions(-) (limited to 'libMpegTPDec/src/tpdec_lib.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 64adb56..3cbdffd 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -437,7 +437,8 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self, UCHAR *elementInstanceTag, UINT alignmentAnchor) { AAC_DECODER_ERROR error = AAC_DEC_OK; - UINT dataStart, dseBits; + UINT dseBits; + INT dataStart; int dataByteAlignFlag, count; FDK_ASSERT(self != NULL); @@ -460,14 +461,14 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self, FDKbyteAlign(bs, alignmentAnchor); } - dataStart = FDKgetValidBits(bs); + dataStart = (INT)FDKgetValidBits(bs); error = CAacDecoder_AncDataParse(&self->ancData, bs, count); transportDec_CrcEndReg(self->hInput, crcReg); { /* Move to the beginning of the data chunk */ - FDKpushBack(bs, dataStart - FDKgetValidBits(bs)); + FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs)); /* Read Anc data if available */ aacDecoder_drcMarkPayload(self->hDrcInfo, bs, DVB_DRC_ANC_DATA); @@ -477,7 +478,7 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self, PCMDMX_ERROR dmxErr = PCMDMX_OK; /* Move to the beginning of the data chunk */ - FDKpushBack(bs, dataStart - FDKgetValidBits(bs)); + FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs)); /* Read DMX meta-data */ dmxErr = pcmDmx_Parse(self->hPcmUtils, bs, dseBits, 0 /* not mpeg2 */); @@ -487,8 +488,7 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self, } /* Move to the very end of the element. */ - FDKpushBiDirectional( - bs, (INT)FDKgetValidBits(bs) - (INT)dataStart + (INT)dseBits); + FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - dataStart + (INT)dseBits); return error; } diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp index db5fab7..6fe7a04 100644 --- a/libDRCdec/src/drcDec_reader.cpp +++ b/libDRCdec/src/drcDec_reader.cpp @@ -1622,7 +1622,7 @@ static DRC_ERROR _readUniDrcConfigExtension( HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) { DRC_ERROR err = DE_OK; int k, bitSizeLen, extSizeBits, bitSize; - UINT nBitsRemaining; + INT nBitsRemaining; UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt); k = 0; @@ -1634,13 +1634,14 @@ static DRC_ERROR _readUniDrcConfigExtension( bitSize = FDKreadBits(hBs, extSizeBits); pExt->extBitSize[k] = bitSize + 1; - nBitsRemaining = FDKgetValidBits(hBs); + nBitsRemaining = (INT)FDKgetValidBits(hBs); switch (pExt->uniDrcConfigExtType[k]) { case UNIDRCCONFEXT_V1: err = _readDrcExtensionV1(hBs, hUniDrcConfig); if (err) return err; - if (nBitsRemaining != (pExt->extBitSize[k] + FDKgetValidBits(hBs))) + if (nBitsRemaining != + ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs))) return DE_NOT_OK; break; case UNIDRCCONFEXT_PARAM_DRC: @@ -1940,7 +1941,7 @@ static DRC_ERROR _readLoudnessInfoSetExtension( HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) { DRC_ERROR err = DE_OK; int k, bitSizeLen, extSizeBits, bitSize; - UINT nBitsRemaining; + INT nBitsRemaining; LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt); k = 0; @@ -1952,13 +1953,14 @@ static DRC_ERROR _readLoudnessInfoSetExtension( bitSize = FDKreadBits(hBs, extSizeBits); pExt->extBitSize[k] = bitSize + 1; - nBitsRemaining = FDKgetValidBits(hBs); + nBitsRemaining = (INT)FDKgetValidBits(hBs); switch (pExt->loudnessInfoSetExtType[k]) { case UNIDRCLOUDEXT_EQ: err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet); if (err) return err; - if (nBitsRemaining != (pExt->extBitSize[k] + FDKgetValidBits(hBs))) + if (nBitsRemaining != + ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs))) return DE_NOT_OK; break; /* add future extensions here */ diff --git a/libFDK/include/FDK_crc.h b/libFDK/include/FDK_crc.h index 17439ab..6c7040c 100644 --- a/libFDK/include/FDK_crc.h +++ b/libFDK/include/FDK_crc.h @@ -115,8 +115,8 @@ amm-info@iis.fraunhofer.de typedef struct { UCHAR isActive; INT maxBits; - UINT bitBufCntBits; - UINT validBits; + INT bitBufCntBits; + INT validBits; } CCrcRegData; diff --git a/libFDK/src/FDK_crc.cpp b/libFDK/src/FDK_crc.cpp index 39f87d3..e208338 100644 --- a/libFDK/src/FDK_crc.cpp +++ b/libFDK/src/FDK_crc.cpp @@ -281,7 +281,7 @@ INT FDKcrcStartReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs, FDK_ASSERT(hCrcInfo->crcRegData[reg].isActive == 0); hCrcInfo->crcRegData[reg].isActive = 1; hCrcInfo->crcRegData[reg].maxBits = mBits; - hCrcInfo->crcRegData[reg].validBits = FDKgetValidBits(hBs); + hCrcInfo->crcRegData[reg].validBits = (INT)FDKgetValidBits(hBs); hCrcInfo->crcRegData[reg].bitBufCntBits = 0; hCrcInfo->regStart = (hCrcInfo->regStart + 1) % MAX_CRC_REGS; @@ -296,10 +296,10 @@ INT FDKcrcEndReg(HANDLE_FDK_CRCINFO hCrcInfo, const HANDLE_FDK_BITSTREAM hBs, if (hBs->ConfigCache == BS_WRITER) { hCrcInfo->crcRegData[reg].bitBufCntBits = - FDKgetValidBits(hBs) - hCrcInfo->crcRegData[reg].validBits; + (INT)FDKgetValidBits(hBs) - hCrcInfo->crcRegData[reg].validBits; } else { hCrcInfo->crcRegData[reg].bitBufCntBits = - hCrcInfo->crcRegData[reg].validBits - FDKgetValidBits(hBs); + hCrcInfo->crcRegData[reg].validBits - (INT)FDKgetValidBits(hBs); } if (hCrcInfo->crcRegData[reg].maxBits == 0) { @@ -432,7 +432,7 @@ static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs, if (hBs->ConfigCache == BS_READER) { bsReader = *hBs; FDKpushBiDirectional(&bsReader, - -(INT)(rD->validBits - FDKgetValidBits(&bsReader))); + -(rD->validBits - (INT)FDKgetValidBits(&bsReader))); } else { FDKinitBitStream(&bsReader, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, hBs->hBitBuf.ValidBits, BS_READER); @@ -441,7 +441,7 @@ static void crcCalc(HANDLE_FDK_CRCINFO hCrcInfo, HANDLE_FDK_BITSTREAM hBs, int bits, rBits; rBits = (rD->maxBits >= 0) ? rD->maxBits : -rD->maxBits; /* ramaining bits */ - if ((rD->maxBits > 0) && (((INT)rD->bitBufCntBits >> 3 << 3) < rBits)) { + if ((rD->maxBits > 0) && ((rD->bitBufCntBits >> 3 << 3) < rBits)) { bits = rD->bitBufCntBits; } else { bits = rBits; diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index 74beaa6..b7fd2a1 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -257,11 +257,11 @@ static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce, } } else { /* No valid extension data found -> restore the initial bitbuffer state */ - FDKpushBack(bs, startAnchor - FDKgetValidBits(bs)); + FDKpushBack(bs, (INT)startAnchor - (INT)FDKgetValidBits(bs)); } /* Always report the bytes read. */ - *bytesAvailable -= (startAnchor - FDKgetValidBits(bs)) >> 3; + *bytesAvailable -= ((INT)startAnchor - (INT)FDKgetValidBits(bs)) >> 3; return (err); } diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 306bec0..5eeb7fc 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -283,7 +283,7 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, for (i = 0; i < 2; i++) { if (i > 0) { - FDKpushBack(hBs, length * 8 - FDKgetValidBits(hBs)); + FDKpushBack(hBs, (INT)length * 8 - (INT)FDKgetValidBits(hBs)); configMode = AC_CM_ALLOC_MEM; } diff --git a/libSACdec/src/sac_bitdec.cpp b/libSACdec/src/sac_bitdec.cpp index b2f3b7c..37e0cf2 100644 --- a/libSACdec/src/sac_bitdec.cpp +++ b/libSACdec/src/sac_bitdec.cpp @@ -566,7 +566,7 @@ SACDEC_ERROR SpatialDecParseSpecificConfig( with respect to the beginning of the syntactic element in which ByteAlign() occurs. */ - numHeaderBits = cfgStartPos - FDKgetValidBits(bitstream); + numHeaderBits = cfgStartPos - (INT)FDKgetValidBits(bitstream); bitsAvailable -= numHeaderBits; pSpatialSpecificConfig->sacExtCnt = 0; @@ -594,7 +594,7 @@ bail: bitbuffer is exactly at its end when leaving the function. */ FDKpushBiDirectional( bitstream, - (sacHeaderLen * 8) - (cfgStartPos - FDKgetValidBits(bitstream))); + (sacHeaderLen * 8) - (cfgStartPos - (INT)FDKgetValidBits(bitstream))); } return err; diff --git a/libSBRdec/src/psbitdec.cpp b/libSBRdec/src/psbitdec.cpp index b2ea2e9..1521178 100644 --- a/libSBRdec/src/psbitdec.cpp +++ b/libSBRdec/src/psbitdec.cpp @@ -496,7 +496,7 @@ unsigned int ReadPsData( /* no useful PS data could be read from bitstream */ h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_none; /* discard all remaining bits */ - nBitsLeft -= startbits - FDKgetValidBits(hBitBuf); + nBitsLeft -= startbits - (INT)FDKgetValidBits(hBitBuf); while (nBitsLeft > 0) { int i = nBitsLeft; if (i > 8) { @@ -505,7 +505,7 @@ unsigned int ReadPsData( FDKreadBits(hBitBuf, i); nBitsLeft -= i; } - return (startbits - FDKgetValidBits(hBitBuf)); + return (UINT)(startbits - (INT)FDKgetValidBits(hBitBuf)); } if (pBsData->modeIid > 2) { -- cgit v1.2.3 From a4d1f0ad52e2cf6f168d2193216602f52033fc27 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 23 May 2018 18:26:27 +0200 Subject: FDKv2 ubsan patches Bug: 80053205 Test: see bug for repro with FB "wow" atest DecoderTestAacDrc Fix signed integer overflows in CLpc_SynthesisLattice() Change-Id: Icbddfcc8c5fc73382ae5bf8c2a7703802c688e06 Fix signed integer overflows in imlt Change-Id: I687834fca2f1aab6210ed9862576b4f38fcdeb24 Fix overflow in addLowbandEnergies() Change-Id: Iaa9fdf9deb49c33ec6ca7ed3081c4ddaa920e9aa Concealment fix for audio frames containing acelp components Change-Id: Ibe5e83a6efa75a48f729984a161a76b826878f4e Fix out-of-bounds access in PS concealment Change-Id: I08809a03a40d1feaf00e41278db314d67e1efe88 Fix potential memory leak in setup of qmf domain Change-Id: Id9fc2448354dc7f1b439469128407305efa3def2 Reject channel config 13 Change-Id: Idf5236f6cd054df994e69c9c972c97f6768cf9e5 Fix unsigned integer overflow in configExtension() Change-Id: I8a1668810b85e6237c3892891444ff08f04b019b Fix unsigned integer overflow in CAacDecoder_DecodeFrame() Change-Id: I79678c571690178e6c37680f70a9b94dd3cbc439 Fix unsigned integer overflow in aacDecoder_UpdateBitStreamCounters() Change-Id: I3bff959da9f53fabb18cd0ae6c260e6256194526 Fix unsigned integer overflow in transportDec_readStream() Change-Id: I6a6f9f4acaa32fae0b5de9641f8787bbc7f8286b --- libAACdec/src/aacdecoder.cpp | 7 +-- libAACdec/src/aacdecoder_lib.cpp | 6 +-- libAACdec/src/conceal.cpp | 4 +- libAACdec/src/usacdec_acelp.cpp | 11 ++++- libAACdec/src/usacdec_acelp.h | 3 +- libAACdec/src/usacdec_lpd.cpp | 2 +- libFDK/include/cplx_mul.h | 20 --------- libFDK/include/mdct.h | 1 + libFDK/src/FDK_lpc.cpp | 15 +++++-- libFDK/src/FDK_qmf_domain.cpp | 97 +++++++++++++++++++++++++++------------- libFDK/src/mdct.cpp | 74 +++++++++++------------------- libMpegTPDec/src/tpdec_asc.cpp | 4 +- libMpegTPDec/src/tpdec_lib.cpp | 6 +-- libSBRdec/src/psbitdec.cpp | 4 ++ libSBRdec/src/psdec.h | 4 +- libSBRenc/src/tran_det.cpp | 18 ++++++-- 16 files changed, 150 insertions(+), 126 deletions(-) (limited to 'libMpegTPDec/src/tpdec_lib.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 3cbdffd..b8b1327 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1589,9 +1589,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, case 14: ascChannels = 8; break; - case 13: /* 22.2 setup */ - ascChannels = 24; - break; default: return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; } @@ -2837,7 +2834,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* usacExtElementStop = 1; */ } - usacExtBitPos = FDKgetValidBits(bs); + usacExtBitPos = (INT)FDKgetValidBits(bs); USAC_EXT_ELEMENT_TYPE usacExtElementType = self->pUsacConfig[streamIndex] @@ -2862,7 +2859,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* Skip any remaining bits of extension payload */ usacExtBitPos = (usacExtElementPayloadLength * 8) - - (usacExtBitPos - FDKgetValidBits(bs)); + (usacExtBitPos - (INT)FDKgetValidBits(bs)); if (usacExtBitPos < 0) { self->frameOK = 0; ErrorStatus = AAC_DEC_PARSE_ERROR; diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index e62d187..cd112b6 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1082,15 +1082,15 @@ static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi, /* bit/byte counters */ { - int nBytes; + INT nBytes; nBytes = nBits >> 3; - pSi->numTotalBytes += nBytes; + pSi->numTotalBytes = (UINT)((INT)pSi->numTotalBytes + nBytes); if (IS_OUTPUT_VALID(ErrorStatus)) { pSi->numTotalAccessUnits++; } if (IS_DECODE_ERROR(ErrorStatus)) { - pSi->numBadBytes += nBytes; + pSi->numBadBytes = (UINT)((INT)pSi->numBadBytes + nBytes); pSi->numBadAccessUnits++; } } diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 91ba488..a6064b6 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -158,8 +158,8 @@ amm-info@iis.fraunhofer.de #define CONCEAL_NOT_DEFINED ((UCHAR)-1) /* default settings */ -#define CONCEAL_DFLT_FADEOUT_FRAMES (0) -#define CONCEAL_DFLT_FADEIN_FRAMES (0) +#define CONCEAL_DFLT_FADEOUT_FRAMES (6) +#define CONCEAL_DFLT_FADEIN_FRAMES (5) #define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0) #define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */ diff --git a/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp index ec4437f..af1f488 100644 --- a/libAACdec/src/usacdec_acelp.cpp +++ b/libAACdec/src/usacdec_acelp.cpp @@ -1116,7 +1116,8 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, const FIXP_LPC *A_new, const INT A_new_exp, const FIXP_LPC *A_old, const INT A_old_exp, CAcelpStaticMem *acelp_mem, - INT coreCoderFrameLength, UCHAR lpd_mode) { + INT coreCoderFrameLength, INT clearOldExc, + UCHAR lpd_mode) { int l_div = coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */ int l_div_partial; @@ -1154,6 +1155,13 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER], M_LP_FILTER_ORDER * sizeof(FIXP_DBL)); + if (clearOldExc) { + FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL)); + C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL, + PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER); + return; + } + /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */ if (last_lpd_mode == 1) { /* last frame was TCX20 */ if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */ @@ -1170,7 +1178,6 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL) ? PIT_MAX_MAX + L_INTERPOL : coreCoderFrameLength / 2; - int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length; E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length); E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length], diff --git a/libAACdec/src/usacdec_acelp.h b/libAACdec/src/usacdec_acelp.h index 593a073..9de41ff 100644 --- a/libAACdec/src/usacdec_acelp.h +++ b/libAACdec/src/usacdec_acelp.h @@ -238,7 +238,8 @@ void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode, const FIXP_LPC *A_new, const INT A_new_exp, const FIXP_LPC *A_old, const INT A_old_exp, CAcelpStaticMem *acelp_mem, - INT coreCoderFrameLength, UCHAR lpd_mode); + INT coreCoderFrameLength, INT clearOldExc, + UCHAR lpd_mode); /** * \brief Calculate zero input response (zir) of the acelp synthesis filter diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index 4ce6699..22069a6 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -1776,7 +1776,7 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal( pAacDecoderChannelInfo->data.usac.lp_coeff[k], pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev, lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame, - mod[k]); + (last_frame_lost && k < 2), mod[k]); } } else { if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset != diff --git a/libFDK/include/cplx_mul.h b/libFDK/include/cplx_mul.h index 9c5da57..eb1afce 100644 --- a/libFDK/include/cplx_mul.h +++ b/libFDK/include/cplx_mul.h @@ -258,26 +258,6 @@ inline void cplxMult(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, const FIXP_DBL a_Im, const FIXP_DPK w) { cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); } -#endif - -#if !defined(FUNCTION_cplxMult_nIm) -#define FUNCTION_cplxMult_nIm - -/* Same as cplxMult, but - a_Im must be negated, when used - c_re must be negated, when output -*/ -inline void cplxMult_nIm(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, - const FIXP_DBL a_Im, const FIXP_SPK w) { - *c_Re = -(fMult(a_Re, w.v.re) + fMult(a_Im, w.v.im)); - *c_Im = fMult(a_Re, w.v.im) - fMult(a_Im, w.v.re); -} - -inline void cplxMult_nIm(FIXP_DBL *c_Re, FIXP_DBL *c_Im, const FIXP_DBL a_Re, - const FIXP_DBL a_Im, const FIXP_DPK w) { - *c_Re = -(fMult(a_Re, w.v.re) + fMult(a_Im, w.v.im)); - *c_Im = fMult(a_Re, w.v.im) - fMult(a_Im, w.v.re); -} #endif /* ############################################################################# diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h index e671da9..1382374 100644 --- a/libFDK/include/mdct.h +++ b/libFDK/include/mdct.h @@ -119,6 +119,7 @@ amm-info@iis.fraunhofer.de #define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS) #endif #define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) +#define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS) #define MLT_FLAG_CURR_ALIAS_SYMMETRY 1 diff --git a/libFDK/src/FDK_lpc.cpp b/libFDK/src/FDK_lpc.cpp index 2ba7707..7d7e691 100644 --- a/libFDK/src/FDK_lpc.cpp +++ b/libFDK/src/FDK_lpc.cpp @@ -184,12 +184,19 @@ void CLpc_SynthesisLattice(FIXP_DBL *signal, const int signal_size, for (i = signal_size; i != 0; i--) { FIXP_DBL *pState = state + order - 1; const FIXP_DBL *pCoeff = coeff + order - 1; - FIXP_DBL tmp; + FIXP_DBL tmp, accu; + + accu = + fMultSubDiv2(scaleValue(*pSignal, signal_e - 1), *pCoeff--, *pState--); + tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); - tmp = scaleValue(*pSignal, signal_e) - fMult(*pCoeff--, *pState--); for (j = order - 1; j != 0; j--) { - tmp = tmp - fMult(pCoeff[0], pState[0]); - pState[1] = pState[0] + fMult(*pCoeff--, tmp); + accu = fMultSubDiv2(tmp >> 1, pCoeff[0], pState[0]); + tmp = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); + + accu = fMultAddDiv2(pState[0] >> 1, *pCoeff--, tmp); + pState[1] = SATURATE_LEFT_SHIFT_ALT(accu, 1, DFRACT_BITS); + pState--; } diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 4b78931..043a372 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -274,17 +274,28 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nBandsAnalysis * 10; if (size > 0) { if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_16) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates16(ch))) + goto bail; + } } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_24) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates24(ch))) + goto bail; + } } else if (gc->nBandsAnalysis == QMF_DOMAIN_ANALYSIS_QMF_BANDS_32) { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates32(ch))) + goto bail; + } } else { - if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pAnaQmfStates == NULL) { + if (NULL == (qd->QmfDomainIn[ch].pAnaQmfStates = GetAnaQmfStates(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].pAnaQmfStates = NULL; @@ -293,20 +304,36 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nQmfOvTimeSlots + gc->nQmfTimeSlots; if (size > 0) { if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_16) { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal16(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag16(ch))) + goto bail; + } } else if (gc->nQmfTimeSlots == QMF_DOMAIN_TIMESLOTS_32) { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal32(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag32(ch))) + goto bail; + } } else { - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch))) - goto bail; - if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch))) - goto bail; + if (qd->QmfDomainIn[ch].hQmfSlotsReal == NULL) { + if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsReal = GetQmfSlotsReal(ch))) + goto bail; + } + if (qd->QmfDomainIn[ch].hQmfSlotsImag == NULL) { + if (NULL == (qd->QmfDomainIn[ch].hQmfSlotsImag = GetQmfSlotsImag(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].hQmfSlotsReal = NULL; @@ -316,17 +343,23 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { size = gc->nQmfOvTimeSlots * gc->nQmfProcBands * CMPLX_MOD; if (size > 0) { if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_16) { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer16(ch))) + goto bail; + } } else if (gc->nQmfOvTimeSlots == QMF_DOMAIN_OV_TIMESLOTS_32) { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer32(ch))) + goto bail; + } } else { - if (NULL == - (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch))) - goto bail; + if (qd->QmfDomainIn[ch].pOverlapBuffer == NULL) { + if (NULL == + (qd->QmfDomainIn[ch].pOverlapBuffer = GetQmfOverlapBuffer(ch))) + goto bail; + } } } else { qd->QmfDomainIn[ch].pOverlapBuffer = NULL; @@ -336,8 +369,10 @@ static int FDK_QmfDomain_AllocatePersistentMemory(HANDLE_FDK_QMF_DOMAIN qd) { for (ch = 0; ch < gc->nOutputChannels; ch++) { int size = gc->nBandsSynthesis * 9; if (size > 0) { - if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch))) - goto bail; + if (qd->QmfDomainOut[ch].pSynQmfStates == NULL) { + if (NULL == (qd->QmfDomainOut[ch].pSynQmfStates = GetSynQmfStates(ch))) + goto bail; + } } else { qd->QmfDomainOut[ch].pSynQmfStates = NULL; } diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp index 6a6604c..d697cfb 100644 --- a/libFDK/src/mdct.cpp +++ b/libFDK/src/mdct.cpp @@ -541,11 +541,16 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, */ /* and de-scale current spectrum signal (time domain, no yet windowed) */ if (gain != (FIXP_DBL)0) { - scaleValuesWithFactor(pSpec, gain, tl, scalefactor[w] + specShiftScale); - } else { - int loc_scale = scalefactor[w] + specShiftScale; + for (i = 0; i < tl; i++) { + pSpec[i] = fMult(pSpec[i], gain); + } + } + + { + int loc_scale = + fixmin_I(scalefactor[w] + specShiftScale, (INT)DFRACT_BITS - 1); DWORD_ALIGNED(pSpec); - scaleValues(pSpec, tl, loc_scale); + scaleValuesSaturate(pSpec, tl, loc_scale); } if (noOutSamples <= nrSamples) { @@ -614,59 +619,34 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, if (!hMdct->pAsymOvlp) { for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; -#ifdef FUNCTION_cplxMult_nIm - /* This macro negates 4th parameter (*pOvl--) */ - /* and inverts the sign of result x1 */ - - /* This subroutine calculates the two output segments (C,D) from the - two availabe DCT IV data blocks, namely, (-D-Cr,A-Br) and - (-F-Er,C-Dr). "pOvl" is the pointer to the overlap block and points - to the end of the (-D-Cr) part of the overlap buffer (-D-Cr,A-Br). - It points to the end of the (-D-Cr) because it will read this part - in a flipped order. "pCurr" is the pointer to the current block - (-F-Er,C-Dr) and points to the beginning of the (C-Dr) block, - because this block will be read consequitively. "pWindow" is a - pointer to the used window coefficients. In pointer "x1" we get the - already computed from the function "Dr" segment. In pointer "x0" we - get the "C" segment. Since we have to output them sequentially the - "x0" pointer points to the beginnig of the output buffer (X,X), and - pointer "x1" points to the end of the output buffer (X,X). When we - get the output of the cplxMult_nIm function we write it sequentially - in the output buffer from the left to right ("x0"=>C) and right to - left ("x1"=>Dr) implementing flipping. At the end we get an output - in the form (C,D). */ - cplxMult_nIm(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0++ = IMDCT_SCALE_DBL(x0); - *pOut1-- = IMDCT_SCALE_DBL(x1); -#else - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(-x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1); pOut0++; pOut1--; -#endif /* #ifdef FUNCTION_cplxMult_nIm */ } } else { FIXP_DBL *pAsymOvl = hMdct->pAsymOvlp + fl / 2 - 1; for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - x1 = -fMult(*pCurr, pWindow[i].v.re) + - fMult(*pAsymOvl, pWindow[i].v.im); - x0 = fMult(*pCurr, pWindow[i].v.im) - fMult(*pOvl, pWindow[i].v.re); + x1 = -fMultDiv2(*pCurr, pWindow[i].v.re) + + fMultDiv2(*pAsymOvl, pWindow[i].v.im); + x0 = fMultDiv2(*pCurr, pWindow[i].v.im) - + fMultDiv2(*pOvl, pWindow[i].v.re); pCurr++; pOvl--; pAsymOvl--; - *pOut0++ = IMDCT_SCALE_DBL(x0); - *pOut1-- = IMDCT_SCALE_DBL(x1); + *pOut0++ = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1-- = IMDCT_SCALE_DBL_LSH1(x1); } hMdct->pAsymOvlp = NULL; } } else { /* prevAliasingSymmetry == 1 */ for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } @@ -675,18 +655,18 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, if (hMdct->prevAliasSymmetry == 0) { for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(-x1); + cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1); pOut0++; pOut1--; } } else { /* prevAliasingSymmetry == 1 */ for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index b7fd2a1..b0f1c6a 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1618,7 +1618,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16); /* Start bit position of config extension */ - nbits = FDKgetValidBits(hBs); + nbits = (INT)FDKgetValidBits(hBs); /* Return an error in case the bitbuffer fill level is too low. */ if (nbits < usacConfigExtLength * 8) { @@ -1650,7 +1650,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, /* Skip remaining bits. If too many bits were parsed, assume error. */ usacConfigExtLength = - 8 * usacConfigExtLength - (nbits - FDKgetValidBits(hBs)); + 8 * usacConfigExtLength - (nbits - (INT)FDKgetValidBits(hBs)); if (usacConfigExtLength < 0) { return TRANSPORTDEC_PARSE_ERROR; } diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 5eeb7fc..1d8b7b3 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1337,9 +1337,9 @@ static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp, INT bitDistance, bfDelta; /* Obtain distance to next synch word */ - bitDistance = FDKgetValidBits(hBs); + bitDistance = (INT)FDKgetValidBits(hBs); error = synchronization(hTp, &headerBits); - bitDistance -= FDKgetValidBits(hBs); + bitDistance -= (INT)FDKgetValidBits(hBs); FDK_ASSERT(bitDistance >= 0); @@ -1380,7 +1380,7 @@ static TRANSPORTDEC_ERROR transportDec_readStream(HANDLE_TRANSPORTDEC hTp, int num, denom; /* Obtain estimate of number of lost frames */ - num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + + num = (INT)hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder; denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame; if (num > 0) { diff --git a/libSBRdec/src/psbitdec.cpp b/libSBRdec/src/psbitdec.cpp index 1521178..f40a156 100644 --- a/libSBRdec/src/psbitdec.cpp +++ b/libSBRdec/src/psbitdec.cpp @@ -311,6 +311,7 @@ int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */ pBsData->noEnv = 1; if (pBsData->bEnableIid) { + pBsData->bFineIidQ = h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ; for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { pBsData->aaIidIndex[pBsData->noEnv - 1][gr] = h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr]; @@ -333,6 +334,9 @@ int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */ } } + /* Update previous frame Iid quantization */ + h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ = pBsData->bFineIidQ; + /* Update previous frame index buffers */ for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr] = diff --git a/libSBRdec/src/psdec.h b/libSBRdec/src/psdec.h index b6d9a12..6ae1473 100644 --- a/libSBRdec/src/psdec.h +++ b/libSBRdec/src/psdec.h @@ -274,7 +274,9 @@ struct PS_DEC { previous frame */ SCHAR aIccPrevFrameIndex[NO_HI_RES_ICC_BINS]; /*!< The ICC index for previous frame */ - UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ + UCHAR + bPrevFrameFineIidQ; /*!< The IID quantization of the previous frame */ + UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ FIXP_DBL pHybridAnaStatesLFdmx [2 * 13 * NO_QMF_BANDS_HYBRID20]; /*!< Memory used in hybrid analysis diff --git a/libSBRenc/src/tran_det.cpp b/libSBRenc/src/tran_det.cpp index b6f1b9f..3b6765a 100644 --- a/libSBRenc/src/tran_det.cpp +++ b/libSBRenc/src/tran_det.cpp @@ -269,23 +269,33 @@ static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, int *scaleEnergies, FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f); FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f); int tran_offdiv2 = tran_off >> nrgSzShift; + const int sc1 = + DFRACT_BITS - + fNormz((FIXP_DBL)fMax( + 1, (freqBandTable[0] * (YBufferWriteOffset - tran_offdiv2) - 1))); + const int sc2 = + DFRACT_BITS - + fNormz((FIXP_DBL)fMax( + 1, (freqBandTable[0] * + (tran_offdiv2 + (slots >> nrgSzShift) - YBufferWriteOffset) - + 1))); int ts, k; /* Sum up lowband energy from one frame at offset tran_off */ /* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */ for (ts = tran_offdiv2; ts < YBufferWriteOffset; ts++) { for (k = 0; k < freqBandTable[0]; k++) { - accu1 += Energies[ts][k] >> 6; + accu1 += Energies[ts][k] >> sc1; } } for (; ts < tran_offdiv2 + (slots >> nrgSzShift); ts++) { for (k = 0; k < freqBandTable[0]; k++) { - accu2 += Energies[ts][k] >> 9; + accu2 += Energies[ts][k] >> sc2; } } - nrgTotal_m = fAddNorm(accu1, 1 - scaleEnergies[0], accu2, - 4 - scaleEnergies[1], &nrgTotal_e); + nrgTotal_m = fAddNorm(accu1, (sc1 - 5) - scaleEnergies[0], accu2, + (sc2 - 5) - scaleEnergies[1], &nrgTotal_e); nrgTotal_m = scaleValueSaturate(nrgTotal_m, nrgTotal_e); return (nrgTotal_m); -- cgit v1.2.3