From cc825aecf5ff8c2c7027f7424d7933cd80d6f3bb Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:05:33 +0200 Subject: Restrict sampling rates parsed from bitstream to maximum of 96kHz. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I2511a7cfcdf1bae57d17c02c93867ccc4f1ea693 --- libMpegTPDec/src/tpdec_asc.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index 28bc22d..a86c2cb 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1440,7 +1440,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, UCHAR tmpDownscaleFreqIdx; esc->m_downscaledSamplingFrequency = getSampleRate(hBs, &tmpDownscaleFreqIdx, 4); - if (esc->m_downscaledSamplingFrequency == 0) { + if (esc->m_downscaledSamplingFrequency == 0 || + esc->m_downscaledSamplingFrequency > 96000) { return TRANSPORTDEC_PARSE_ERROR; } downscale_fill_nibble = FDKreadBits(hBs, 4); @@ -1948,6 +1949,9 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, INT nbits = (INT)FDKgetValidBits(hBs); usacSamplingFrequency = getSampleRate(hBs, &asc->m_samplingFrequencyIndex, 5); + if (usacSamplingFrequency == 0 || usacSamplingFrequency > 96000) { + return TRANSPORTDEC_PARSE_ERROR; + } asc->m_samplingFrequency = (UINT)usacSamplingFrequency; coreSbrFrameLengthIndex = FDKreadBits(hBs, 3); @@ -2027,7 +2031,8 @@ static TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse( self->m_extensionSamplingFrequency = getSampleRate( bs, &self->m_extensionSamplingFrequencyIndex, 4); - if ((INT)self->m_extensionSamplingFrequency <= 0) { + if (self->m_extensionSamplingFrequency == 0 || + self->m_extensionSamplingFrequency > 96000) { return TRANSPORTDEC_PARSE_ERROR; } } @@ -2153,6 +2158,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4); + if (self->m_extensionSamplingFrequency == 0 || + self->m_extensionSamplingFrequency > 96000) { + return TRANSPORTDEC_PARSE_ERROR; + } self->m_aot = getAOT(bs); switch (self->m_aot) { -- cgit v1.2.3 From dbfa1cd71bbc5c0af382f47c222a72739bc101de Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:06:06 +0200 Subject: Fix assert in synchronization() for loas streams with multiple sub frames. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Icb7d4b0b00a17367c8ec762b112fbb25268d9f67 --- libMpegTPDec/src/tpdec_lib.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 506aed3..ede64c9 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -663,10 +663,14 @@ TRANSPORTDEC_ERROR transportDec_FillData(const HANDLE_TRANSPORTDEC hTp, if (*pBytesValid == 0) { /* nothing to do */ return TRANSPORTDEC_OK; - } - - if (hTp->numberOfRawDataBlocks <= 0) { + } else { + const int bytesValid = *pBytesValid; FDKfeedBuffer(hBs, pBuffer, bufferSize, pBytesValid); + + if (hTp->numberOfRawDataBlocks > 0) { + hTp->globalFramePos += (bytesValid - *pBytesValid) * 8; + hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs); + } } } @@ -1151,6 +1155,11 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, &rawDataBlockLength, &fTraverseMoreFrames, &syncLayerFrameBits, &fConfigFound, &headerBits); + if (headerBits > bitsAvail) { + err = (headerBits < (INT)hBs->hBitBuf.bufBits) + ? TRANSPORTDEC_NOT_ENOUGH_BITS + : TRANSPORTDEC_SYNC_ERROR; + } 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 @@ -1181,8 +1190,6 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, } if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { - /* Enforce reading of new data */ - hTp->numberOfRawDataBlocks = 0; break; } @@ -1273,7 +1280,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, /* Rewind for retry because of not enough bits */ if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { FDKpushBack(hBs, headerBits); + hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious; headerBits = 0; + rawDataBlockLength = rawDataBlockLengthPrevious; } else { /* reset hold off frame counter */ hTp->holdOffFrames = 0; -- cgit v1.2.3 From 128abf6b1ace9c790ba7f42d976d3035cbe347b6 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:06:37 +0200 Subject: Validate aacSampleRate after applying ELD downscale factor. Avoid division by zero. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I3f7ece9451121d40fab2c97571c695c1ac62bd00 --- libAACdec/src/aacdecoder.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 7617937..38ef4f8 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1928,6 +1928,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, self->samplingRateInfo[0].samplingRate / self->downscaleFactor; self->streamInfo.aacSamplesPerFrame = asc->m_samplesPerFrame / self->downscaleFactor; + if (self->streamInfo.aacSampleRate <= 0) { + return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; + } } } -- cgit v1.2.3 From f26eb8af7c38047ad113072a6de38e069dc5cf3f Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:06:59 +0200 Subject: Fix CpePersistentData memory leak. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iee5c93d61088bbda2328099ad20413adae3fa09b --- libAACdec/src/aacdecoder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 38ef4f8..b15fc80 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1303,7 +1303,8 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self, const int subStreamIndex) { int ch; int aacChannelOffset = 0, aacChannels = (8); - int numElements = (((8)) + (8)), elementOffset = 0; + int numElements = (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1), + elementOffset = 0; if (self == NULL) return; -- cgit v1.2.3 From 2b5217a9532ab952c831693e208bdfcb6a0b50eb Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:07:19 +0200 Subject: Fix possible stack buffer overflow in mapIndexData(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I160e7174f32dabe386fce1e9ec67d3c8cea60c78 --- libSACdec/src/sac_bitdec.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libSACdec/src/sac_bitdec.cpp b/libSACdec/src/sac_bitdec.cpp index a1bdca4..c814b41 100644 --- a/libSACdec/src/sac_bitdec.cpp +++ b/libSACdec/src/sac_bitdec.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1554,22 +1554,20 @@ static SACDEC_ERROR mapIndexData( /* Interpolate */ i1 = 0; for (i = 0; i < numParameterSets; i++) { - int xi, i2, x1, x2; - if (aInterpolate[i] != 1) { i1 = i; - } - i2 = i; - while (aInterpolate[i2] == 1) { - i2++; - if (i2 >= MAX_PARAMETER_SETS) return MPS_WRONG_PARAMETERSETS; - } - x1 = paramSlot[i1]; - xi = paramSlot[i]; - x2 = paramSlot[i2]; + } else { + int xi, i2, x1, x2; - if (aInterpolate[i] == 1) { + for (i2 = i; i2 < numParameterSets; i2++) { + if (aInterpolate[i2] != 1) break; + } if (i2 >= numParameterSets) return MPS_WRONG_PARAMETERSETS; + + x1 = paramSlot[i1]; + xi = paramSlot[i]; + x2 = paramSlot[i2]; + for (band = startBand; band < stopBand; band++) { int yi, y1, y2; y1 = outputIdxData[xttIdx][i1][band]; -- cgit v1.2.3 From 572f59359a5e71f59a09e2dbc75aa45e7eaaa360 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:07:39 +0200 Subject: Reject unsupported channel configuration / audio object type combinations. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I84bd355df0f690636c109695d8df64fa7bdcf63c --- libMpegTPDec/src/tpdec_asc.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index a86c2cb..ad13378 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -2144,6 +2144,24 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( self->m_channelConfiguration = FDKreadBits(bs, 4); + /* MPEG-04 standard ISO/IEC 14496-3: channelConfiguration == 0 is reserved + in er_raw_data_block (table 4.19) and er_raw_data_block_eld (table 4.75) + MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration == 0 is not + permitted for AOT_ER_AAC_LC, AOT_ER_AAC_LTP, AOT_ER_AAC_LD, + AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */ + if ((self->m_channelConfiguration == 0) && + ((self->m_aot == AOT_ER_AAC_LC) || (self->m_aot == AOT_ER_AAC_LTP) || + (self->m_aot == AOT_ER_AAC_LD) || (self->m_aot == AOT_ER_AAC_SCAL) || + (self->m_aot == AOT_ER_AAC_ELD))) { + return TRANSPORTDEC_UNSUPPORTED_FORMAT; + } + /* MPEG-04 conformance ISO/IEC 14496-4: channelConfiguration > 2 is not + * permitted for AOT_AAC_SCAL and AOT_ER_AAC_SCAL (chapter 6.6.4.1.2.1.1) */ + if ((self->m_channelConfiguration > 2) && + ((self->m_aot == AOT_AAC_SCAL) || (self->m_aot == AOT_ER_AAC_SCAL))) { + return TRANSPORTDEC_UNSUPPORTED_FORMAT; + } + /* SBR extension ( explicit non-backwards compatible mode ) */ self->m_sbrPresentFlag = 0; self->m_psPresentFlag = 0; -- cgit v1.2.3 From 0be235952d653d9932b8cb180cdb16560506b98c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:08:05 +0200 Subject: Solve potential dereference of null pointers in factorCLD(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I27334567d1887755d62fadf2456fd5366869cbab --- libSACdec/src/sac_bitdec.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libSACdec/src/sac_bitdec.cpp b/libSACdec/src/sac_bitdec.cpp index c814b41..4b47132 100644 --- a/libSACdec/src/sac_bitdec.cpp +++ b/libSACdec/src/sac_bitdec.cpp @@ -1586,9 +1586,9 @@ static SACDEC_ERROR mapIndexData( for (ps = 0; ps < numParameterSets; ps++) { if (quantMode && (paramType == t_CLD)) { if (pOttVsTotDbIn == 0) return MPS_WRONG_OTT; - if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode == ottVsTotDb1Activ)) + if ((pOttVsTotDb1 == 0) && (ottVsTotDbMode & ottVsTotDb1Activ)) return MPS_WRONG_OTT; - if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode == ottVsTotDb2Activ)) + if ((pOttVsTotDb2 == 0) && (ottVsTotDbMode & ottVsTotDb2Activ)) return MPS_WRONG_OTT; for (pb = startBand; pb < stopBand; pb++) { -- cgit v1.2.3 From b1b306443a1cc0308fa563b40a281bae53346d01 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:08:22 +0200 Subject: Replace obsolete SBR CRC with superior FDK CRC implementation. Fixes ELD SBR CRC decoding and prevents negative shift exponents in calcCRC(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I0c40609975de5854560643f3ce2c9fecf5973f73 --- libSBRdec/src/sbr_crc.cpp | 192 ------------------------------------------- libSBRdec/src/sbr_crc.h | 138 ------------------------------- libSBRdec/src/sbrdecoder.cpp | 87 ++++++++------------ 3 files changed, 35 insertions(+), 382 deletions(-) delete mode 100644 libSBRdec/src/sbr_crc.cpp delete mode 100644 libSBRdec/src/sbr_crc.h diff --git a/libSBRdec/src/sbr_crc.cpp b/libSBRdec/src/sbr_crc.cpp deleted file mode 100644 index ba0fd05..0000000 --- a/libSBRdec/src/sbr_crc.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© 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. - -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: - -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 -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. - -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." - -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. - -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. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC check coutines -*/ - -#include "sbr_crc.h" - -#include "FDK_bitstream.h" -#include "transcendent.h" - -#define MAXCRCSTEP 16 -#define MAXCRCSTEP_LD 4 - -/*! - \brief crc calculation -*/ -static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) { - int i; - ULONG bMask = (1UL << (nBits - 1)); - - for (i = 0; i < nBits; i++, bMask >>= 1) { - USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0; - USHORT flag1 = (bMask & bValue) ? 1 : 0; - - flag ^= flag1; - hCrcBuf->crcState <<= 1; - if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly; - } - - return (hCrcBuf->crcState); -} - -/*! - \brief crc -*/ -static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) { - int i; - CRC_BUFFER CrcBuf; - - CrcBuf.crcState = SBR_CRC_START; - CrcBuf.crcPoly = SBR_CRC_POLY; - CrcBuf.crcMask = SBR_CRC_MASK; - - int CrcStep = NrBits >> MAXCRCSTEP_LD; - - int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP); - ULONG bValue; - - for (i = 0; i < CrcStep; i++) { - bValue = FDKreadBits(hBs, MAXCRCSTEP); - calcCRC(&CrcBuf, bValue, MAXCRCSTEP); - } - - bValue = FDKreadBits(hBs, CrcNrBitsRest); - calcCRC(&CrcBuf, bValue, CrcNrBitsRest); - - return (CrcBuf.crcState & SBR_CRC_RANGE); -} - -/*! - \brief crc interface - \return 1: CRC OK, 0: CRC check failure -*/ -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */ - LONG NrBits) /*!< max. CRC length */ -{ - int crcResult = 1; - ULONG NrCrcBits; - ULONG crcCheckResult; - LONG NrBitsAvailable; - ULONG crcCheckSum; - - crcCheckSum = FDKreadBits(hBs, 10); - - NrBitsAvailable = FDKgetValidBits(hBs); - if (NrBitsAvailable <= 0) { - return 0; - } - - NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable); - - crcCheckResult = getCrc(hBs, NrCrcBits); - FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs))); - - if (crcCheckResult != crcCheckSum) { - crcResult = 0; - } - - return (crcResult); -} diff --git a/libSBRdec/src/sbr_crc.h b/libSBRdec/src/sbr_crc.h deleted file mode 100644 index 9633717..0000000 --- a/libSBRdec/src/sbr_crc.h +++ /dev/null @@ -1,138 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© 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. - -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: - -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 -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. - -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." - -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. - -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. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC checking routines -*/ -#ifndef SBR_CRC_H -#define SBR_CRC_H - -#include "sbrdecoder.h" - -#include "FDK_bitstream.h" - -/* some useful crc polynoms: - -crc5: x^5+x^4+x^2+x^1+1 -crc6: x^6+x^5+x^3+x^2+x+1 -crc7: x^7+x^6+x^2+1 -crc8: x^8+x^2+x+x+1 -*/ - -/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */ -#define SBR_CRC_POLY 0x0233 -#define SBR_CRC_MASK 0x0200 -#define SBR_CRC_START 0x0000 -#define SBR_CRC_RANGE 0x03FF - -typedef struct { - USHORT crcState; - USHORT crcMask; - USHORT crcPoly; -} CRC_BUFFER; - -typedef CRC_BUFFER *HANDLE_CRC; - -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits); - -#endif diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index c827ced..52403f6 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -143,14 +143,12 @@ amm-info@iis.fraunhofer.de #include "env_extr.h" #include "sbr_dec.h" #include "env_dec.h" -#include "sbr_crc.h" +#include "FDK_crc.h" #include "sbr_ram.h" #include "sbr_rom.h" #include "lpp_tran.h" #include "transcendent.h" -#include "FDK_crc.h" - #include "sbrdec_drc.h" #include "psbitdec.h" @@ -1134,18 +1132,22 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; INT startPos = FDKgetValidBits(hBs); - INT CRCLen = 0; + FDK_CRCINFO crcInfo; + INT crcReg = 0; + USHORT sbrCrc = 0; + UINT crcPoly; + UINT crcStartValue = 0; + UINT crcLen; + HANDLE_FDK_BITSTREAM hBsOriginal = hBs; FDK_BITSTREAM bsBwd; - FDK_CRCINFO crcInfo; - INT crcReg = 0; - USHORT drmSbrCrc = 0; const int fGlobalIndependencyFlag = acFlags & AC_INDEP; const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC; const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES; int stereo; int fDoDecodeSbrData = 1; + int alignBits = 0; int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0; @@ -1277,27 +1279,23 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, if (fDoDecodeSbrData) { if (crcFlag) { switch (self->coreCodec) { - case AOT_ER_AAC_ELD: - FDKpushFor(hBs, 10); - /* check sbrcrc later: we don't know the payload length now */ - break; case AOT_DRM_AAC: case AOT_DRM_SURROUND: - drmSbrCrc = (USHORT)FDKreadBits(hBs, 8); - /* Setup CRC decoder */ - FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8); - /* Start CRC region */ - crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); + crcPoly = 0x001d; + crcLen = 8; + crcStartValue = 0x000000ff; break; default: - CRCLen = bsPayLen - 10; /* change: 0 => i */ - if (CRCLen < 0) { - fDoDecodeSbrData = 0; - } else { - fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen); - } + crcPoly = 0x0633; + crcLen = 10; + crcStartValue = 0x00000000; break; } + sbrCrc = (USHORT)FDKreadBits(hBs, crcLen); + /* Setup CRC decoder */ + FDKcrcInit(&crcInfo, crcPoly, crcStartValue, crcLen); + /* Start CRC region */ + crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); } } /* if (fDoDecodeSbrData) */ @@ -1450,35 +1448,6 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, valBits = (INT)FDKgetValidBits(hBs); } - if (crcFlag) { - switch (self->coreCodec) { - case AOT_ER_AAC_ELD: { - /* late crc check for eld */ - INT payloadbits = - (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos; - INT crcLen = payloadbits - 10; - FDKpushBack(hBs, payloadbits); - fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen); - FDKpushFor(hBs, crcLen); - } break; - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - /* End CRC region */ - FDKcrcEndReg(&crcInfo, hBs, crcReg); - /* Check CRC */ - if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) { - fDoDecodeSbrData = 0; - if (headerStatus != HEADER_NOT_PRESENT) { - headerStatus = HEADER_ERROR; - hSbrHeader->syncState = SBR_NOT_INITIALIZED; - } - } - break; - default: - break; - } - } - /* sanity check of remaining bits */ if (valBits < 0) { fDoDecodeSbrData = 0; @@ -1489,7 +1458,7 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, case AOT_AAC_LC: { /* This sanity check is only meaningful with General Audio * bitstreams */ - int alignBits = valBits & 0x7; + alignBits = valBits & 0x7; if (valBits > alignBits) { fDoDecodeSbrData = 0; @@ -1508,6 +1477,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, errorStatus = SBRDEC_PARSE_ERROR; } + if (crcFlag && (hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { + FDKpushFor(hBs, alignBits); + FDKcrcEndReg(&crcInfo, hBs, crcReg); /* End CRC region */ + FDKpushBack(hBs, alignBits); + /* Check CRC */ + if ((FDKcrcGetCRC(&crcInfo) ^ crcStartValue) != sbrCrc) { + fDoDecodeSbrData = 0; + if (headerStatus != HEADER_NOT_PRESENT) { + headerStatus = HEADER_ERROR; + hSbrHeader->syncState = SBR_NOT_INITIALIZED; + } + } + } + if (!fDoDecodeSbrData) { /* Set error flag for this slot to trigger concealment */ setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); -- cgit v1.2.3 From bedfd82356dafa1f51f360af29f302a672d6866c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:00 +0200 Subject: Fix shift value assignment in addHighBandPart(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I69457c1b551e33e3ee9ef39b457b0f83de2e370e --- libSBRdec/src/hbe.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp index 1141e9c..2284c42 100644 --- a/libSBRdec/src/hbe.cpp +++ b/libSBRdec/src/hbe.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1339,7 +1339,7 @@ static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e, g_r_m = fMultDiv2(tmp_r, factor_m) << shift; g_i_m = fMultDiv2(tmp_i, factor_m) << shift; g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add); - fMax((INT)0, g_e); + g_e = fMax((INT)0, g_e); *qmfHBEBufReal_F += g_r_m >> g_e; *qmfHBEBufImag_F += g_i_m >> g_e; } -- cgit v1.2.3 From a65911cd2ef6a16878e88cd91818ef962950ceec Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:18 +0200 Subject: Limit shift exponent in adjustTimeSlot_EldGrid(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I4000972d63d74e871d47f2db031308cd7ea285d6 --- libSBRdec/src/env_calc.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 1242833..eaf739d 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1576,12 +1576,13 @@ void calculateSbrEnvelope( FDK_ASSERT(!iTES_enable); /* not supported */ if (flags & SBRDEC_ELD_GRID) { /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */ - adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs, - &h_sbr_cal_env->harmIndex, lowSubband, - noSubbands, - fMin(scale_change, DFRACT_BITS - 1), - noNoiseFlag, &h_sbr_cal_env->phaseIndex, - EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); + adjustTimeSlot_EldGrid( + &analysBufferReal[j][lowSubband], pNrgs, + &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, + fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag, + &h_sbr_cal_env->phaseIndex, + fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale, + -(DFRACT_BITS - 1))); } else { adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs, &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, -- cgit v1.2.3 From 6f98eab35095f5fd7bcfb9df585ff0b0c6f1460d Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:09:36 +0200 Subject: Saturate shift value in calculateSbrEnvelope(). Prevents too large shift values. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I3331ac9bc267cd3fa4c1178bc445998869f0d99b --- libSBRdec/src/env_calc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index eaf739d..c34ce96 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1477,7 +1477,7 @@ void calculateSbrEnvelope( for (k = 0; k < noSubbands; k++) { int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1); - pNrgs->nrgGain[k] >>= sc; + pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1); pNrgs->nrgGain_e[k] += sc; } @@ -1485,7 +1485,7 @@ void calculateSbrEnvelope( for (k = 0; k < noSubbands; k++) { int sc = scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1); - h_sbr_cal_env->filtBuffer[k] >>= sc; + h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1); } } -- cgit v1.2.3 From 15965e3feb9025e1db65a7c9a7408b3970430cb8 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:10:07 +0200 Subject: Limit too large shift exponent in CJointStereo_ApplyMS() Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ia6ab654654e899368ba207a66eddf22b6b855635 --- libAACdec/src/stereo.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/libAACdec/src/stereo.cpp b/libAACdec/src/stereo.cpp index eed826b..a90ae35 100644 --- a/libAACdec/src/stereo.cpp +++ b/libAACdec/src/stereo.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -807,19 +807,17 @@ void CJointStereo_ApplyMS( for (int i = 0; i < windowLen; i++) { dmx_re_prev[i] = ((staticSpectralCoeffsL[index_offset + i] >> - srLeftChan) + + fMin(DFRACT_BITS - 1, srLeftChan + 1)) + (staticSpectralCoeffsR[index_offset + i] >> - srRightChan)) >> - 1; + fMin(DFRACT_BITS - 1, srRightChan + 1))); } } else { for (int i = 0; i < windowLen; i++) { dmx_re_prev[i] = ((staticSpectralCoeffsL[index_offset + i] >> - srLeftChan) - + fMin(DFRACT_BITS - 1, srLeftChan + 1)) - (staticSpectralCoeffsR[index_offset + i] >> - srRightChan)) >> - 1; + fMin(DFRACT_BITS - 1, srRightChan + 1))); } } } @@ -854,12 +852,13 @@ void CJointStereo_ApplyMS( if (window == 0) { if (dmx_re_prev_e < frameMaxScale) { if (mainband_flag == 0) { - scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen, - -(frameMaxScale - dmx_re_prev_e)); + scaleValues( + dmx_re_prev, store_dmx_re_prev, windowLen, + -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e))); } else { - for (int i = 0; i < windowLen; i++) { - dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e); - } + scaleValues( + dmx_re_prev, windowLen, + -fMin(DFRACT_BITS - 1, (frameMaxScale - dmx_re_prev_e))); } } else { if (mainband_flag == 0) { @@ -873,10 +872,9 @@ void CJointStereo_ApplyMS( FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence == BLOCK_SHORT); if (specScaleL[window - 1] < frameMaxScale) { - for (int i = 0; i < windowLen; i++) { - dmx_re[windowLen * (window - 1) + i] >>= - (frameMaxScale - specScaleL[window - 1]); - } + scaleValues(&dmx_re[windowLen * (window - 1)], windowLen, + -fMin(DFRACT_BITS - 1, + (frameMaxScale - specScaleL[window - 1]))); } else { specScaleL[window] = specScaleL[window - 1]; specScaleR[window] = specScaleR[window - 1]; -- cgit v1.2.3 From da5b0dcb3c01197b3499e0b569babcb0f5a09bbe Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 9 Aug 2019 17:10:29 +0200 Subject: Restrict size of huffman escape sequence to prevent shift with too large exponent in DecodeEscapeSequence(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ibcd182e313e9ef480e92619023bf424762b92e23 --- libAACdec/src/aacdec_hcr.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/libAACdec/src/aacdec_hcr.cpp b/libAACdec/src/aacdec_hcr.cpp index 6114756..a7e9cce 100644 --- a/libAACdec/src/aacdec_hcr.cpp +++ b/libAACdec/src/aacdec_hcr.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -137,7 +137,7 @@ static void DeriveNumberOfExtendedSortedSectionsInSets( static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, INT quantSpecCoef, INT *pLeftStartOfSegment, SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits); + int *pNumDecodedBits, UINT *errorWord); static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, UINT codebookDim, const SCHAR *pQuantVal, @@ -1179,8 +1179,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) { bs, pHcr->decInOut.bitstreamAnchor, pQuantizedSpectralCoefficients [quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, pRemainingBitsInSegment, - &numDecodedBits); + pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits, + &pHcr->decInOut.errorLog); } quantizedSpectralCoefficientsIdx++; if (quantizedSpectralCoefficientsIdx >= 1024) { @@ -1195,8 +1195,8 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) { bs, pHcr->decInOut.bitstreamAnchor, pQuantizedSpectralCoefficients [quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, pRemainingBitsInSegment, - &numDecodedBits); + pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits, + &pHcr->decInOut.errorLog); } quantizedSpectralCoefficientsIdx++; if (quantizedSpectralCoefficientsIdx >= 1024) { @@ -1386,7 +1386,7 @@ value == 16, a escapeSequence is decoded in two steps: static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, INT quantSpecCoef, INT *pLeftStartOfSegment, SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits) { + int *pNumDecodedBits, UINT *errorWord) { UINT i; INT sign; UINT escapeOnesCounter = 0; @@ -1400,6 +1400,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; + if (*pRemainingBitsInSegment < 0) { + return Q_VALUE_INVALID; + } if (carryBit != 0) { escapeOnesCounter += 1; @@ -1416,6 +1419,9 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; + if (*pRemainingBitsInSegment < 0) { + return Q_VALUE_INVALID; + } escape_word <<= 1; escape_word = escape_word | carryBit; @@ -1423,8 +1429,12 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor, sign = (quantSpecCoef >= 0) ? 1 : -1; - quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word); - + if (escapeOnesCounter < 13) { + quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word); + } else { + *errorWord |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED; + quantSpecCoef = Q_VALUE_INVALID; + } return quantSpecCoef; } -- cgit v1.2.3 From f0e1e3f8c7f835a0faf259ef21a51b55e2cec1f3 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 13:55:57 +0200 Subject: Validate correct ascLen in CLatmDemux_ReadStreamMuxConfig() to overcome integer overflow in FDK_get32(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I87b53661df7a435ddf3572a0ff8b6ef84972db60 --- libMpegTPDec/src/tpdec_latm.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index 2edf055..3b71db8 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -367,10 +367,10 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadStreamMuxConfig( } if (pLatmDemux->m_AudioMuxVersion == 1) { FDK_BITSTREAM tmpBs; - UINT ascLen = 0; + INT ascLen = 0; ascLen = CLatmDemux_GetValue(bs); /* The ascLen could be wrong, so check if validBits<=bufBits*/ - if (ascLen > FDKgetValidBits(bs)) { + if (ascLen < 0 || ascLen > (INT)FDKgetValidBits(bs)) { ErrorStatus = TRANSPORTDEC_PARSE_ERROR; goto bail; } -- cgit v1.2.3 From 40d2a1d8b055ebe17b67195029029ecdc5bc3268 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 13:58:23 +0200 Subject: Avoid integer overflows with pseudoLR in CAacDecoder_DecodeFrame(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I5c83d72b5c0f4cd1569b648f102c8c549a7a6ac2 --- libAACdec/src/aacdecoder.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index b15fc80..6b5a86c 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -3388,7 +3388,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( * LR) */ if ((aacChannels == 2) && bsPseudoLr) { int i, offset2; - const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f); + const FIXP_SGL invSqrt2 = + FL2FXCONST_SGL(0.353553390593273f); /* scaled by -1 */ FIXP_PCM *pTD = pTimeData; offset2 = timeDataChannelOffset; @@ -3399,11 +3400,14 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( L = fMult(L, invSqrt2); R = fMult(R, invSqrt2); #if (SAMPLE_BITS == 16) - pTD[0] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000)); - pTD[offset2] = FX_DBL2FX_PCM(fAddSaturate(L - R, (FIXP_DBL)0x8000)); + pTD[0] = (FIXP_SGL)SATURATE_RIGHT_SHIFT(L + R + (FIXP_DBL)(1 << 14), + 15, FRACT_BITS); + pTD[offset2] = (FIXP_SGL)SATURATE_RIGHT_SHIFT( + L - R + (FIXP_DBL)(1 << 14), 15, FRACT_BITS); #else - pTD[0] = FX_DBL2FX_PCM(L + R); - pTD[offset2] = FX_DBL2FX_PCM(L - R); + pTD[0] = SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L + R), 1, DFRACT_BITS); + pTD[offset2] = + SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L - R), 1, DFRACT_BITS); #endif pTD++; } -- cgit v1.2.3 From 1b4a3bedbb9d512c929c2fa191cc44c8dae8bce9 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:00:27 +0200 Subject: Overcome potential integer overflows in M/S module for complex prediction. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ic0648203b6a61ebff8bcc93c4b1099e033bc6860 --- libAACdec/src/stereo.cpp | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/libAACdec/src/stereo.cpp b/libAACdec/src/stereo.cpp index a90ae35..47f1a31 100644 --- a/libAACdec/src/stereo.cpp +++ b/libAACdec/src/stereo.cpp @@ -989,7 +989,7 @@ void CJointStereo_ApplyMS( } /* if ( pJointStereoData->complex_coef == 1 ) */ /* 4. upmix process */ - INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1; + LONG pred_dir = cplxPredictionData->pred_dir ? -1 : 1; /* 0.1 in Q-3.34 */ const FIXP_DBL pointOne = 0x66666666; /* 0.8 */ /* Shift value for the downmix */ @@ -1039,34 +1039,24 @@ void CJointStereo_ApplyMS( the downmix. "dmx_re" and "specL" are two different pointers pointing to separate arrays, which may or may not contain the same data (with different scaling). - */ - - /* help1: alpha_re[i] * dmx_re[i] */ - FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++); - - /* tmp: dmx_im[i] */ - FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx; - /* help2: alpha_im[i] * dmx_im[i] */ - FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp); - - /* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */ - FIXP_DBL help3 = help1 + help2; + specL[i] = + (specL[i] + side); + specR[i] = -/+ (specL[i] - side); + */ + FIXP_DBL side, left, right; - /* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i] - * * dmx_im[i]) */ - FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift); + side = fMultAddDiv2(fMultDiv2(alpha_re_tmp, *p2dmxRe++), + alpha_im_tmp, (*p2dmxIm++) << shift_dmx); + side = ((*p2CoeffR) >> 2) - + (FIXP_DBL)SATURATE_SHIFT(side, -(help3_shift - 2), + DFRACT_BITS - 2); - /* We calculate the left and right output by using the helper - * function */ - /* specR[i] = -/+ (specL[i] - side); */ - *p2CoeffR = - (FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir); - p2CoeffR++; + left = ((*p2CoeffL) >> 2) + side; + right = ((*p2CoeffL) >> 2) - side; + right = (FIXP_DBL)((LONG)right * pred_dir); - /* specL[i] = specL[i] + side; */ - *p2CoeffL = *p2CoeffL + help4; - p2CoeffL++; + *p2CoeffL++ = SATURATE_LEFT_SHIFT_ALT(left, 2, DFRACT_BITS); + *p2CoeffR++ = SATURATE_LEFT_SHIFT_ALT(right, 2, DFRACT_BITS); } } -- cgit v1.2.3 From 4c839c6a90d800d60f66f848f437ccdd800953a9 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:01:01 +0200 Subject: Fix integer overflow in E_UTIL_preemph(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iaaa0630e59d8e83e58b25168a3db04304485429b --- libAACdec/src/usacdec_acelp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp index c836c6a..1ac8c9f 100644 --- a/libAACdec/src/usacdec_acelp.cpp +++ b/libAACdec/src/usacdec_acelp.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -131,7 +131,7 @@ void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) { int i; for (i = 0; i < L; i++) { - out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]); + out[i] = fAddSaturate(in[i], -fMult(PREEMPH_FAC, in[i - 1])); } return; -- cgit v1.2.3 From 2d292e9b2d116934f09e37c6553927582c9ee4fc Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:01:32 +0200 Subject: Use SATURATE_LEFT_SHIFT in get_lsppol() to prevent integer overflow. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ie9ec52485a52b076a900b111b035289110c004f8 --- libAACdec/src/usacdec_lpc.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libAACdec/src/usacdec_lpc.cpp b/libAACdec/src/usacdec_lpc.cpp index 271463f..440fa87 100644 --- a/libAACdec/src/usacdec_lpc.cpp +++ b/libAACdec/src/usacdec_lpc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1138,9 +1138,12 @@ static void get_lsppol(FIXP_LPC lsp[], FIXP_DBL f[], int n, int flag) { for (i = 2; i <= n; i++) { plsp += 2; b = -FX_LPC2FX_DBL(*plsp); - f[i] = ((fMultDiv2(b, f[i - 1]) << 1) + (f[i - 2])) << 1; + f[i] = SATURATE_LEFT_SHIFT((fMultDiv2(b, f[i - 1]) + (f[i - 2] >> 1)), 2, + DFRACT_BITS); for (j = i - 1; j > 1; j--) { - f[j] = f[j] + (fMultDiv2(b, f[j - 1]) << 2) + f[j - 2]; + f[j] = SATURATE_LEFT_SHIFT( + ((f[j] >> 2) + fMultDiv2(b, f[j - 1]) + (f[j - 2] >> 2)), 2, + DFRACT_BITS); } f[1] = f[1] + (b >> (SF_F - 1)); } -- cgit v1.2.3 From 4db9f39f6d1a4f89e3891d29345201a04eef43f0 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:02:19 +0200 Subject: Avoid signed integer overflow in E_LPC_f_lsp_a_conversion(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: If2110ad246bb5b57ef76c9cd251874ecd4b05109 --- libAACdec/src/usacdec_lpc.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libAACdec/src/usacdec_lpc.cpp b/libAACdec/src/usacdec_lpc.cpp index 440fa87..278afbe 100644 --- a/libAACdec/src/usacdec_lpc.cpp +++ b/libAACdec/src/usacdec_lpc.cpp @@ -1170,6 +1170,9 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) { /*-----------------------------------------------------* * Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) * *-----------------------------------------------------*/ + scaleValues(f1, NC + 1, -2); + scaleValues(f2, NC + 1, -2); + for (i = NC; i > 0; i--) { f1[i] += f1[i - 1]; f2[i] -= f2[i - 1]; @@ -1178,13 +1181,8 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) { FIXP_DBL aDBL[M_LP_FILTER_ORDER]; for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) { - FIXP_DBL tmp1, tmp2; - - tmp1 = f1[i] >> 1; - tmp2 = f2[i] >> 1; - - aDBL[i - 1] = (tmp1 + tmp2); - aDBL[k] = (tmp1 - tmp2); + aDBL[i - 1] = f1[i] + f2[i]; + aDBL[k] = f1[i] - f2[i]; } int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER); @@ -1193,5 +1191,5 @@ void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) { a[i] = FX_DBL2FX_LPC(aDBL[i] << headroom_a); } - *a_exp = 8 - headroom_a; + *a_exp = SF_F + (2 - 1) - headroom_a; } -- cgit v1.2.3 From 3c377e33055267a007566a550820ae1cdb135331 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:02:46 +0200 Subject: Prevent signed integer overflow in RE8_PPV(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ic66ac4742d8e466431c5cf09d02b0d9c7f842df2 --- libAACdec/src/usacdec_lpc.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libAACdec/src/usacdec_lpc.cpp b/libAACdec/src/usacdec_lpc.cpp index 278afbe..d726798 100644 --- a/libAACdec/src/usacdec_lpc.cpp +++ b/libAACdec/src/usacdec_lpc.cpp @@ -231,7 +231,7 @@ void nearest_neighbor_2D8(FIXP_ZF x[8], int y[8]) { void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) { int i, y0[8], y1[8]; FIXP_ZF x1[8], tmp; - FIXP_DBL e; + INT64 e; /* find the nearest neighbor y0 of x in 2D8 */ nearest_neighbor_2D8(x, y0); @@ -245,16 +245,16 @@ void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) { } /* compute e0=||x-y0||^2 and e1=||x-y1||^2 */ - e = (FIXP_DBL)0; + e = 0; for (i = 0; i < 8; i++) { tmp = x[i] - INT2ZF(y0[i], 0); - e += fPow2Div2( + e += (INT64)fPow2Div2( tmp << r); /* shift left to ensure that no fract part bits get lost. */ tmp = x[i] - INT2ZF(y1[i], 0); - e -= fPow2Div2(tmp << r); + e -= (INT64)fPow2Div2(tmp << r); } /* select best candidate y0 or y1 to minimize distortion */ - if (e < (FIXP_DBL)0) { + if (e < 0) { for (i = 0; i < 8; i++) { y[i] = y0[i]; } -- cgit v1.2.3 From 2152ae1a5ef0511e0b38a981745eb910f2af9bca Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 20 Sep 2019 14:03:40 +0200 Subject: Suppress integer overflow in lsf_weight_2st() by using 64 bit multiplication with explicit 32 bit integer result. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I82ce4858688e90abee0c44c4ada34a9a7b08342f --- libAACdec/src/usacdec_lpc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libAACdec/src/usacdec_lpc.cpp b/libAACdec/src/usacdec_lpc.cpp index d726798..88601b7 100644 --- a/libAACdec/src/usacdec_lpc.cpp +++ b/libAACdec/src/usacdec_lpc.cpp @@ -565,7 +565,8 @@ static void lsf_weight_2st(FIXP_LPC *lsfq, FIXP_DBL *xq, int nk_mode) { /* add non-weighted residual LSF vector to LSF1st */ for (i = 0; i < M_LP_FILTER_ORDER; i++) { w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1]))); - lsfq[i] = fAddSaturate(lsfq[i], FX_DBL2FX_LPC((FIXP_DBL)(w * (LONG)xq[i]))); + lsfq[i] = fAddSaturate(lsfq[i], + FX_DBL2FX_LPC((FIXP_DBL)((INT64)w * (LONG)xq[i]))); } return; -- cgit v1.2.3 From a7029823f4836a4e8564b636d43e4ebd202f3ec0 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:02:38 +0200 Subject: Prevent integer overflow in sbrDecoder_calculateGainVec(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I359f7f976a5ad5459be7d7b786145988a175e305 --- libSBRdec/src/HFgen_preFlat.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libSBRdec/src/HFgen_preFlat.cpp b/libSBRdec/src/HFgen_preFlat.cpp index 96adbb9..268011e 100644 --- a/libSBRdec/src/HFgen_preFlat.cpp +++ b/libSBRdec/src/HFgen_preFlat.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -904,23 +904,24 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, } if (maxVal != FL2FX_DBL(0.0f)) { - reserve = fixMax(0, CntLeadingZeros(maxVal) - 2); + reserve = CntLeadingZeros(maxVal) - 2; } nrg_ov = nrg = (FIXP_DBL)0; if (scale_nrg_ov > -31) { for (i = startSample; i < overlap; i++) { - nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> - sum_scale_ov; + nrg_ov += + (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) + + fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >> + sum_scale_ov; } } else { scale_nrg_ov = 0; } if (scale_nrg > -31) { for (i = overlap; i < stopSample; i++) { - nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> + nrg += (fPow2Div2(scaleValue(sourceBufferReal[i][loBand], reserve)) + + fPow2Div2(scaleValue(sourceBufferImag[i][loBand], reserve))) >> sum_scale; } } else { -- cgit v1.2.3 From 9ba6f8b6a21cca4a4f89d0202af501fd3a67e144 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:02:58 +0200 Subject: Fix signed integer overflow in calcFactorPerBand() calculation. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I9f18f675112651be8dec5c0474601ca6531fbf15 --- libSBRdec/src/sbrdec_freq_sca.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libSBRdec/src/sbrdec_freq_sca.cpp b/libSBRdec/src/sbrdec_freq_sca.cpp index 165f94b..e187656 100644 --- a/libSBRdec/src/sbrdec_freq_sca.cpp +++ b/libSBRdec/src/sbrdec_freq_sca.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -230,6 +230,8 @@ static UCHAR getStopBand( } } + stopMin = fMin(stopMin, 64); + /* Choose a stop band between k1 and 64 depending on stopFreq (0..13), based on a logarithmic scale. @@ -523,7 +525,8 @@ static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) { step = FL2FXCONST_DBL(0.0f); } } - return FX_DBL2FX_SGL(bandfactor << 1); + return (bandfactor >= FL2FXCONST_DBL(0.5)) ? (FIXP_SGL)MAXVAL_SGL + : FX_DBL2FX_SGL(bandfactor << 1); } /*! -- cgit v1.2.3 From ea9d3a049b7b3bb1a9523fe8cf79375140856359 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:03:21 +0200 Subject: Prevent signed integer overflow in filtLP(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I8da32f4794274e2955936ccd42c009485fbe1972 --- libAACdec/src/usacdec_lpd.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index e0a2631..fa68ccb 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -130,9 +130,10 @@ void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, for (i = 0; i < stop; i++) { tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16 for (j = 1; j <= len; j++) { - tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]); + tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]); } - syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp)); + syn_out[i] = (FIXP_PCM)(SATURATE_SHIFT( + (syn[i] >> 1) - (tmp >> 1), (MDCT_OUTPUT_SCALE - 1), PCM_OUT_BITS)); } } -- cgit v1.2.3 From f22eb9c1fa5bc594e6468a00566c11fc00654394 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:03:39 +0200 Subject: Avoid signed integer overflow in bass_pf_1sf_delay(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I67bfab71987b31601a4666c8cf292f71bcb6799a --- libAACdec/src/usacdec_lpd.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index fa68ccb..5c3426d 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -336,17 +336,22 @@ void bass_pf_1sf_delay( { for (i = 0; i < lg; i++) { - /* scaled with SF_SYNTH + gain_sf + 1 */ + /* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2: + * one additional shift of syn values + fMult => fMultDiv2 */ noise_in[i] = - (fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) - - (syn[i + i_subfr + T] >> 1))) >> - s1; + scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) - + (syn[i + i_subfr - T] >> 2) - + (syn[i + i_subfr + T] >> 2)), + 2 - s1); } for (i = lg; i < L_SUBFR; i++) { - /* scaled with SF_SYNTH + gain_sf + 1 */ + /* scaled with SF_SYNTH + gain_sf + 1; composition of scalefactor 2: + * one additional shift of syn values + fMult => fMultDiv2 */ noise_in[i] = - (fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1; + scaleValue(fMultDiv2(gainSGL, (syn[i + i_subfr] >> 1) - + (syn[i + i_subfr - T] >> 1)), + 2 - s1); } } } else { -- cgit v1.2.3 From 3634955ca5efcfe7a8565ef1ba676531b3123ca1 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:03:59 +0200 Subject: Fix integer overflow in complex multiplication called from CLpd_FAC_Acelp2Mdct(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I7cd234698821cf13b163d323cfd90fdccaaec3c1 --- libAACdec/src/usacdec_fac.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libAACdec/src/usacdec_fac.cpp b/libAACdec/src/usacdec_fac.cpp index 0d3d844..0e28fbb 100644 --- a/libAACdec/src/usacdec_fac.cpp +++ b/libAACdec/src/usacdec_fac.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -668,9 +668,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(-x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(-x1); pOut0++; pOut1--; } @@ -680,9 +680,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } @@ -691,9 +691,9 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, for (i = 0; i < fl / 2; i++) { FIXP_DBL x0, x1; - cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]); - *pOut0 = IMDCT_SCALE_DBL(x0); - *pOut1 = IMDCT_SCALE_DBL(x1); + cplxMultDiv2(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]); + *pOut0 = IMDCT_SCALE_DBL_LSH1(x0); + *pOut1 = IMDCT_SCALE_DBL_LSH1(x1); pOut0++; pOut1--; } -- cgit v1.2.3 From 920ecc7487645192e9b9dee7c5261b5ff8b81be9 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:04:15 +0200 Subject: Prevent signed integer overflows in CLpd_FAC_Acelp2Mdct(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I216f97b0c75a9076f3963036b098af37b390c5bb --- libAACdec/src/usacdec_fac.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libAACdec/src/usacdec_fac.cpp b/libAACdec/src/usacdec_fac.cpp index 0e28fbb..3c0b1ce 100644 --- a/libAACdec/src/usacdec_fac.cpp +++ b/libAACdec/src/usacdec_fac.cpp @@ -493,9 +493,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, /* Div2 is compensated by table scaling */ x = fMultDiv2(pTmp2[i], FacWindowZir[w]); x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]); - x += pFAC_and_FAC_ZIR[i]; - pOut1[i] = x; - + pOut1[i] = fAddSaturate(x, pFAC_and_FAC_ZIR[i]); w++; } } @@ -552,7 +550,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, FDK_ASSERT((pOut1 >= hMdct->overlap.time && pOut1 < hMdct->overlap.time + hMdct->ov_size) || (pOut1 >= output && pOut1 < output + 1024)); - *pOut1 += IMDCT_SCALE_DBL(-x1); + *pOut1 = fAddSaturate(*pOut1, IMDCT_SCALE_DBL(-x1)); pOut1--; } @@ -578,7 +576,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, FIXP_DBL x = -(*pCurr--); /* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */ if (i < f_len) { - x += *pF++; + x = fAddSaturate(x, *pF++); } FDK_ASSERT((pOut1 >= hMdct->overlap.time && @@ -705,7 +703,7 @@ INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec, FIXP_DBL *pOut = pOut0 - fl / 2; FDK_ASSERT(fl / 2 <= 128); for (i = 0; i < fl / 2; i++) { - pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]); + pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i])); } hMdct->pFacZir = NULL; } -- cgit v1.2.3 From b8f7bab39cf4b3c97bbca9c3461e7c047a20d4ab Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:04:32 +0200 Subject: Fix integer overflow in imlt_block(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ia7e03bbf6daef61079514de407a5900f6dc22a21 --- libFDK/src/mdct.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libFDK/src/mdct.cpp b/libFDK/src/mdct.cpp index d697cfb..0062b27 100644 --- a/libFDK/src/mdct.cpp +++ b/libFDK/src/mdct.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -569,7 +569,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, */ for (i = 0; i < hMdct->prev_nr; i++) { FIXP_DBL x = -(*pOvl--); - *pOut0 = IMDCT_SCALE_DBL(x + hMdct->pFacZir[i]); + *pOut0 = fAddSaturate(x, IMDCT_SCALE_DBL(hMdct->pFacZir[i])); pOut0++; } hMdct->pFacZir = NULL; @@ -678,7 +678,7 @@ INT imlt_block(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *spectrum, FIXP_DBL *pOut = pOut0 - fl / 2; FDK_ASSERT(fl / 2 <= 128); for (i = 0; i < fl / 2; i++) { - pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]); + pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i])); } hMdct->pFacZir = NULL; } -- cgit v1.2.3 From ade11a1d6f3954ded789afcdac8ef4c80f9bb2f9 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:04:50 +0200 Subject: Prevent signed integer overflows in CLpd_FAC_Mdct2Acelp(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I348fe4be577ac39f961352902d138a8e07982096 --- libAACdec/src/usacdec_fac.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libAACdec/src/usacdec_fac.cpp b/libAACdec/src/usacdec_fac.cpp index 3c0b1ce..b246171 100644 --- a/libAACdec/src/usacdec_fac.cpp +++ b/libAACdec/src/usacdec_fac.cpp @@ -344,7 +344,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac, /* Overlap Add */ x0 = -fMult(*pOvl--, pWindow[i].v.re); - *pOut0 += IMDCT_SCALE_DBL(x0); + *pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0)); pOut0++; } } else { @@ -354,7 +354,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac, /* Overlap Add */ x0 = fMult(*pOvl--, pWindow[i].v.re); - *pOut0 += IMDCT_SCALE_DBL(x0); + *pOut0 = fAddSaturate(*pOut0, IMDCT_SCALE_DBL(x0)); pOut0++; } } @@ -362,7 +362,7 @@ INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac, 0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */ FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */ for (i = 0; i < fl / 2; i++) { - pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]); + pOut[i] = fAddSaturate(pOut[i], IMDCT_SCALE_DBL(hMdct->pFacZir[i])); } hMdct->pFacZir = NULL; } -- cgit v1.2.3 From 54cd15bd807a69a7d68cbb414b8a3ea4b280748f Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:05:11 +0200 Subject: Fix nrgGain_e update in equalizeFiltBufferExp(). Prevents negative shift exponents in calculateSbrEnvelope(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I66ad54dae0fa1d414d8b2b9a9e0b6145cce4042d --- libSBRdec/src/env_calc.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index c34ce96..5cfd56c 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -1831,7 +1831,8 @@ static void equalizeFiltBufferExp( diff = (int)(nrgGain_e[band] - filtBuffer_e[band]); if (diff > 0) { filtBuffer[band] >>= - diff; /* Compensate for the scale change by shifting the mantissa. */ + fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by + shifting the mantissa. */ filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ } else if (diff < 0) { /* The buffered gains seem to be larger, but maybe there @@ -1851,8 +1852,8 @@ static void equalizeFiltBufferExp( filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ /* For the remaining difference, change the new gain value */ - diff = fixMin(-(reserve + diff), DFRACT_BITS - 1); - nrgGain[band] >>= diff; + diff = -(reserve + diff); + nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1); nrgGain_e[band] += diff; } } -- cgit v1.2.3 From b2f2a109d3546a1f412fda3a3f41abc6bdb4f949 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:05:33 +0200 Subject: Limit too large shift value in apply_inter_tes(). Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I38cc7053e671f6e20a1a9ba4f1645d1cf8be77e2 --- libSBRdec/src/env_calc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 5cfd56c..41c9e88 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -739,7 +739,8 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf); total_power_high_after_sf = new_summand_sf; } else if (new_summand_sf < total_power_high_after_sf) { - subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf; + subsample_power_high[i] >>= + fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf); } total_power_high_after += subsample_power_high[i] >> preShift2; } -- cgit v1.2.3 From 418526638abb80291feb502b91d13b52aaa2dc9d Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 18 Oct 2019 14:05:57 +0200 Subject: Initialize scale variable in qmfForwardModulationLP_even() and qmfInverseModulationLP_even() which is updated in dct/fft processing. Bug: 131430997 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Id294afb1ac740abf6000d7286e0f95c8b13a7eb8 --- libFDK/src/qmf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp index 6fca043..69f7e05 100644 --- a/libFDK/src/qmf.cpp +++ b/libFDK/src/qmf.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -244,7 +244,7 @@ static void qmfForwardModulationLP_even( int i; int L = anaQmf->no_channels; int M = L >> 1; - int scale; + int scale = 0; FIXP_DBL accu; const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M]; @@ -603,7 +603,7 @@ inline static void qmfInverseModulationLP_even( int i; int L = synQmf->no_channels; int M = L >> 1; - int scale; + int scale = 0; FIXP_DBL tmp; FIXP_DBL *RESTRICT tReal = pTimeOut; FIXP_DBL *RESTRICT tImag = pTimeOut + L; -- cgit v1.2.3 From fc8faa38d90380adfb61b2b280a36c73369c9aff Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Mon, 21 Oct 2019 14:52:48 -0700 Subject: FDK: USAC CLpd_Reset uses rate constants Use constants defined in libAACdec/src/usacdec_const.h Test: atest DecoderTestXheAac Change-Id: Idf1aa9fefb92b1abf64f50b044b2490b0d31b426 --- libAACdec/src/usacdec_lpd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index 5c3426d..de0c2de 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -1228,7 +1228,7 @@ AAC_DECODER_ERROR CLpdChannelStream_Read( (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM - (INT)PIT_MIN_12k8; - if ((samplingRate < 6000) || (samplingRate > 24000)) { + if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) { error = AAC_DEC_PARSE_ERROR; goto bail; } -- cgit v1.2.3 From 07b5fd99418373e7c622030735bd47a0b153a9ec Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:05:02 +0100 Subject: Use one additional bit headroom to prevent signed integer overflow in BuildAdaptiveExcitation(). Bug: 145666984 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I5c881238562c3d9f7cd8d77a8c52f7231126587f --- libAACdec/src/usacdec_acelp.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp index 1ac8c9f..a8dadc0 100644 --- a/libAACdec/src/usacdec_acelp.cpp +++ b/libAACdec/src/usacdec_acelp.cpp @@ -465,7 +465,9 @@ void BuildAdaptiveExcitation( /* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory! If exc2[i] is written, code[i] will be destroyed! */ -#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC) +#define SF_HEADROOM (1) +#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM) +#define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM) int i; FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth; @@ -477,8 +479,8 @@ void BuildAdaptiveExcitation( cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f); /* u'(n) */ - tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */ - *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF); + tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */ + *exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM; /* u(n) */ code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed) @@ -487,15 +489,15 @@ void BuildAdaptiveExcitation( code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */ tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */ cpe_code_smooth = fMultDiv2(cpe, code_smooth); - *exc2++ = tmp - cpe_code_smooth; + *exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM; cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev); i = L_SUBFR - 2; do /* ARM926: 22 cycles per iteration */ { /* u'(n) */ - tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); - *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF); + tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); + *exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM; /* u(n) */ tmp += code_smooth; /* += g_sc * c(i) */ tmp -= cpe_code_smooth_prev; @@ -503,16 +505,17 @@ void BuildAdaptiveExcitation( code_i = *code++; code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; cpe_code_smooth = fMultDiv2(cpe, code_smooth); - *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */ + *exc2++ = (tmp - cpe_code_smooth) + << SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */ } while (--i != 0); /* u'(n) */ - tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); - *exc = tmp + (fMultDiv2(code_i, gain_code) << SF); + tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); + *exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM; /* u(n) */ tmp += code_smooth; tmp -= cpe_code_smooth_prev; - *exc2++ = tmp; + *exc2++ = tmp << SF_HEADROOM; return; } -- cgit v1.2.3 From 5838a313ae49b81dfc377d4c4ef45c34239d3495 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:05:18 +0100 Subject: Fix signed integer overflow in pvcDecodeTimeSlot(). Bug: 145668022 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I0a165330cf174f24310f8d705523d310a3522e7a --- libSBRdec/src/pvc_dec.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libSBRdec/src/pvc_dec.cpp b/libSBRdec/src/pvc_dec.cpp index b477122..e1e3c2c 100644 --- a/libSBRdec/src/pvc_dec.cpp +++ b/libSBRdec/src/pvc_dec.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -534,7 +534,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) { for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) { /* The division by 8 == (RATE*lbw) is required algorithmically */ - E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2; + E[ksg] += + ((fPow2Div2(qmfR[band]) >> 1) + (fPow2Div2(qmfI[band]) >> 1)) >> 3; } } } @@ -542,7 +543,7 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, if (E[ksg] > (FIXP_DBL)0) { /* 10/log2(10) = 0.752574989159953 * 2^2 */ int exp_log; - FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log); + FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent + 2, &exp_log); nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC)); nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2); pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP))); @@ -603,22 +604,22 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, E_high_exp[ksg] = 0; /* residual part */ - accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP + + accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP - 2 + pPvcDynamicData->pScalingCoef[3]); /* linear combination of lower grouped energies part */ for (kb = 0; kb < PVC_NBLOW; kb++) { predCoeff = (FIXP_SGL)( (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8); - predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] + - 1; /* +1 to compensate for Div2 */ - accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp; + predCoeff_exp = -(pPvcDynamicData->pScalingCoef[kb] + 1 - + 2); /* +1 to compensate for Div2; -2 for accu */ + accu += fMultDiv2(E[kb], predCoeff) >> predCoeff_exp; } /* convert back to linear domain */ accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV)); - accu = f2Pow( - accu, PVC_ESG_EXP - 1, - &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */ + accu = f2Pow(accu, PVC_ESG_EXP - 1 + 2, + &predCoeff_exp); /* -1 compensates for exponent of + LOG10FAC_INV; +2 for accu */ predictedEsgSlot[ksg] = accu; E_high_exp[ksg] = predCoeff_exp; if (predCoeff_exp > E_high_exp_max) { @@ -628,8 +629,8 @@ void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, /* rescale output vector according to largest exponent */ for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) { - int scale = E_high_exp[ksg] - E_high_exp_max; - predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale); + int scale = fMin(E_high_exp_max - E_high_exp[ksg], DFRACT_BITS - 1); + predictedEsgSlot[ksg] = predictedEsgSlot[ksg] >> scale; } *predictedEsg_exp = E_high_exp_max; } -- cgit v1.2.3 From 2ce3e76d0fd843e1cede9c747392b716039db596 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:05:40 +0100 Subject: Improve robustness of limiter band table calculation in ResetLimiterBands(). Bug: 145668973 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ic076cf5b44c0618734064b670de61f9da532a13e --- libSBRdec/src/env_calc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 41c9e88..23ad509 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -3144,6 +3144,11 @@ ResetLimiterBands( return SBRDEC_UNSUPPORTED_CONFIG; } + /* Restrict maximum value of limiter band table */ + if (workLimiterBandTable[tempNoLim] > highSubband) { + return SBRDEC_UNSUPPORTED_CONFIG; + } + /* Copy limiterbands from working buffer into final destination */ for (k = 0; k <= nBands; k++) { limiterBandTable[k] = workLimiterBandTable[k]; -- cgit v1.2.3 From 68cdcfc6b82f88ed1f616b7e3a0133b0072f4bf4 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:06:00 +0100 Subject: Avoid signed integer overflows in multiple adjustTimeSlot*() functions. Bug: 145669628 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Id0f3ee9d3413e534505c0c7eea379ce42880ca79 --- libSBRdec/src/env_calc.cpp | 97 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 23ad509..81f03f3 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -151,6 +151,9 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" /* need FDKpow() for debug outputs */ +#define MAX_SFB_NRG_HEADROOM (1) +#define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM)) + typedef struct { FIXP_DBL nrgRef[MAX_FREQ_COEFFS]; FIXP_DBL nrgEst[MAX_FREQ_COEFFS]; @@ -986,7 +989,8 @@ void calculateSbrEnvelope( */ if (!useLP) adj_e = h_sbr_cal_env->filtBufferNoise_e - - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); + getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) + + (INT)MAX_SFB_NRG_HEADROOM; /* Scan for maximum reference energy to be able @@ -1006,7 +1010,7 @@ void calculateSbrEnvelope( - Smoothing can smear high gains of the previous envelope into the current */ - maxSfbNrg_e += 6; + maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); adj_e = maxSfbNrg_e; // final_e should not exist for PVC fixfix framing @@ -1032,7 +1036,7 @@ void calculateSbrEnvelope( - Smoothing can smear high gains of the previous envelope into the current */ - maxSfbNrg_e += 6; + maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM); if (borders[i] < hHeaderData->numberTimeSlots) /* This envelope affects timeslots that belong to the output frame */ @@ -2426,6 +2430,9 @@ static void adjustTimeSlot_EldGrid( const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0]; const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0]; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; + *(ptrReal - 1) = fAddSaturate( *(ptrReal - 1), SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]), @@ -2438,7 +2445,8 @@ static void adjustTimeSlot_EldGrid( FIXP_DBL sineLevel_curr = *pSineLevel++; phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sbNoise = *pNoiseLevel++; if (((INT)sineLevel_curr | noNoiseFlag) == 0) { signalReal += @@ -2472,7 +2480,8 @@ static void adjustTimeSlot_EldGrid( FIXP_DBL sineLevel_curr = *pSineLevel++; phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sbNoise = *pNoiseLevel++; if (((INT)sineLevel_curr | noNoiseFlag) == 0) { signalReal += @@ -2512,6 +2521,8 @@ static void adjustTimeSlotLC( FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; int tone_count = 0; int sineSign = 1; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f)) #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f)) @@ -2527,7 +2538,8 @@ static void adjustTimeSlotLC( of the signal and should be carried out with full accuracy (supplying #FRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; sineLevel = *pSineLevel++; sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); @@ -2555,10 +2567,10 @@ static void adjustTimeSlotLC( /* save switch and compare operations and reduce to XOR statement */ if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) { - *(ptrReal - 1) += tmp1; + *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1); signalReal -= tmp2; } else { - *(ptrReal - 1) -= tmp1; + *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1); signalReal += tmp2; } *ptrReal++ = signalReal; @@ -2589,7 +2601,9 @@ static void adjustTimeSlotLC( /* The next multiplication constitutes the actual envelope adjustment of * the signal. */ - signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal += + fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; pNoiseLevel++; *ptrReal++ = signalReal; @@ -2602,7 +2616,8 @@ static void adjustTimeSlotLC( index++; /* The next multiplication constitutes the actual envelope adjustment of * the signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val) + << scale_change; if (*pSineLevel++ != FL2FXCONST_DBL(0.0f)) tone_count++; @@ -2630,7 +2645,8 @@ static void adjustTimeSlotLC( index++; /* The next multiplication constitutes the actual envelope adjustment of the * signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change); + signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val) + << scale_change; sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f)); sineLevel = pSineLevel[0]; @@ -2699,6 +2715,9 @@ static void adjustTimeSlotHQ_GainAndNoise( /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; int index = *ptrPhaseIndex; int shift; + FIXP_DBL max_val_noise = 0, min_val_noise = 0; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); @@ -2708,6 +2727,8 @@ static void adjustTimeSlotHQ_GainAndNoise( shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); } else { shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); + max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; + min_val_noise = -max_val_noise; } if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { @@ -2723,8 +2744,10 @@ static void adjustTimeSlotHQ_GainAndNoise( smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + fMult(direct_ratio, noiseLevel[k]); } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); + smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); + smoothedNoise = + (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + + fMult(direct_ratio, noiseLevel[k]); } /* @@ -2732,8 +2755,12 @@ static void adjustTimeSlotHQ_GainAndNoise( of the signal and should be carried out with full accuracy (supplying #DFRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2755,8 +2782,12 @@ static void adjustTimeSlotHQ_GainAndNoise( } else { for (k = 0; k < noSubbands; k++) { smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2862,6 +2893,9 @@ static void adjustTimeSlotHQ( int freqInvFlag = (lowSubband & 1); FIXP_DBL sineLevel; int shift; + FIXP_DBL max_val_noise = 0, min_val_noise = 0; + const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change; + const FIXP_DBL min_val = -max_val; *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); *ptrHarmIndex = (harmIndex + 1) & 3; @@ -2877,10 +2911,13 @@ static void adjustTimeSlotHQ( filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */ - if (filtBufferNoiseShift < 0) + if (filtBufferNoiseShift < 0) { shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); - else + } else { shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); + max_val_noise = MAX_VAL_NRG_HEADROOM >> shift; + min_val_noise = -max_val_noise; + } if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { for (k = 0; k < noSubbands; k++) { @@ -2896,8 +2933,10 @@ static void adjustTimeSlotHQ( smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + fMult(direct_ratio, noiseLevel[k]); } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); + smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]); + smoothedNoise = + (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) + + fMult(direct_ratio, noiseLevel[k]); } /* @@ -2905,8 +2944,12 @@ static void adjustTimeSlotHQ( of the signal and should be carried out with full accuracy (supplying #DFRACT_BITS valid bits). */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; @@ -2959,8 +3002,12 @@ static void adjustTimeSlotHQ( } else { for (k = 0; k < noSubbands; k++) { smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; + signalReal = + fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val) + << scale_change; + signalImag = + fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val) + << scale_change; index++; -- cgit v1.2.3 From 089d368ddb5ce41c397fdd05034a1e67d519b836 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:06:16 +0100 Subject: Prevent signed integer overflows in ELD filterbank, multE2_DinvF_fdk(). Bug: 145669388 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iaba69b58666833c90e05b296c502ba6509a087a9 --- libAACdec/src/ldfiltbank.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libAACdec/src/ldfiltbank.cpp b/libAACdec/src/ldfiltbank.cpp index c7d2928..1898557 100644 --- a/libAACdec/src/ldfiltbank.cpp +++ b/libAACdec/src/ldfiltbank.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -131,10 +131,12 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, FIXP_DBL z0, z2, tmp; z2 = x[N / 2 + i]; - z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)); + z0 = fAddSaturate(z2, + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1))); - z[N / 2 + i] = x[N / 2 - 1 - i] + - (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)); + z[N / 2 + i] = fAddSaturate( + x[N / 2 - 1 - i], + (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1))); tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N + N / 2 + i])); @@ -159,10 +161,12 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, FIXP_DBL z0, z2, tmp0, tmp1; z2 = x[N / 2 + i]; - z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1)); + z0 = fAddSaturate(z2, + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1))); - z[N / 2 + i] = x[N / 2 - 1 - i] + - (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1)); + z[N / 2 + i] = fAddSaturate( + x[N / 2 - 1 - i], + (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1))); tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N / 2 + i])); -- cgit v1.2.3 From 24171ed080e447c3ed01643833ba711dcae91293 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:06:56 +0100 Subject: Add loop abort criterion to prevent timeout in EldSpecificConfig_Parse(). Bug: 145668344 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iea6457e8545438c7ad4d05a682ffa656ec35ead9 --- libMpegTPDec/src/tpdec_asc.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index ad13378..82f840e 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1325,9 +1325,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, CSTpCallBacks *cb) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; CSEldSpecificConfig *esc = &asc->m_sc.m_eldSpecificConfig; - ASC_ELD_EXT_TYPE eldExtType; + UINT eldExtType; int eldExtLen, len, cnt, ldSbrLen = 0, eldExtLenSum, numSbrHeader = 0, - sbrIndex; + sbrIndex, eldExtCnt = 0; unsigned char downscale_fill_nibble; @@ -1394,9 +1394,8 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, eldExtLenSum = FDKgetValidBits(hBs); esc->m_downscaledSamplingFrequency = asc->m_samplingFrequency; /* parse ExtTypeConfigData */ - while ( - ((eldExtType = (ASC_ELD_EXT_TYPE)FDKreadBits(hBs, 4)) != ELDEXT_TERM) && - ((INT)FDKgetValidBits(hBs) >= 0)) { + while (((eldExtType = FDKreadBits(hBs, 4)) != ELDEXT_TERM) && + ((INT)FDKgetValidBits(hBs) >= 0) && (eldExtCnt++ < 15)) { eldExtLen = len = FDKreadBits(hBs, 4); if (len == 0xf) { len = FDKreadBits(hBs, 8); @@ -1455,6 +1454,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, break; } } + if (eldExtType != ELDEXT_TERM) { + return TRANSPORTDEC_PARSE_ERROR; + } if ((INT)FDKgetValidBits(hBs) < 0) { return TRANSPORTDEC_PARSE_ERROR; -- cgit v1.2.3 From ee6c6fa4ba104941150998d53792af80ab9b3b5a Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:07:10 +0100 Subject: Fix dry and wet energy initialization in subbandTPInit(). Bug: 145668025 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iadf5d4ebcecfa544b688a69d569ad515c0affade --- libSACdec/src/sac_stp.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp index 818e9df..17e4472 100644 --- a/libSACdec/src/sac_stp.cpp +++ b/libSACdec/src/sac_stp.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -305,12 +305,10 @@ SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) { for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) { self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE)); - self->oldWetEnerLD64[ch] = - FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */ + self->oldWetEnerLD64[ch] = FL2FXCONST_DBL(0.0); } for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) { - self->oldDryEnerLD64[ch] = - FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */ + self->oldDryEnerLD64[ch] = FL2FXCONST_DBL(0.0); } self->BP = BP__FDK; -- cgit v1.2.3 From 110e4ca996edb074e2b0071d63472bf26f0a6dd8 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:07:42 +0100 Subject: Avoid signed integer overflow in subbandTPApply() dry energy calculation. Bug: 145668819 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I4f61efa70e77ae64b99fe7cafbc2b43f5cc09b06 --- libSACdec/src/sac_stp.cpp | 61 +++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp index 17e4472..b6e5947 100644 --- a/libSACdec/src/sac_stp.cpp +++ b/libSACdec/src/sac_stp.cpp @@ -106,6 +106,8 @@ amm-info@iis.fraunhofer.de #include "FDK_matrixCalloc.h" #include "sac_rom.h" +#define SF_FREQ_DOMAIN_HEADROOM (2 * (1)) + #define BP_GF_START 6 #define BP_GF_SIZE 25 #define HP_SIZE 9 @@ -114,6 +116,11 @@ amm-info@iis.fraunhofer.de #define SF_WET 5 #define SF_DRY \ 3 /* SF_DRY == 2 would produce good conformance test results as well */ +#define SF_DRY_NRG \ + (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \ + i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \ + calculation needs 4 bits headroom, headroom can be reduced by 1 \ + bit due to fPow2Div2() usage */ #define SF_PRODUCT_BP_GF 13 #define SF_PRODUCT_BP_GF_GF 26 #define SF_SCALE 2 @@ -172,18 +179,8 @@ amm-info@iis.fraunhofer.de STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO) */ -#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx - #define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx -#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \ - DryEner += \ - fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2) - -#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \ - DryEner += fMultDiv2( \ - fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n]) - #define CALC_WET_SCALE(dryIdx, wetIdx) \ if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \ scale[wetIdx] = STP_SCALE_LIMIT_HI; \ @@ -362,7 +359,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { { cplxBands = BP_GF_SIZE; cplxHybBands = self->hybridBands; - dry_scale_dmx = (2 * SF_DRY) - 2; + if (self->treeConfig == TREE_212) { + dry_scale_dmx = 2; /* 2 bits to compensate fMultDiv2() and fPow2Div2() + used in energy calculation */ + } else { + dry_scale_dmx = (2 * SF_DRY) - 2; + } wet_scale_dmx = 2; } @@ -409,12 +411,33 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { pBP = hStpDec->BP_GF - BP_GF_START; switch (self->treeConfig) { case TREE_212: + INT sMin, sNorm, sReal, sImag; + + sReal = fMin(getScalefactor(&qmfOutputRealDry[i_LF][BP_GF_START], + cplxBands - BP_GF_START), + getScalefactor(&qmfOutputRealDry[i_RF][BP_GF_START], + cplxBands - BP_GF_START)); + sImag = fMin(getScalefactor(&qmfOutputImagDry[i_LF][BP_GF_START], + cplxBands - BP_GF_START), + getScalefactor(&qmfOutputImagDry[i_RF][BP_GF_START], + cplxBands - BP_GF_START)); + sMin = fMin(sReal, sImag) - 1; + for (n = BP_GF_START; n < cplxBands; n++) { - dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n]; - dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n]; - DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n); + dmxReal0 = scaleValue(qmfOutputRealDry[i_LF][n], sMin) + + scaleValue(qmfOutputRealDry[i_RF][n], sMin); + dmxImag0 = scaleValue(qmfOutputImagDry[i_LF][n], sMin) + + scaleValue(qmfOutputImagDry[i_RF][n], sMin); + + DryEner0 += (fMultDiv2(fPow2Div2(dmxReal0), pBP[n]) + + fMultDiv2(fPow2Div2(dmxImag0), pBP[n])) >> + SF_DRY_NRG; } - DRY_ENER_WEIGHT(DryEner0); + + sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_DRY_NRG + dry_scale_dmx - + (2 * sMin) + nrgScale; + DryEner0 = scaleValueSaturate( + DryEner0, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1))); break; default:; } @@ -422,7 +445,7 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { /* normalise the 'direct' signals */ for (ch = 0; ch < self->numInputChannels; ch++) { - DryEner[ch] = DryEner[ch] << (nrgScale); + if (self->treeConfig != TREE_212) DryEner[ch] = DryEner[ch] << nrgScale; hStpDec->runDryEner[ch] = fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) + fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]); @@ -434,10 +457,8 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); } } - if (self->treeConfig == TREE_212) { - for (; ch < MAX_INPUT_CHANNELS; ch++) { - DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); - } + for (; ch < MAX_INPUT_CHANNELS; ch++) { + DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); } /* normalise the 'diffuse' signals */ -- cgit v1.2.3 From 7bb841dfb15f20b7068ca429eb888ca31dc57faf Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:07:58 +0100 Subject: Avoid signed integer overflow in subbandTPApply() wet energy calculation. Bug: 145668345 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I92cfb0412d11c8a41431294a2a7fe399dc756f44 --- libSACdec/src/sac_stp.cpp | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp index b6e5947..6ac5a56 100644 --- a/libSACdec/src/sac_stp.cpp +++ b/libSACdec/src/sac_stp.cpp @@ -121,6 +121,11 @@ amm-info@iis.fraunhofer.de i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \ calculation needs 4 bits headroom, headroom can be reduced by 1 \ bit due to fPow2Div2() usage */ +#define SF_WET_NRG \ + (4 - 1) /* 8.495f = sum(BP_GF__FDK[i]) \ + i=0,..,(sizeof(BP_GF__FDK)/sizeof(FIXP_CFG)-1) => energy \ + calculation needs 4 bits headroom, headroom can be reduced by 1 \ + bit due to fPow2Div2() usage */ #define SF_PRODUCT_BP_GF 13 #define SF_PRODUCT_BP_GF_GF 26 #define SF_SCALE 2 @@ -179,8 +184,6 @@ amm-info@iis.fraunhofer.de STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO) */ -#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx - #define CALC_WET_SCALE(dryIdx, wetIdx) \ if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \ scale[wetIdx] = STP_SCALE_LIMIT_HI; \ @@ -390,8 +393,12 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK); } for (ch = 0; ch < self->numOutputChannels; ch++) { - hStpDec->oldWetEnerLD64[ch] = - CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK); + if (self->treeConfig == TREE_212) + hStpDec->oldWetEnerLD64[ch] = + CalcLdData(hStpDec->runWetEner[ch] + ABS_THR__FDK); + else + hStpDec->oldWetEnerLD64[ch] = + CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK); } } else { hStpDec->update_old_ener++; @@ -469,14 +476,30 @@ SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { } WetEnerX = FL2FXCONST_DBL(0.0f); - for (n = BP_GF_START; n < cplxBands; n++) { - tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET); - tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET); - WetEnerX += fMultDiv2(tmp, pBP[n]); - } - WET_ENER_WEIGHT(WetEnerX); - WetEnerX = WetEnerX << (nrgScale); + if (self->treeConfig == TREE_212) { + INT sMin, sNorm; + + sMin = fMin(getScalefactor(&qmfOutputRealWet[ch][BP_GF_START], + cplxBands - BP_GF_START), + getScalefactor(&qmfOutputImagWet[ch][BP_GF_START], + cplxBands - BP_GF_START)); + + for (n = BP_GF_START; n < cplxBands; n++) { + WetEnerX += + (fMultDiv2(fPow2Div2(scaleValue(qmfOutputRealWet[ch][n], sMin)), + pBP[n]) + + fMultDiv2(fPow2Div2(scaleValue(qmfOutputImagWet[ch][n], sMin)), + pBP[n])) >> + SF_WET_NRG; + } + sNorm = SF_FREQ_DOMAIN_HEADROOM + SF_WET_NRG + wet_scale_dmx - + (2 * sMin) + nrgScale; + WetEnerX = scaleValueSaturate( + WetEnerX, fMax(fMin(sNorm, DFRACT_BITS - 1), -(DFRACT_BITS - 1))); + } else + FDK_ASSERT(self->treeConfig == TREE_212); + hStpDec->runWetEner[ch] = fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) + fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX); -- cgit v1.2.3 From c69e4584c375e1426b2c93249197a5b6c9385daf Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:08:53 +0100 Subject: Fix signed integer overflow in DuckerCalcEnergy(). Bug: 145668917 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I9f6458860901fa354a534e8fabe20dfa1a0cf7a9 --- libFDK/src/FDK_decorrelate.cpp | 80 +++++++++++++----------------------------- 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/libFDK/src/FDK_decorrelate.cpp b/libFDK/src/FDK_decorrelate.cpp index c5de79a..324983a 100644 --- a/libFDK/src/FDK_decorrelate.cpp +++ b/libFDK/src/FDK_decorrelate.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) { } #define DUCKER_MAX_NRG_SCALE (24) -#define DUCKER_HEADROOM_BITS (3) +#define DUCKER_HEADROOM_BITS (2) #define FILTER_SF (2) @@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[], dataImagIn += start; dataRealOut += start; dataImagOut += start; -#ifdef FUNCTION_DecorrFilterApplyPASS_func1 - DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut, - dataImagOut, pDelayBuffer, offset); -#else do { FIXP_DBL delay_re, delay_im, real, imag; @@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[], *dataImagOut++ = delay_im; pDelayBuffer += offset; } while (--i != 0); -#endif } } @@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self, FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f); if (maxVal == FL2FXCONST_DBL(-1.0f)) { -#ifdef FUNCTION_DuckerCalcEnergy_func2 - maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand, - maxHybBand, maxHybridBand); -#else - FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f); - for (qs = startHybBand; qs <= maxHybBand; qs++) { - localMaxVal |= fAbs(inputReal[qs]); - localMaxVal |= fAbs(inputImag[qs]); - } - for (; qs <= maxHybridBand; qs++) { - localMaxVal |= fAbs(inputReal[qs]); - } - maxVal = localMaxVal; -#endif + clz = fMin(getScalefactor(&inputReal[startHybBand], + fMax(0, maxHybridBand - startHybBand + 1)), + getScalefactor(&inputImag[startHybBand], + fMax(0, maxHybBand - startHybBand + 1))); + } else { + clz = CntLeadingZeros(maxVal) - 1; } - clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS); - clz = fixMin(clz, DUCKER_MAX_NRG_SCALE); + clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE); *nrgScale = (SCHAR)clz << 1; /* Initialize pb since it would stay uninitialized for the case startHybBand @@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self, pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands); for (qs = startHybBand; qs <= maxHybBand; qs++) { pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); - energy[pb] = - fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) + - fPow2Div2(inputImag[qs] << clz)); + energy[pb] = SATURATE_LEFT_SHIFT( + (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) + + (fPow2Div2(inputImag[qs] << clz) >> 1), + 1, DFRACT_BITS); } pb++; @@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self, maxVal = inputMaxVal; if (maxVal == FL2FXCONST_DBL(-1.0f)) { -#ifdef FUNCTION_DuckerCalcEnergy_func2 - maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand, - maxHybBand, maxHybridBand); -#else - FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f); - for (qs = startHybBand; qs <= maxHybBand; qs++) { - localMaxVal |= fAbs(inputReal[qs]); - localMaxVal |= fAbs(inputImag[qs]); - } - for (; qs <= maxHybridBand; qs++) { - localMaxVal |= fAbs(inputReal[qs]); - } - maxVal = localMaxVal; -#endif + clz = fMin(getScalefactor(&inputReal[startHybBand], + fMax(0, maxHybridBand - startHybBand + 1)), + getScalefactor(&inputImag[startHybBand], + fMax(0, maxHybBand - startHybBand + 1))); + } else { + clz = CntLeadingZeros(maxVal) - 1; } - clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS); - clz = fixMin(clz, DUCKER_MAX_NRG_SCALE); + clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE); *nrgScale = (SCHAR)clz << 1; -#ifdef FUNCTION_DuckerCalcEnergy_func4 - DuckerCalcEnergy_func4(inputReal, inputImag, energy, - self->mapHybBands2ProcBands, clz, startHybBand, - maxHybBand, maxHybridBand); -#else for (qs = startHybBand; qs <= maxHybBand; qs++) { int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); - energy[pb] = - fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) + - fPow2Div2(inputImag[qs] << clz)); + energy[pb] = SATURATE_LEFT_SHIFT( + (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) + + (fPow2Div2(inputImag[qs] << clz) >> 1), + 1, DFRACT_BITS); } for (; qs <= maxHybridBand; qs++) { int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz)); } -#endif /* FUNCTION_DuckerCalcEnergy_func4 */ } { @@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self, } } -#ifdef FUNCTION_DuckerApply_func1 - qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag, - duckGain); -#else /* general gain*output section */ if (qs < hybBands) { /* true for about 39% */ for (; qs < qs_next; qs++) { /* runs about 2 times */ @@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self, outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2; } } -#endif } /* pb */ self->headroomSmoothDirRevNrg = -- cgit v1.2.3 From 801b45ffab8c3ac50c620fd5c6a5818782d2f889 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:09:09 +0100 Subject: Adjust scaling in lppTransposerHBE() to prevent signed integer overflow in autocorrelation. Bug: 145669291 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ia32b081b982d6886f51642a7ed1ca73acb40dac9 --- libSBRdec/src/lpp_tran.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libSBRdec/src/lpp_tran.cpp b/libSBRdec/src/lpp_tran.cpp index 6acb626..93e1158 100644 --- a/libSBRdec/src/lpp_tran.cpp +++ b/libSBRdec/src/lpp_tran.cpp @@ -1014,8 +1014,8 @@ void lppTransposerHBE( pSettings->nCols) + lowBandShift); - dynamicScale = fixMax( - 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */ + dynamicScale = + dynamicScale - 1; /* one additional bit headroom to prevent -1.0 */ /* Scale temporal QMF buffer. @@ -1194,6 +1194,9 @@ void lppTransposerHBE( } else { /* bw <= 0 */ int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); + dynamicScale += + 1; /* prevent negativ scale factor due to 'one additional bit + headroom' */ for (i = startSample; i < stopSample; i++) { FIXP_DBL accu1, accu2; @@ -1210,9 +1213,9 @@ void lppTransposerHBE( dynamicScale; qmfBufferReal[i][loBand] = - (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); + (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << (1 + 1)); qmfBufferImag[i][loBand] = - (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); + (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << (1 + 1)); } } /* bw <= 0 */ -- cgit v1.2.3 From 3700d4ff8fac723f4051a9d53dedae26393a2013 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:09:23 +0100 Subject: Prevent negation of INT_MIN in pcmLimiter_Apply(). Bug: 145668877 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I734f839818f7130615a4438b8831ac664206cc34 --- libPCMutils/src/limiter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libPCMutils/src/limiter.cpp b/libPCMutils/src/limiter.cpp index a799a51..60e3e3b 100644 --- a/libPCMutils/src/limiter.cpp +++ b/libPCMutils/src/limiter.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -239,8 +239,8 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, tmp1 = (FIXP_DBL)0; for (j = 0; j < channels; j++) { tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]); - tmp2 = fAbs(tmp2); - tmp2 = FIXP_DBL(INT(tmp2) ^ INT((tmp2 >> (SAMPLE_BITS_LIM - 1)))); + tmp2 = + (tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2); tmp1 = fMax(tmp1, tmp2); } tmp = fMult(tmp1, additionalGain); -- cgit v1.2.3 From 2334454bc85e205b0d9f23ba6fbd1a966bf2c364 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:09:38 +0100 Subject: Add sanity check for huffman escape sequences in HCR tool. Bug: 145669389 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iaa624f3040269b5c84883bc3ee38cad7cd88e54d --- libAACdec/src/aacdec_hcrs.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libAACdec/src/aacdec_hcrs.cpp b/libAACdec/src/aacdec_hcrs.cpp index d2bc867..44b32a5 100644 --- a/libAACdec/src/aacdec_hcrs.cpp +++ b/libAACdec/src/aacdec_hcrs.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1324,6 +1324,10 @@ UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) { /* count ones and store sum in escapePrefixUp */ if (carryBit == 1) { escapePrefixUp += 1; /* update conter for ones */ + if (escapePrefixUp > 8) { + pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX; + return BODY_SIGN_ESC__ESC_PREFIX; + } /* store updated counter in sideinfo of current codeword */ pEscapeSequenceInfo[codewordOffset] &= -- cgit v1.2.3 From 40c083f59a308efe7d43b498e544756a43579261 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:09:56 +0100 Subject: Avoid negation of INT_MIN in dst_IV(). Bug: 145669114 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I6ddd7a39376c5276ec636572c3bfd4d83d05f9f5 --- libFDK/src/dct.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libFDK/src/dct.cpp b/libFDK/src/dct.cpp index 776493e..bd26736 100644 --- a/libFDK/src/dct.cpp +++ b/libFDK/src/dct.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -489,18 +489,18 @@ void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) { for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) { FIXP_DBL accu1, accu2, accu3, accu4; - accu1 = pDat_1[1]; - accu2 = -pDat_0[0]; - accu3 = pDat_0[1]; - accu4 = -pDat_1[0]; + accu1 = pDat_1[1] >> 1; + accu2 = -(pDat_0[0] >> 1); + accu3 = pDat_0[1] >> 1; + accu4 = -(pDat_1[0] >> 1); cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]); cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]); - pDat_0[0] = accu2 >> 1; - pDat_0[1] = accu1 >> 1; - pDat_1[0] = accu4 >> 1; - pDat_1[1] = -(accu3 >> 1); + pDat_0[0] = accu2; + pDat_0[1] = accu1; + pDat_1[0] = accu4; + pDat_1[1] = -accu3; } if (M & 1) { FIXP_DBL accu1, accu2; -- cgit v1.2.3 From 9d40b65b15c780e8c37be4e5471247b802e20992 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:10:10 +0100 Subject: For all scaleValuesSaturate() variants make source pointer const. Bug: 145669510 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ib69a4f12405026d3165193f0192eb25eaed7e797 --- libFDK/include/scale.h | 8 +++----- libFDK/src/scale.cpp | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/libFDK/include/scale.h b/libFDK/include/scale.h index 655ccaf..a58614e 100644 --- a/libFDK/include/scale.h +++ b/libFDK/include/scale.h @@ -129,15 +129,13 @@ void scaleCplxValues(FIXP_DBL *r_dst, FIXP_DBL *i_dst, const FIXP_DBL *r_src, void scaleValuesWithFactor(FIXP_DBL *vector, FIXP_DBL factor, INT len, INT scalefactor); void scaleValuesSaturate(FIXP_DBL *vector, INT len, INT scalefactor); -void scaleValuesSaturate(FIXP_DBL *dst, FIXP_DBL *src, INT len, +void scaleValuesSaturate(FIXP_DBL *dst, const FIXP_DBL *src, INT len, INT scalefactor); -void scaleValuesSaturate(FIXP_SGL *dst, FIXP_DBL *src, INT len, +void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_DBL *src, INT len, INT scalefactor); -void scaleValuesSaturate(INT_PCM *dst, FIXP_DBL *src, INT len, INT scalefactor); void scaleValuesSaturate(FIXP_SGL *vector, INT len, INT scalefactor); -void scaleValuesSaturate(FIXP_SGL *dst, FIXP_SGL *src, INT len, +void scaleValuesSaturate(FIXP_SGL *dst, const FIXP_SGL *src, INT len, INT scalefactor); -void scaleValuesSaturate(INT_PCM *dst, INT_PCM *src, INT len, INT scalefactor); INT getScalefactorShort(const SHORT *vector, INT len); INT getScalefactorPCM(const INT_PCM *vector, INT len, INT stride); INT getScalefactor(const FIXP_DBL *vector, INT len); diff --git a/libFDK/src/scale.cpp b/libFDK/src/scale.cpp index 24a8a5b..6192170 100644 --- a/libFDK/src/scale.cpp +++ b/libFDK/src/scale.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -250,10 +250,10 @@ void scaleValuesSaturate(FIXP_DBL *vector, /*!< Vector */ */ #define FUNCTION_scaleValuesSaturate_DBL_DBL SCALE_INLINE -void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */ - FIXP_DBL *src, /*!< Input */ - INT len, /*!< Length */ - INT scalefactor /*!< Scalefactor */ +void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */ + const FIXP_DBL *src, /*!< Input */ + INT len, /*!< Length */ + INT scalefactor /*!< Scalefactor */ ) { INT i; @@ -285,10 +285,10 @@ void scaleValuesSaturate(FIXP_DBL *dst, /*!< Output */ */ #define FUNCTION_scaleValuesSaturate_SGL_DBL SCALE_INLINE -void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */ - FIXP_DBL *src, /*!< Input */ - INT len, /*!< Length */ - INT scalefactor) /*!< Scalefactor */ +void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */ + const FIXP_DBL *src, /*!< Input */ + INT len, /*!< Length */ + INT scalefactor) /*!< Scalefactor */ { INT i; scalefactor = fixmax_I(fixmin_I(scalefactor, (INT)DFRACT_BITS - 1), @@ -345,10 +345,10 @@ void scaleValuesSaturate(FIXP_SGL *vector, /*!< Vector */ */ #define FUNCTION_scaleValuesSaturate_SGL_SGL SCALE_INLINE -void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */ - FIXP_SGL *src, /*!< Input */ - INT len, /*!< Length */ - INT scalefactor /*!< Scalefactor */ +void scaleValuesSaturate(FIXP_SGL *dst, /*!< Output */ + const FIXP_SGL *src, /*!< Input */ + INT len, /*!< Length */ + INT scalefactor /*!< Scalefactor */ ) { INT i; -- cgit v1.2.3 From 5357a4411aff621ab7f2e4a2efcffac8673f4987 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:10:23 +0100 Subject: Use saturate shift to prevent signed integer overflow in multiple qmfInverseModulation*() functions. Bug: 145669510 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I4cee10423bc14e3db26de877b5e70701ac3324da --- libFDK/src/qmf.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp index 69f7e05..19f1ea1 100644 --- a/libFDK/src/qmf.cpp +++ b/libFDK/src/qmf.cpp @@ -609,9 +609,9 @@ inline static void qmfInverseModulationLP_even( FIXP_DBL *RESTRICT tImag = pTimeOut + L; /* Move input to output vector with offset */ - scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand); - scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb], - synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand); + scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand); + scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb], + synQmf->usb - synQmf->lsb, scaleFactorHighBand); FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL)); /* Dct type-2 transform */ @@ -662,9 +662,9 @@ inline static void qmfInverseModulationLP_odd( int shift = 0; /* Move input to output vector with offset */ - scaleValues(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand); - scaleValues(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb, - synQmf->usb - synQmf->lsb, scaleFactorHighBand); + scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand); + scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb, + synQmf->usb - synQmf->lsb, scaleFactorHighBand); FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL)); dct_IV(pTimeOut + M, L, &shift); @@ -698,26 +698,27 @@ inline static void qmfInverseModulationHQ( FIXP_DBL *RESTRICT tImag = pWorkBuffer + L; if (synQmf->flags & QMF_FLAG_CLDFB) { - for (i = 0; i < synQmf->lsb; i++) { - cplxMult(&tImag[i], &tReal[i], scaleValue(qmfImag[i], scaleFactorLowBand), - scaleValue(qmfReal[i], scaleFactorLowBand), synQmf->t_cos[i], - synQmf->t_sin[i]); - } - for (; i < synQmf->usb; i++) { - cplxMult(&tImag[i], &tReal[i], - scaleValue(qmfImag[i], scaleFactorHighBand), - scaleValue(qmfReal[i], scaleFactorHighBand), synQmf->t_cos[i], - synQmf->t_sin[i]); + for (i = 0; i < synQmf->usb; i++) { + cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i], + synQmf->t_cos[i], synQmf->t_sin[i]); } + scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1); + scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb, + scaleFactorHighBand + 1); + scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1); + scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb, + scaleFactorHighBand + 1); } if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) { - scaleValues(&tReal[0], &qmfReal[0], synQmf->lsb, (int)scaleFactorLowBand); - scaleValues(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb], - synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand); - scaleValues(&tImag[0], &qmfImag[0], synQmf->lsb, (int)scaleFactorLowBand); - scaleValues(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb], - synQmf->usb - synQmf->lsb, (int)scaleFactorHighBand); + scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, + scaleFactorLowBand); + scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb], + synQmf->usb - synQmf->lsb, scaleFactorHighBand); + scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb, + scaleFactorLowBand); + scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb], + synQmf->usb - synQmf->lsb, scaleFactorHighBand); } FDKmemclear(&tReal[synQmf->usb], -- cgit v1.2.3 From 7104c00b44a4c447bde18d03c8f2e9590706e339 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:10:37 +0100 Subject: Move array definition out of for loop in MPEG-D DRC _skipEqInstructions(). Bug: 145669488 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Icb71fb1cb8e0b64ae969276d08746f687a753467 --- libDRCdec/src/drcDec_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp index a784457..9e37246 100644 --- a/libDRCdec/src/drcDec_reader.cpp +++ b/libDRCdec/src/drcDec_reader.cpp @@ -1018,6 +1018,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs, int additionalDrcSetIdPresent, additionalDrcSetIdCount; int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent, subbandGainsPresent, eqTransitionDurationPresent; + UCHAR eqChannelGroupForChannel[8]; FDKpushFor(hBs, 6); /* eqSetId */ FDKpushFor(hBs, 4); /* eqSetComplexityLevel */ @@ -1067,7 +1068,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs, eqChannelGroupCount = 0; for (c = 0; c < channelCount; c++) { - UCHAR eqChannelGroupForChannel[8]; int newGroup = 1; if (c >= 8) return DE_MEMORY_ERROR; eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7); -- cgit v1.2.3 From 8cd3578cc62fbb9b7c7431bc6e6877da33a41e1b Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:11:02 +0100 Subject: Fix for OPD smoothing in USAC decoder. Bug: 145668878 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I075e3230d53c5a848f93541a9918c5bfaf2df725 --- libSACdec/src/sac_bitdec.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libSACdec/src/sac_bitdec.cpp b/libSACdec/src/sac_bitdec.cpp index 4b47132..4485ccf 100644 --- a/libSACdec/src/sac_bitdec.cpp +++ b/libSACdec/src/sac_bitdec.cpp @@ -1610,6 +1610,10 @@ static SACDEC_ERROR mapIndexData( } /* for( i = 0 ; i < numParameterSets; i++ ) */ if (extendFrame) { + if (paramType == t_IPD) { + llData->bsQuantCoarseXXX[numParameterSets] = + llData->bsQuantCoarseXXX[numParameterSets - 1]; + } for (band = startBand; band < stopBand; band++) { outputDataIdx[xttIdx][numParameterSets][band] = outputDataIdx[xttIdx][numParameterSets - 1][band]; -- cgit v1.2.3 From b10c18741e961015fbded7df2bbf0ec5f799de9e Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 27 Dec 2019 12:56:18 -0800 Subject: Add TEST_MAPPING for aac project Add a TEST_MAPPING file for this project so every change runs all the CTS decoding tests as presubmit. Alternatively this can be used as a convenient way to run all AAC tests in one command. Test: [from root] atest --test-mapping external/aac/ Test: [from external/aaac] atest Change-Id: Ic03753b57bb1d3b6a06ced1fd7f321bf8402e8cf --- TEST_MAPPING | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 TEST_MAPPING diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 0000000..bc22166 --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,22 @@ +{ + "presubmit": [ + { + "name": "CtsMediaTestCases", + "options": [ + { "include-filter": "android.media.cts.DecoderTest#testCodecResetsM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecode51M4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeAacEldM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcMcM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeAacTs" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacMcM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacV2M4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeM4a" }, + { "include-filter": "android.media.cts.DecoderTest#testDecodeMonoM4a" }, + { "include-filter": "android.media.cts.DecoderTestXheAac" }, + { "include-filter": "android.media.cts.DecoderTestAacDrc" } + ] + } + ] +} -- cgit v1.2.3 From 8458e48f05f68037f5fd978e25845ba7e351fe01 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Fri, 3 Jan 2020 00:17:38 +0000 Subject: Revert "Add TEST_MAPPING for aac project" This reverts commit b10c18741e961015fbded7df2bbf0ec5f799de9e. Reason for revert: cf_x86_phone-userdebug breaks on those tests Bug: 147097191 Change-Id: I15eccdc2a8527f526882dc6e5df241f404cb163d --- TEST_MAPPING | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 TEST_MAPPING diff --git a/TEST_MAPPING b/TEST_MAPPING deleted file mode 100644 index bc22166..0000000 --- a/TEST_MAPPING +++ /dev/null @@ -1,22 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsMediaTestCases", - "options": [ - { "include-filter": "android.media.cts.DecoderTest#testCodecResetsM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecode51M4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeAacEldM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeAacLcMcM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeAacTs" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacMcM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeHeAacV2M4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeM4a" }, - { "include-filter": "android.media.cts.DecoderTest#testDecodeMonoM4a" }, - { "include-filter": "android.media.cts.DecoderTestXheAac" }, - { "include-filter": "android.media.cts.DecoderTestAacDrc" } - ] - } - ] -} -- cgit v1.2.3 From 70192726460eea96ddfc77ac86e2ba59fc758f26 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:04:48 +0100 Subject: Prevent signed integer overflow in fMultIceil() for case m_e=-31. Bug: 146934600 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I8a67a3b17f3ec3af753b6463b72ae2947986b39c --- libFDK/include/fixpoint_math.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h index 3805892..93aea19 100644 --- a/libFDK/include/fixpoint_math.h +++ b/libFDK/include/fixpoint_math.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -545,15 +545,20 @@ inline INT fMultIceil(FIXP_DBL a, INT b) { m = fMultNorm(a, (FIXP_DBL)b, &m_e); if (m_e < (INT)0) { - if (m_e > (INT)-DFRACT_BITS) { + if (m_e > (INT) - (DFRACT_BITS - 1)) { mi = (m >> (-m_e)); if ((LONG)m & ((1 << (-m_e)) - 1)) { mi = mi + (FIXP_DBL)1; } } else { - mi = (FIXP_DBL)1; - if (m < (FIXP_DBL)0) { - mi = (FIXP_DBL)0; + if (m > (FIXP_DBL)0) { + mi = (FIXP_DBL)1; + } else { + if ((m_e == -(DFRACT_BITS - 1)) && (m == (FIXP_DBL)MINVAL_DBL)) { + mi = (FIXP_DBL)-1; + } else { + mi = (FIXP_DBL)0; + } } } } else { -- cgit v1.2.3 From 76c229c01896506f1c77929b1748fa6ed5ee1e27 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:05:17 +0100 Subject: Introduce scaling in FDKhybridSynthesisApply() to avoid potential signed integer overflow. Bug: 146937225 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ifa3d157a842828c2a66694d95dad5d4992ff6d87 --- libFDK/src/FDK_hybrid.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/libFDK/src/FDK_hybrid.cpp b/libFDK/src/FDK_hybrid.cpp index b661f82..08d32a8 100644 --- a/libFDK/src/FDK_hybrid.cpp +++ b/libFDK/src/FDK_hybrid.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -142,11 +142,12 @@ amm-info@iis.fraunhofer.de } /* How to arrange the packed values. */ struct FDK_HYBRID_SETUP { - UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */ - UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */ - SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */ - UCHAR protoLen; /*!< Prototype filter length. */ - UCHAR filterDelay; /*!< Delay caused by hybrid filter. */ + UCHAR nrQmfBands; /*!< Number of QMF bands to be converted to hybrid. */ + UCHAR nHybBands[3]; /*!< Number of Hybrid bands generated by nrQmfBands. */ + UCHAR synHybScale[3]; /*!< Headroom needed in hybrid synthesis filterbank. */ + SCHAR kHybrid[3]; /*!< Filter configuration of each QMF band. */ + UCHAR protoLen; /*!< Prototype filter length. */ + UCHAR filterDelay; /*!< Delay caused by hybrid filter. */ const INT *pReadIdxTable; /*!< Helper table to access input data ringbuffer. */ }; @@ -156,12 +157,12 @@ static const INT ringbuffIdxTab[2 * 13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const FDK_HYBRID_SETUP setup_3_16 = {3, {8, 4, 4}, {8, 4, 4}, - 13, (13 - 1) / 2, ringbuffIdxTab}; -static const FDK_HYBRID_SETUP setup_3_12 = {3, {8, 2, 2}, {8, 2, 2}, - 13, (13 - 1) / 2, ringbuffIdxTab}; -static const FDK_HYBRID_SETUP setup_3_10 = {3, {6, 2, 2}, {-8, -2, 2}, - 13, (13 - 1) / 2, ringbuffIdxTab}; +static const FDK_HYBRID_SETUP setup_3_16 = { + 3, {8, 4, 4}, {4, 3, 3}, {8, 4, 4}, 13, (13 - 1) / 2, ringbuffIdxTab}; +static const FDK_HYBRID_SETUP setup_3_12 = { + 3, {8, 2, 2}, {4, 2, 2}, {8, 2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab}; +static const FDK_HYBRID_SETUP setup_3_10 = { + 3, {6, 2, 2}, {3, 2, 2}, {-8, -2, 2}, 13, (13 - 1) / 2, ringbuffIdxTab}; static const FIXP_HTP HybFilterCoef8[] = { HTCP(0x10000000, 0x00000000), HTCP(0x0df26407, 0xfa391882), @@ -477,17 +478,18 @@ void FDKhybridSynthesisApply(HANDLE_FDK_SYN_HYB_FILTER hSynthesisHybFilter, */ for (k = 0; k < nrQmfBandsLF; k++) { const int nHybBands = hSynthesisHybFilter->pSetup->nHybBands[k]; + const int scale = hSynthesisHybFilter->pSetup->synHybScale[k]; FIXP_DBL accu1 = FL2FXCONST_DBL(0.f); FIXP_DBL accu2 = FL2FXCONST_DBL(0.f); /* Perform hybrid filtering. */ for (n = 0; n < nHybBands; n++) { - accu1 += pHybridReal[hybOffset + n]; - accu2 += pHybridImag[hybOffset + n]; + accu1 += pHybridReal[hybOffset + n] >> scale; + accu2 += pHybridImag[hybOffset + n] >> scale; } - pQmfReal[k] = accu1; - pQmfImag[k] = accu2; + pQmfReal[k] = SATURATE_LEFT_SHIFT(accu1, scale, DFRACT_BITS); + pQmfImag[k] = SATURATE_LEFT_SHIFT(accu2, scale, DFRACT_BITS); hybOffset += nHybBands; } -- cgit v1.2.3 From 25fb9adf6fe129e0b74fe78c04526a57b8210f29 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:05:46 +0100 Subject: Avoid signed integer overflows in SpatialDecApplyParameterSets() when adding dry and wet signal. Bug: 146936964 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Idb4242d54b2e61805ab071a8977eed8f06081edf --- libSACdec/src/sac_dec.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp index 3f55a7d..c1832f1 100644 --- a/libSACdec/src/sac_dec.cpp +++ b/libSACdec/src/sac_dec.cpp @@ -1317,10 +1317,12 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( if ((self->tempShapeConfig == 1) && (!isTwoChMode(self->upmixType))) { for (ch = 0; ch < self->numOutputChannels; ch++) { for (hyb = 0; hyb < self->tp_hybBandBorder; hyb++) { - self->hybOutputRealDry__FDK[ch][hyb] += - self->hybOutputRealWet__FDK[ch][hyb]; - self->hybOutputImagDry__FDK[ch][hyb] += - self->hybOutputImagWet__FDK[ch][hyb]; + self->hybOutputRealDry__FDK[ch][hyb] = + fAddSaturate(self->hybOutputRealDry__FDK[ch][hyb], + self->hybOutputRealWet__FDK[ch][hyb]); + self->hybOutputImagDry__FDK[ch][hyb] = + fAddSaturate(self->hybOutputImagDry__FDK[ch][hyb], + self->hybOutputImagWet__FDK[ch][hyb]); } /* loop hyb */ } /* loop ch */ err = subbandTPApply( @@ -1341,11 +1343,11 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( FIXP_DBL *RESTRICT pRealWet = self->hybOutputRealWet__FDK[ch]; FIXP_DBL *RESTRICT pImagWet = self->hybOutputImagWet__FDK[ch]; for (hyb = 0; hyb < nHybBands; hyb++) { - pRealDry[hyb] += pRealWet[hyb]; - pImagDry[hyb] += pImagWet[hyb]; + pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]); + pImagDry[hyb] = fAddSaturate(pImagDry[hyb], pImagWet[hyb]); } /* loop hyb */ for (; hyb < self->hybridBands; hyb++) { - pRealDry[hyb] += pRealWet[hyb]; + pRealDry[hyb] = fAddSaturate(pRealDry[hyb], pRealWet[hyb]); } /* loop hyb */ } /* loop ch */ } /* ( self->tempShapeConfig == 1 ) || ( self->tempShapeConfig == 2 ) */ -- cgit v1.2.3 From 063d5f30864c6293855da6f7b8dd482d7c408158 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:05:58 +0100 Subject: Revise scaling for USAC combined with phase coding in SpatialDecApplyM2() to prevent signed integer overflow. Bug: 146937759 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: If7c484b2e1bee82747f5c6dc0ee7ad1f282c0189 --- libSACdec/src/sac_calcM1andM2.h | 5 +- libSACdec/src/sac_process.cpp | 145 ++++++++++++++++++++++------------------ 2 files changed, 84 insertions(+), 66 deletions(-) diff --git a/libSACdec/src/sac_calcM1andM2.h b/libSACdec/src/sac_calcM1andM2.h index 996238d..cefc4bb 100644 --- a/libSACdec/src/sac_calcM1andM2.h +++ b/libSACdec/src/sac_calcM1andM2.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -117,6 +117,9 @@ amm-info@iis.fraunhofer.de /* Scaling of spectral data after applying M2 matrix, but only for binaural upmix type Scaling is compensated later in synthesis qmf filterbank */ #define SCALE_DATA_APPLY_M2 (1) +/* Applying M2 parameter in combination with phase coding needs 2 bits headroom + * because up to a maximum of 4 spectral values can be added for USAC */ +#define SCALE_DATA_APPLY_M2_PC (2) SACDEC_ERROR initM1andM2(spatialDec* self, int initStatesFlag, int configChanged); diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp index 56c72ad..95128f3 100644 --- a/libSACdec/src/sac_process.cpp +++ b/libSACdec/src/sac_process.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -113,6 +113,8 @@ amm-info@iis.fraunhofer.de #include "FDK_trigFcts.h" #include "FDK_decorrelate.h" +#define SAC_DEC_APPLY_M2_SCALE(spec, s) ((spec) >> (-(s))) + /** * \brief Linear interpolation between two parameter values. * a*alpha + b*(1-alpha) @@ -634,8 +636,7 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, } if (self->phaseCoding == 3) { - /* + SCALE_DATA_APPLY_M2 to compensate for Div2 below ?! */ - scale_param_m2 = SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2; + scale_param_m2 = -(SCALE_DATA_APPLY_M2_PC - 1); } for (row = 0; row < self->numM2rows; row++) { @@ -686,10 +687,10 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, } else { /* isBinauralMode(self->upmixType) */ for (qs = 0; qs < complexHybBands; qs++) { - pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); + pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); } M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col], @@ -697,27 +698,27 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, self->kernels_width, alpha, complexParBands); /* direct signals sign is -1 for qs = 0,2 */ - pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0]) - << (scale_param_m2); - pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0]) - << (scale_param_m2); + pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2); + pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2); - pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2]) - << (scale_param_m2); - pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2]) - << (scale_param_m2); + pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2); + pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2); /* direct signals sign is +1 for qs = 1,3,4,5,...,complexHybBands */ - pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1]) - << (scale_param_m2); - pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1]) - << (scale_param_m2); + pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2); + pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2); for (qs = 3; qs < complexHybBands; qs++) { - pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); + pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); } } /* self->upmixType */ } /* if (activParamBands) */ @@ -770,17 +771,17 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, FIXP_DBL *RESTRICT pHybOutImag; for (qs = 0; qs < resHybIndex; qs++) { - pHybOutRealDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagDry[qs] += fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); + pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); } /* decor signals */ for (; qs < complexHybBands; qs++) { - pHybOutRealWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagWet[qs] += fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealWet[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); + pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); } M2ParamToKernelMult(pKernel, self->M2Imag__FDK[row][col], @@ -790,20 +791,20 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, /* direct signals sign is -1 for qs = 0,2 */ /* direct signals sign is +1 for qs = 1,3.. */ if (toolsDisabled) { - pHybOutRealDry[0] += fMultDiv2(pWImag[0], pKernel[0]) - << (scale_param_m2); - pHybOutImagDry[0] -= fMultDiv2(pWReal[0], pKernel[0]) - << (scale_param_m2); - - pHybOutRealDry[1] -= fMultDiv2(pWImag[1], pKernel[1]) - << (scale_param_m2); - pHybOutImagDry[1] += fMultDiv2(pWReal[1], pKernel[1]) - << (scale_param_m2); - - pHybOutRealDry[2] += fMultDiv2(pWImag[2], pKernel[2]) - << (scale_param_m2); - pHybOutImagDry[2] -= fMultDiv2(pWReal[2], pKernel[2]) - << (scale_param_m2); + pHybOutRealDry[0] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2); + pHybOutImagDry[0] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2); + + pHybOutRealDry[1] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2); + pHybOutImagDry[1] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2); + + pHybOutRealDry[2] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2); + pHybOutImagDry[2] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2); } else { pHybOutReal = &pHybOutRealDry[0]; pHybOutImag = &pHybOutImagDry[0]; @@ -811,46 +812,60 @@ SACDEC_ERROR SpatialDecApplyM2(spatialDec *self, INT ps, const FIXP_SGL alpha, pHybOutReal = &pHybOutRealWet[0]; pHybOutImag = &pHybOutImagWet[0]; } - pHybOutReal[0] += fMultDiv2(pWImag[0], pKernel[0]) - << (scale_param_m2); - pHybOutImag[0] -= fMultDiv2(pWReal[0], pKernel[0]) - << (scale_param_m2); + pHybOutReal[0] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[0], pKernel[0]), scale_param_m2); + pHybOutImag[0] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[0], pKernel[0]), scale_param_m2); if (1 == resHybIndex) { pHybOutReal = &pHybOutRealWet[0]; pHybOutImag = &pHybOutImagWet[0]; } - pHybOutReal[1] -= fMultDiv2(pWImag[1], pKernel[1]) - << (scale_param_m2); - pHybOutImag[1] += fMultDiv2(pWReal[1], pKernel[1]) - << (scale_param_m2); + pHybOutReal[1] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[1], pKernel[1]), scale_param_m2); + pHybOutImag[1] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[1], pKernel[1]), scale_param_m2); if (2 == resHybIndex) { pHybOutReal = &pHybOutRealWet[0]; pHybOutImag = &pHybOutImagWet[0]; } - pHybOutReal[2] += fMultDiv2(pWImag[2], pKernel[2]) - << (scale_param_m2); - pHybOutImag[2] -= fMultDiv2(pWReal[2], pKernel[2]) - << (scale_param_m2); + pHybOutReal[2] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[2], pKernel[2]), scale_param_m2); + pHybOutImag[2] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[2], pKernel[2]), scale_param_m2); } for (qs = 3; qs < resHybIndex; qs++) { - pHybOutRealDry[qs] -= fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagDry[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealDry[qs] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); + pHybOutImagDry[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); } /* decor signals */ for (; qs < complexHybBands; qs++) { - pHybOutRealWet[qs] -= fMultDiv2(pWImag[qs], pKernel[qs]) - << (scale_param_m2); - pHybOutImagWet[qs] += fMultDiv2(pWReal[qs], pKernel[qs]) - << (scale_param_m2); + pHybOutRealWet[qs] -= SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWImag[qs], pKernel[qs]), scale_param_m2); + pHybOutImagWet[qs] += SAC_DEC_APPLY_M2_SCALE( + fMultDiv2(pWReal[qs], pKernel[qs]), scale_param_m2); } } /* self->upmixType */ } /* if (activParamBands) { */ } /* self->numVChannels */ + + if (self->phaseCoding == 3) { + scaleValuesSaturate(pHybOutRealDry, complexHybBands, + SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC); + scaleValuesSaturate(pHybOutImagDry, complexHybBands, + SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC); + + if (!toolsDisabled) { + scaleValuesSaturate(pHybOutRealWet, complexHybBands, + SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC); + scaleValuesSaturate(pHybOutImagWet, complexHybBands, + SCALE_PARAM_M2_212_PRED + SCALE_DATA_APPLY_M2_PC); + } + } } C_ALLOC_SCRATCH_END(pKernel, FIXP_SGL, MAX_HYBRID_BANDS); -- cgit v1.2.3 From 1a0335287fffe56e811a67e1a3eb04f940cf178a Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:06:13 +0100 Subject: Prevent signed integer overflow in TsdApply(). Bug: 146937678 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ia7b58caf9eb86c19e3ae10b3cc624490b2a5f07b --- libSACdec/src/sac_tsd.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libSACdec/src/sac_tsd.cpp b/libSACdec/src/sac_tsd.cpp index 30acca8..a07447b 100644 --- a/libSACdec/src/sac_tsd.cpp +++ b/libSACdec/src/sac_tsd.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -123,12 +123,15 @@ static const UCHAR nBitsTsdCW_64slots[64] = { RAM_ALIGN LNK_SECTION_CONSTDATA -static const FIXP_STP phiTsd[8] = { - STCP(0x7fffffff, 0x00000000), STCP(0x5a82799a, 0x5a82799a), - STCP(0x00000000, 0x7fffffff), STCP(0xa57d8666, 0x5a82799a), - STCP(0x80000000, 0x00000000), STCP(0xa57d8666, 0xa57d8666), - STCP(0x00000000, 0x80000000), STCP(0x5a82799a, 0xa57d8666), -}; +static const FIXP_DPK phiTsd[8] = { + {{(FIXP_DBL)0x7fffffff, (FIXP_DBL)0x00000000}}, + {{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0x5a82799a}}, + {{(FIXP_DBL)0x00000000, (FIXP_DBL)0x7fffffff}}, + {{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0x5a82799a}}, + {{(FIXP_DBL)0x80000000, (FIXP_DBL)0x00000000}}, + {{(FIXP_DBL)0xa57d8666, (FIXP_DBL)0xa57d8666}}, + {{(FIXP_DBL)0x00000000, (FIXP_DBL)0x80000000}}, + {{(FIXP_DBL)0x5a82799a, (FIXP_DBL)0xa57d8666}}}; /*** Static Functions ***/ static void longmult1(USHORT a[], USHORT b, USHORT d[], int len) { @@ -333,16 +336,19 @@ void TsdApply(const int numHybridBands, const TSD_DATA *pTsdData, int *pTsdTs, if (isTrSlot(pTsdData, ts)) { int k; - const FIXP_STP *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]]; + const FIXP_DPK *phi = &phiTsd[pTsdData->bsTsdTrPhaseData[ts]]; FDK_ASSERT((pTsdData->bsTsdTrPhaseData[ts] >= 0) && (pTsdData->bsTsdTrPhaseData[ts] < 8)); /* d = d_nonTr + v_direct * exp(j * bsTsdTrPhaseData[ts]/4 * pi ) */ for (k = TSD_START_BAND; k < numHybridBands; k++) { FIXP_DBL tempReal, tempImag; - cplxMult(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], *phi); - pDnonTrReal[k] += tempReal; - pDnonTrImag[k] += tempImag; + cplxMultDiv2(&tempReal, &tempImag, pVdirectReal[k], pVdirectImag[k], + *phi); + pDnonTrReal[k] = SATURATE_LEFT_SHIFT( + (pDnonTrReal[k] >> 2) + (tempReal >> 1), 2, DFRACT_BITS); + pDnonTrImag[k] = SATURATE_LEFT_SHIFT( + (pDnonTrImag[k] >> 2) + (tempImag >> 1), 2, DFRACT_BITS); } } -- cgit v1.2.3 From ed5a207a1f32c7b5aef053866c04f0bd8501ec57 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:06:24 +0100 Subject: Avoid signed integer overflow in combineSignalCplx*(). Bug: 146937324 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I3f5516085483ac349f9873e7267c6ff7f9c6f816 --- libSACdec/src/sac_stp.cpp | 41 ++++++++++------------------------------- 1 file changed, 10 insertions(+), 31 deletions(-) diff --git a/libSACdec/src/sac_stp.cpp b/libSACdec/src/sac_stp.cpp index 6ac5a56..bb66277 100644 --- a/libSACdec/src/sac_stp.cpp +++ b/libSACdec/src/sac_stp.cpp @@ -206,29 +206,6 @@ struct STP_DEC { int update_old_ener; }; -inline void combineSignalReal(FIXP_DBL *hybOutputRealDry, - FIXP_DBL *hybOutputRealWet, int bands) { - int n; - - for (n = bands - 1; n >= 0; n--) { - *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet; - hybOutputRealDry++, hybOutputRealWet++; - } -} - -inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry, - FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX, - int bands) { - int n; - - for (n = bands - 1; n >= 0; n--) { - *hybOutputRealDry = - *hybOutputRealDry + - (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1)); - hybOutputRealDry++, hybOutputRealWet++; - } -} - inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry, FIXP_DBL *hybOutputImagDry, FIXP_DBL *hybOutputRealWet, @@ -236,8 +213,8 @@ inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry, int n; for (n = bands - 1; n >= 0; n--) { - *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet; - *hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet; + *hybOutputRealDry = fAddSaturate(*hybOutputRealDry, *hybOutputRealWet); + *hybOutputImagDry = fAddSaturate(*hybOutputImagDry, *hybOutputImagWet); hybOutputRealDry++, hybOutputRealWet++; hybOutputImagDry++, hybOutputImagWet++; } @@ -253,12 +230,14 @@ inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry, FIXP_DBL scaleY; for (n = bands - 1; n >= 0; n--) { scaleY = fMultDiv2(scaleX, *pBP); - *hybOutputRealDry = - *hybOutputRealDry + - (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2)); - *hybOutputImagDry = - *hybOutputImagDry + - (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2)); + *hybOutputRealDry = SATURATE_LEFT_SHIFT( + (*hybOutputRealDry >> 1) + + (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 1)), + 1, DFRACT_BITS); + *hybOutputImagDry = SATURATE_LEFT_SHIFT( + (*hybOutputImagDry >> 1) + + (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 1)), + 1, DFRACT_BITS); hybOutputRealDry++, hybOutputRealWet++; hybOutputImagDry++, hybOutputImagWet++; pBP++; -- cgit v1.2.3 From 3070b0e81bfd3285055bcd4b76a0ca3769bda70b Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:06:43 +0100 Subject: Revise scaling in extractBBEnv() to avoid potential signed integer overflows. Bug: 146936823 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I268f4ed2778ffad6cbd90e1df627daf2eab97604 --- libSACdec/src/sac_reshapeBBEnv.cpp | 174 +++++++++++++++---------------------- 1 file changed, 68 insertions(+), 106 deletions(-) diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp index 87c0ac6..588c866 100644 --- a/libSACdec/src/sac_reshapeBBEnv.cpp +++ b/libSACdec/src/sac_reshapeBBEnv.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -162,75 +162,59 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal, FIXP_DBL nrg; /* qs = 12, 13, 14 */ - slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 15 */ - slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 16, 17 */ - nrg = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[4] = + nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 18, 19, 20 */ - nrg = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - nrg += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[5] = + nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 21, 22 */ - nrg = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[6] = + nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 23, 24 */ if (hybBands > 23) { - slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 25, 26, 29, 28, 29 */ - nrg = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - nrg += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - nrg += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - nrg += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); - slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); + slotNrg[7] = + nrg + ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); /* qs = 30 ... min(41,hybBands-1) */ - nrg = ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg = ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); for (qs = 31; qs < hybBands; qs++) { - nrg += ((fPow2Div2((*pReal++) << maxValSF) + - fPow2Div2((*pImag++) << maxValSF)) >> - (SF_FACTOR_SLOT - 1)); + nrg += ((fPow2Div2((*pReal++) << maxValSF) >> (SF_FACTOR_SLOT - 1)) + + (fPow2Div2((*pImag++) << maxValSF) >> (SF_FACTOR_SLOT - 1))); } slotNrg[8] = nrg; } else { @@ -239,49 +223,22 @@ static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal, } } -static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal, - FIXP_DBL *RESTRICT pImag, INT cplxBands, - INT hybBands) { - INT qs, clz; - FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); - - for (qs = 12; qs < cplxBands; qs++) { - maxVal |= fAbs(pReal[qs]); - maxVal |= fAbs(pImag[qs]); - } - for (; qs < hybBands; qs++) { - maxVal |= fAbs(pReal[qs]); - } - - clz = fixMax(0, CntLeadingZeros(maxVal) - 1); - - return (clz); -} - -static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal, - FIXP_DBL *RESTRICT pImag, - FIXP_DBL *RESTRICT pHybOutputRealDry, - FIXP_DBL *RESTRICT pHybOutputImagDry, - FIXP_DBL *RESTRICT pHybOutputRealWet, - FIXP_DBL *RESTRICT pHybOutputImagWet, - INT cplxBands, INT hybBands) { - INT qs, clz; - FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); +static inline void combineDryWet(FIXP_DBL *RESTRICT pReal, + FIXP_DBL *RESTRICT pImag, + FIXP_DBL *RESTRICT pHybOutputRealDry, + FIXP_DBL *RESTRICT pHybOutputImagDry, + FIXP_DBL *RESTRICT pHybOutputRealWet, + FIXP_DBL *RESTRICT pHybOutputImagWet, + INT cplxBands, INT hybBands) { + INT qs; for (qs = 12; qs < cplxBands; qs++) { - pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs]; - maxVal |= fAbs(pReal[qs]); - pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs]; - maxVal |= fAbs(pImag[qs]); + pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1); + pImag[qs] = (pHybOutputImagDry[qs] >> 1) + (pHybOutputImagWet[qs] >> 1); } for (; qs < hybBands; qs++) { - pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs]; - maxVal |= fAbs(pReal[qs]); + pReal[qs] = (pHybOutputRealDry[qs] >> 1) + (pHybOutputRealWet[qs] >> 1); } - - clz = fixMax(0, CntLeadingZeros(maxVal) - 1); - - return (clz); } static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry, @@ -386,15 +343,18 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels, prevChOffs = ch; pReal = pScratchBuffer; pImag = pScratchBuffer + 42; - clz = getMaxValDryWet( - pReal, pImag, self->hybOutputRealDry__FDK[ch], - self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch], - self->hybOutputImagWet__FDK[ch], cplxBands, hybBands); + combineDryWet(pReal, pImag, self->hybOutputRealDry__FDK[ch], + self->hybOutputImagDry__FDK[ch], + self->hybOutputRealWet__FDK[ch], + self->hybOutputImagWet__FDK[ch], cplxBands, hybBands); + clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)), + getScalefactor(&pImag[12], fMax(0, cplxBands - 12))); } else { prevChOffs = ch + self->numOutputChannels; pReal = self->hybInputReal__FDK[ch]; pImag = self->hybInputImag__FDK[ch]; - clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands); + clz = fMin(getScalefactor(&pReal[12], fMax(0, hybBands - 12)), + getScalefactor(&pImag[12], fMax(0, cplxBands - 12))); } partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs]; @@ -411,8 +371,10 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels, SF_FACTOR_SLOT */ } - slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT; - frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT; + slotNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) + + SF_FACTOR_SLOT; + frameNrgSF = 2 * (staticScale - clz + ((inp == INP_DRY_WET) ? 1 : 0)) + + SF_FACTOR_SLOT; partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1, pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1); -- cgit v1.2.3 From 9ab63ce1512780752eb5f54bfd91d132a8611b2a Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:06:56 +0100 Subject: Prevent negation of INT_MIN in CConcealment_ApplyRandomSign(). Bug: 146937601 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I9747110eca96b37604df996ef5e86ea58e2d8932 --- libAACdec/src/conceal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 5895cb8..ae98874 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1618,7 +1618,7 @@ static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec, } if (packedSign & 0x1) { - spec[i] = -spec[i]; + spec[i] = -fMax(spec[i], (FIXP_DBL)(MINVAL_DBL + 1)); } packedSign >>= 1; -- cgit v1.2.3 From 8caa63f329c26fcf8dda71ed0a928a7c39c0f839 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:07:13 +0100 Subject: Avoid unsigned integer overflow in transportDec_InBandConfig() and transportDec_ReadAccessUnit(). Bug: 146937857 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: If2320f3a1ddf6a36c07338100481801a996e455d --- libMpegTPDec/src/tpdec_lib.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index ede64c9..617f9a1 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -482,7 +482,8 @@ TRANSPORTDEC_ERROR transportDec_InBandConfig(HANDLE_TRANSPORTDEC hTp, for (int i = 0; i < 2; i++) { if (i > 0) { - FDKpushBack(hBs, newConfigLength * 8 - FDKgetValidBits(hBs)); + FDKpushBack(hBs, + (INT)newConfigLength * 8 - (INT)FDKgetValidBits(hBs)); configMode = AC_CM_ALLOC_MEM; } /* config transport decoder */ @@ -1469,7 +1470,7 @@ TRANSPORTDEC_ERROR transportDec_ReadAccessUnit(const HANDLE_TRANSPORTDEC hTp, for (i = 0; i < 2; i++) { if (i > 0) { - FDKpushBack(hBs, bsStart - FDKgetValidBits(hBs)); + FDKpushBack(hBs, bsStart - (INT)FDKgetValidBits(hBs)); configMode = AC_CM_ALLOC_MEM; } -- cgit v1.2.3 From 8fee7605df2d8759a63faa3d0b1aac7d95dfc1af Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:07:33 +0100 Subject: Prevent undefined syncLayerFrameBits in synchronization(). Bug: 146937540 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Idaaa11d95c13220a9f96e6d73d4813492a740954 --- libMpegTPDec/src/tpdec_lib.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 617f9a1..7bebbaa 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -981,6 +981,9 @@ static TRANSPORTDEC_ERROR transportDec_readHeader( CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm); if (hTp->transportFmt == TT_MP4_LOAS) { syncLayerFrameBits -= startPos - (INT)FDKgetValidBits(hBs) - (13); + if (syncLayerFrameBits <= 0) { + err = TRANSPORTDEC_SYNC_ERROR; + } } } } else { @@ -1271,8 +1274,9 @@ static TRANSPORTDEC_ERROR synchronization(HANDLE_TRANSPORTDEC hTp, if (!(hTp->flags & (TPDEC_LOST_FRAMES_PENDING | TPDEC_IGNORE_BUFFERFULLNESS | TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) { - err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), - FDKgetValidBits(hBs) - syncLayerFrameBits); + err = + additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), + (INT)FDKgetValidBits(hBs) - syncLayerFrameBits); if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) { hTp->holdOffFrames++; } -- cgit v1.2.3 From 5d095631969aa7136ac2cb7e0e13664516054097 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:08:57 +0100 Subject: Avoid too large shift exponent in apply_inter_tes() by using fIsLessThan. Bug: 146936613 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I8414072929ec8f786e0c003f18ab453dbacb9e5e --- libSBRdec/src/env_calc.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp index 81f03f3..0b2f651 100644 --- a/libSBRdec/src/env_calc.cpp +++ b/libSBRdec/src/env_calc.cpp @@ -702,20 +702,11 @@ static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */ /* set gain to at least 0.2f */ - FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */ - int point_two_sf = -2; - - FIXP_DBL tmp = gain[i]; - if (point_two_sf < gain_sf[i]) { - point_two >>= gain_sf[i] - point_two_sf; - } else { - tmp >>= point_two_sf - gain_sf[i]; - } - /* limit and calculate gain[i]^2 too */ FIXP_DBL gain_pow2; int gain_pow2_sf; - if (tmp < point_two) { + + if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) { gain[i] = FL2FXCONST_DBL(0.8f); gain_sf[i] = -2; gain_pow2 = FL2FXCONST_DBL(0.64f); -- cgit v1.2.3 From e3b9058b8b72ccc890014c597b25a7cedfd555e3 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:08:09 +0100 Subject: Avoid unsigned integer overflows in FDK_Feed(). Bug: 146937030 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I7bd63c2fbfed2612c80d3334d1339e1cd215e034 --- libFDK/src/FDK_bitbuffer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libFDK/src/FDK_bitbuffer.cpp b/libFDK/src/FDK_bitbuffer.cpp index 98905ea..9b7f5b8 100644 --- a/libFDK/src/FDK_bitbuffer.cpp +++ b/libFDK/src/FDK_bitbuffer.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -368,7 +368,10 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer, UINT bTotal = 0; - UINT bToRead = (hBitBuf->bufBits - hBitBuf->ValidBits) >> 3; + UINT bToRead = + fMin(hBitBuf->bufBits, + (UINT)fMax(0, ((INT)hBitBuf->bufBits - (INT)hBitBuf->ValidBits))) >> + 3; UINT noOfBytes = fMin(bToRead, *bytesValid); //(bToRead < *bytesValid) ? bToRead : *bytesValid ; @@ -384,7 +387,7 @@ void FDK_Feed(HANDLE_FDK_BITBUF hBitBuf, const UCHAR *RESTRICT inputBuffer, bToRead * sizeof(UCHAR)); /* add noOfBits to number of valid bits in buffer */ - hBitBuf->ValidBits += bToRead << 3; + hBitBuf->ValidBits = (UINT)((INT)hBitBuf->ValidBits + (INT)(bToRead << 3)); bTotal += bToRead; inputBuffer += bToRead; -- cgit v1.2.3 From 86f7d2b69a00ae32d555f37fe687c001eaa99ddd Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:09:14 +0100 Subject: Prevent too large shift exponents in SpatialDecReshapeBBEnv(). Bug: 146937858 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I9fbe0b364ae4d329c6e5cc1109a111ef5def552d --- libSACdec/src/sac_reshapeBBEnv.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp index 588c866..b44ce4e 100644 --- a/libSACdec/src/sac_reshapeBBEnv.cpp +++ b/libSACdec/src/sac_reshapeBBEnv.cpp @@ -284,11 +284,14 @@ shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry, } } else { for (qs = 0; qs < cplxBands; qs++) { - pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale; - pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale; + pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT( + fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS); + pHybOutputImagDry[qs] = SATURATE_LEFT_SHIFT( + fMultDiv2(pHybOutputImagDry[qs], dryFac), scale, DFRACT_BITS); } for (; qs < hybBands; qs++) { - pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale; + pHybOutputRealDry[qs] = SATURATE_LEFT_SHIFT( + fMultDiv2(pHybOutputRealDry[qs], dryFac), scale, DFRACT_BITS); } } } @@ -614,14 +617,16 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame, fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3 bits to avoid overflows when calculating dryFac */ - dryFac = dryFac >> (scale - dryFacSF); - slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF); + dryFac = dryFac >> fixMin(scale - dryFacSF, DFRACT_BITS - 1); + slotAmp_ratio = + slotAmp_ratio >> fixMin(scale - slotAmpSF, DFRACT_BITS - 1); /* limit dryFac */ dryFac = fixMax( FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1), - fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) + - (dryFac >> scale)); + fMult(dryFac, slotAmp_ratio) - + (slotAmp_ratio >> fixMin(scale, DFRACT_BITS - 1)) + + (dryFac >> fixMin(scale, DFRACT_BITS - 1))); dryFac = fixMin( FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1), dryFac); /* reduce shift bits by 3, because upper @@ -635,8 +640,8 @@ void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame, /* shaping */ shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6], - &self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands, - hybBands); + &self->hybOutputImagDry__FDK[ch][6], dryFac, + fixMin(scale, DFRACT_BITS - 1), cplxBands, hybBands); } } } -- cgit v1.2.3 From 1020e48d6e76506ac85a7678fe950ce7245d3aea Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:08:24 +0100 Subject: Fix IsLessThan() function for certain edge cases. Bug: 146936613 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Idbec38c1df01bd7a6a48ac4b6e5673c30627fc73 --- libFDK/include/fixpoint_math.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h index 93aea19..373eec1 100644 --- a/libFDK/include/fixpoint_math.h +++ b/libFDK/include/fixpoint_math.h @@ -171,6 +171,19 @@ extern const FIXP_DBL invSqrtTab[SQRT_VALUES]; * \return non-zero if (a_m*2^a_e) < (b_m*2^b_e), 0 otherwise */ FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) { + INT n; + + n = fixnorm_D(a_m); + a_m <<= n; + a_e -= n; + + n = fixnorm_D(b_m); + b_m <<= n; + b_e -= n; + + if (a_m == (FIXP_DBL)0) a_e = b_e; + if (b_m == (FIXP_DBL)0) b_e = a_e; + if (a_e > b_e) { return ((b_m >> fMin(a_e - b_e, DFRACT_BITS - 1)) > a_m); } else { @@ -179,6 +192,19 @@ FDK_INLINE INT fIsLessThan(FIXP_DBL a_m, INT a_e, FIXP_DBL b_m, INT b_e) { } FDK_INLINE INT fIsLessThan(FIXP_SGL a_m, INT a_e, FIXP_SGL b_m, INT b_e) { + INT n; + + n = fixnorm_S(a_m); + a_m <<= n; + a_e -= n; + + n = fixnorm_S(b_m); + b_m <<= n; + b_e -= n; + + if (a_m == (FIXP_SGL)0) a_e = b_e; + if (b_m == (FIXP_SGL)0) b_e = a_e; + if (a_e > b_e) { return ((b_m >> fMin(a_e - b_e, FRACT_BITS - 1)) > a_m); } else { -- cgit v1.2.3 From cee316ab3ebde92047b5e76d15c00768b92cb890 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:09:34 +0100 Subject: Fix too large shift exponent in CConcealment_InterpolateBuffer(). Bug: 146938361 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Idb0a4e2c87962e453a991f0a573155ace6e9bf40 --- libAACdec/src/conceal.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index ae98874..379e63a 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -1228,7 +1228,6 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum, int sfb, line = 0; int fac_shift; int fac_mod; - FIXP_DBL accu; for (sfb = 0; sfb < sfbCnt; sfb++) { fac_shift = @@ -1236,15 +1235,11 @@ static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum, fac_mod = fac_shift & 3; fac_shift = (fac_shift >> 2) + 1; fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct); + fac_shift = fMax(fMin(fac_shift, DFRACT_BITS - 1), -(DFRACT_BITS - 1)); for (; line < pSfbOffset[sfb + 1]; line++) { - accu = fMult(*(spectrum + line), facMod4Table[fac_mod]); - if (fac_shift < 0) { - accu >>= -fac_shift; - } else { - accu <<= fac_shift; - } - *(spectrum + line) = accu; + FIXP_DBL accu = fMult(*(spectrum + line), facMod4Table[fac_mod]); + *(spectrum + line) = scaleValue(accu, fac_shift); } } *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct); -- cgit v1.2.3 From 3ce7751a440cafe41ff2eefb105b03096fbe122c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 20 Dec 2018 15:52:47 +0100 Subject: Perform sanity check on DRC sets and improve the selection process Bug: 137282770 Bug: 141883493 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ie8e17c82653cb0d9adcdb10ec3f4875b6207ac6f --- libDRCdec/src/FDK_drcDecLib.cpp | 12 +++++- libDRCdec/src/drcDec_gainDecoder.cpp | 8 ++-- libDRCdec/src/drcDec_reader.cpp | 23 ++++++----- libDRCdec/src/drcDec_selectionProcess.cpp | 64 +++++++++++++++++++++++++++---- libDRCdec/src/drcDec_types.h | 3 ++ 5 files changed, 88 insertions(+), 22 deletions(-) diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index 4f8ebc7..e43279f 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -145,6 +145,10 @@ struct s_drc_decoder { SEL_PROC_OUTPUT selProcOutput; } DRC_DECODER; +static int _getGainStatus(HANDLE_UNI_DRC_GAIN hUniDrcGain) { + return hUniDrcGain->status; +} + static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec, const SEL_PROC_OUTPUT oldSelProcOutput) { int i, resetNeeded = 0; @@ -729,7 +733,9 @@ FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec, &(hDrcDec->uniDrcGain)); if (dErr) return DRC_DEC_NOT_OK; - hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + if (_getGainStatus(&(hDrcDec->uniDrcGain))) { + hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + } return DRC_DEC_OK; } @@ -751,7 +757,9 @@ FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec, startSelectionProcess(hDrcDec); if (dErr) return DRC_DEC_NOT_OK; - hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + if (_getGainStatus(&(hDrcDec->uniDrcGain))) { + hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + } return DRC_DEC_OK; } diff --git a/libDRCdec/src/drcDec_gainDecoder.cpp b/libDRCdec/src/drcDec_gainDecoder.cpp index 9d91267..de54dde 100644 --- a/libDRCdec/src/drcDec_gainDecoder.cpp +++ b/libDRCdec/src/drcDec_gainDecoder.cpp @@ -297,9 +297,11 @@ drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec, int seq, gainSequenceCount; DRC_COEFFICIENTS_UNI_DRC* pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); - if (pCoef == NULL) return DE_OK; - - gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + if (pCoef && pCoef->gainSequenceCount) { + gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + } else { + gainSequenceCount = 1; + } for (seq = 0; seq < gainSequenceCount; seq++) { int lastNodeIndex = 0; diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp index 9e37246..367a352 100644 --- a/libDRCdec/src/drcDec_reader.cpp +++ b/libDRCdec/src/drcDec_reader.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -199,11 +199,8 @@ drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig, } } - if (hUniDrcGain != NULL) { - err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault, - hUniDrcGain); - if (err) return err; - } + err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault, + hUniDrcGain); return err; } @@ -487,10 +484,13 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs, int seq, gainSequenceCount; DRC_COEFFICIENTS_UNI_DRC* pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); - if (pCoef == NULL) return DE_OK; - if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */ - - gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + if (hUniDrcGain == NULL) return DE_NOT_OK; + hUniDrcGain->status = 0; + if (pCoef) { + gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + } else { + gainSequenceCount = 0; + } for (seq = 0; seq < gainSequenceCount; seq++) { UCHAR index = pCoef->gainSetIndexForGainSequence[seq]; @@ -518,6 +518,9 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs, if (err) return err; } + if (err == DE_OK && gainSequenceCount > 0) { + hUniDrcGain->status = 1; + } return err; } diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index c33bf74..d806ae9 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -956,17 +956,31 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4( return DRCDEC_SELECTION_PROCESS_NO_ERROR; } -/* #5: The number of DRC bands is supported. */ +/* #5: The number of DRC bands is supported. Moreover, gainSetIndex and + * gainSequenceIndex are within the allowed range. */ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) { - int i; + int b, i; *pMatchFound = 1; + if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */ + { + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + if (pCoef == NULL) /* check for parametricDRC */ { - *pMatchFound = 1; + *pMatchFound = 0; /* parametricDRC not supported */ + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + + if (pCoef->drcLocation != + pDrcInstructionUniDrc + ->drcLocation) /* drcLocation must be LOCATION_SELECTED */ + { + *pMatchFound = 0; return DRCDEC_SELECTION_PROCESS_NO_ERROR; } @@ -974,10 +988,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i]; int bandCount = 0; + if (indexDrcCoeff >= 12) { + *pMatchFound = 0; + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */ { - *pMatchFound = 1; - return DRCDEC_SELECTION_PROCESS_NO_ERROR; + continue; } GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]); @@ -986,6 +1004,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( if (bandCount > 4) { *pMatchFound = 0; } + + for (b = 0; b < bandCount; b++) { + if ((gainSet->gainSequenceIndex[b] >= 12) || + (gainSet->gainSequenceIndex[b] >= pCoef->gainSequenceCount)) { + *pMatchFound = 0; + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + } } return DRCDEC_SELECTION_PROCESS_NO_ERROR; @@ -1078,6 +1104,19 @@ static int _targetLoudnessInRange( return retVal; } +static int _drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig, + DRC_INSTRUCTIONS_UNI_DRC* pInst) { + int usable = 0; + DRC_COEFFICIENTS_UNI_DRC* pCoef = + selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); + + /* check if ID is unique */ + if (selectDrcInstructions(hUniDrcConfig, pInst->drcSetId) != pInst) return 0; + /* sanity check on drcInstructions */ + _preSelectionRequirement5(pInst, pCoef, &usable); + return usable; +} + /* #8: The range of the target loudness specified for a DRC set has to include * the requested decoder target loudness. */ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( @@ -2051,8 +2090,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet; for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) { - if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId == - dependsOnDrcSetID) { + DRC_INSTRUCTIONS_UNI_DRC* pInst = + &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; + + if (pInst->drcSetId == dependsOnDrcSetID) { hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] = hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId; hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = @@ -2071,6 +2113,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & EB_FADE) { if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) { @@ -2098,6 +2141,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { for (j = 0; j < pInst->downmixIdCount; j++) { @@ -2124,6 +2168,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { for (j = 0; j < pInst->downmixIdCount; j++) { @@ -2231,6 +2276,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection( for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) { DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction = &(hUniDrcConfig->drcInstructionsUniDrc[j]); + /* check if ID is unique */ + if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) != + pDrcInstruction) + continue; + retVal = _drcSetPreSelectionSingleInstruction( hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction, *ppCandidatesPotential, *ppCandidatesSelected, codecMode); diff --git a/libDRCdec/src/drcDec_types.h b/libDRCdec/src/drcDec_types.h index 6b99018..b0d89c1 100644 --- a/libDRCdec/src/drcDec_types.h +++ b/libDRCdec/src/drcDec_types.h @@ -130,6 +130,9 @@ typedef struct { UCHAR uniDrcGainExtPresent; UNI_DRC_GAIN_EXTENSION uniDrcGainExtension; + + /* derived data */ + UCHAR status; } UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN; /****************/ -- cgit v1.2.3 From e323bf6cabad6cafd31fc77c4d8c14bb48ea71e1 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:09:45 +0100 Subject: Avoid undefined shift exponent in f2Pow(). Bug: 146938418 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Id28608e049244968158900848c23bf7a8298083d --- libFDK/include/fixpoint_math.h | 2 +- libFDK/src/fixpoint_math.cpp | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h index 373eec1..51df4d7 100644 --- a/libFDK/include/fixpoint_math.h +++ b/libFDK/include/fixpoint_math.h @@ -775,7 +775,7 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e, /** * \brief return (base_m * 2^base_e) ^ N - * \param base_m mantissa of the base + * \param base_m mantissa of the base. Must not be negative. * \param base_e exponent of the base * \param N power to be calculated of the base * \param result_e pointer to a INT where the exponent of the result will be diff --git a/libFDK/src/fixpoint_math.cpp b/libFDK/src/fixpoint_math.cpp index 6c656fa..1e26420 100644 --- a/libFDK/src/fixpoint_math.cpp +++ b/libFDK/src/fixpoint_math.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -650,6 +650,12 @@ FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e, INT ans_lg2_e, baselg2_e; FIXP_DBL base_lg2, ans_lg2, result; + if (base_m <= (FIXP_DBL)0) { + result = (FIXP_DBL)0; + *result_e = 0; + return result; + } + /* Calc log2 of base */ base_lg2 = fLog2(base_m, base_e, &baselg2_e); -- cgit v1.2.3 From cedcc475f52dd704497524dda6ec2ef430d2b6c5 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:10:07 +0100 Subject: Reject undefined fPow() input data in _compressorIO_sigmoid_common(). Bug: 146938418 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iae4730ab5f5cef7c0ac8830831d25cfcaa567a99 --- libDRCdec/src/drcGainDec_preprocess.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libDRCdec/src/drcGainDec_preprocess.cpp b/libDRCdec/src/drcGainDec_preprocess.cpp index c543c53..8d94ace 100644 --- a/libDRCdec/src/drcGainDec_preprocess.cpp +++ b/libDRCdec/src/drcGainDec_preprocess.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -285,6 +285,9 @@ static DRC_ERROR _compressorIO_sigmoid_common( &e_tmp2); invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp); e_invExp += 1 - 5; + if (tmp2 < (FIXP_DBL)0) { + return DE_NOT_OK; + } denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom); *out = fDivNormSigned(tmp, denom, &e_out); e_out += 7 - e_denom; -- cgit v1.2.3 From 7388c0732d9cfabd5757f4eda9ea15608a5db126 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:10:21 +0100 Subject: Reject HE-AAC SBR with a ratio greater than 2:1 and reject USAC streams containing legacy DRC info. Bug: 146937553 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I1a23d986160c1de07a7159ac026f57d821d3ff1d --- libAACdec/src/aacdecoder.cpp | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 6b5a86c..bd12d96 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1848,6 +1848,12 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, self->streamInfo.extSamplingRate / self->downscaleFactor; } } + if ((asc->m_aot == AOT_AAC_LC) && (asc->m_sbrPresentFlag == 1) && + (asc->m_extensionSamplingFrequency > (2 * asc->m_samplingFrequency))) { + return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* Core decoder supports at most a + 1:2 upsampling for HE-AAC and + HE-AACv2 */ + } /* --------- vcb11 ------------ */ self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; @@ -2366,6 +2372,13 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, goto bail; } + if (*configChanged) { + if (asc->m_aot == AOT_USAC) { + self->hDrcInfo->enable = 0; + self->hDrcInfo->progRefLevelPresent = 0; + } + } + if (asc->m_aot == AOT_USAC) { pcmLimiter_SetAttack(self->hLimiter, (5)); pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f)); @@ -3172,9 +3185,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo, pce->ElementInstanceTag, drcChMap, aacChannels); if (mapped > 0) { - /* If at least one DRC thread has been mapped to a channel threre was DRC - * data in the bitstream. */ - self->flags[streamIndex] |= AC_DRC_PRESENT; + if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) { + /* If at least one DRC thread has been mapped to a channel there was DRC + * data in the bitstream. */ + self->flags[streamIndex] |= AC_DRC_PRESENT; + } else { + self->hDrcInfo->enable = 0; + self->hDrcInfo->progRefLevelPresent = 0; + ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; + } } /* Create a reverse mapping table */ @@ -3419,9 +3438,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo, pce->ElementInstanceTag, drcChMap, aacChannels); if (mapped > 0) { - /* If at least one DRC thread has been mapped to a channel threre was DRC - * data in the bitstream. */ - self->flags[streamIndex] |= AC_DRC_PRESENT; + if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) { + /* If at least one DRC thread has been mapped to a channel there was DRC + * data in the bitstream. */ + self->flags[streamIndex] |= AC_DRC_PRESENT; + } else { + self->hDrcInfo->enable = 0; + self->hDrcInfo->progRefLevelPresent = 0; + ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; + } } } -- cgit v1.2.3 From 262c9f28ec50e2ebbd2cdd64bd82831d957cf420 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:07:47 +0100 Subject: Avoid negative valid bits in adtsRead_DecodeHeader() Avoid negative valid bits in adtsRead_DecodeHeader() and prevent unsigned integer overflow. Bug: 146937602 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I264ff99e0461352ae5c2b2031393b67a7fa44571 --- libMpegTPDec/src/tpdec_adts.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libMpegTPDec/src/tpdec_adts.cpp b/libMpegTPDec/src/tpdec_adts.cpp index 1a4e3fd..63cc44f 100644 --- a/libMpegTPDec/src/tpdec_adts.cpp +++ b/libMpegTPDec/src/tpdec_adts.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -322,7 +322,13 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts, CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor); adtsRead_CrcEndReg(pAdts, hBs, crcReg); - pceBits = alignAnchor - FDKgetValidBits(hBs); + pceBits = (INT)alignAnchor - (INT)FDKgetValidBits(hBs); + adtsHeaderLength += pceBits; + + if (pceBits > (INT)alignAnchor) { + goto bail; + } + /* store the number of PCE bits */ bs.num_pce_bits = pceBits; } else { -- cgit v1.2.3 From f04a8a855cf8ddb5996c8e191fd3fa15b3808657 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:10:38 +0100 Subject: Do not allow channel configuration change within PCE for ADTS. Fixes assert. Bug: 146938557 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Icba99bd0eeba1f94298bdd08b85f1b0cb3cf241b --- libMpegTPDec/src/tpdec_adts.cpp | 38 ++++++++++++++++++++++++++++++++++++-- libMpegTPDec/src/tpdec_lib.cpp | 5 +++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/libMpegTPDec/src/tpdec_adts.cpp b/libMpegTPDec/src/tpdec_adts.cpp index 63cc44f..f936634 100644 --- a/libMpegTPDec/src/tpdec_adts.cpp +++ b/libMpegTPDec/src/tpdec_adts.cpp @@ -213,8 +213,8 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts, goto bail; } + FDKcrcReset(&pAdts->crcInfo); if (!bs.protection_absent) { - FDKcrcReset(&pAdts->crcInfo); FDKpushBack(hBs, 56); /* complete fixed and variable header! */ crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0); FDKpushFor(hBs, 56); @@ -314,12 +314,46 @@ TRANSPORTDEC_ERROR adtsRead_DecodeHeader(HANDLE_ADTS pAdts, if (bs.channel_config == 0) { int pceBits = 0; UINT alignAnchor = FDKgetValidBits(hBs); + CProgramConfig tmpPce; if (FDKreadBits(hBs, 3) == ID_PCE) { /* Got luck! Parse the PCE */ crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0); - CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor); + CProgramConfig_Init(&tmpPce); + CProgramConfig_Read(&tmpPce, hBs, alignAnchor); + + if (CProgramConfig_IsValid(&tmpPce)) { + if (CProgramConfig_IsValid(&oldPce)) { + /* Compare the new and the old PCE (tags ignored) */ + switch (CProgramConfig_Compare(&tmpPce, &oldPce)) { + case 0: /* Nothing to do because PCE matches the old one exactly. */ + case 1: /* Channel configuration not changed. Just new metadata. */ + FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce, + sizeof(CProgramConfig)); + break; + case 2: /* The number of channels are identical but not the config + */ + case -1: /* The channel configuration is completely different */ + default: + FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, + sizeof(CProgramConfig)); + FDKpushBack(hBs, adtsHeaderLength); + return TRANSPORTDEC_PARSE_ERROR; + } + } else { + FDKmemcpy(&pAsc->m_progrConfigElement, &tmpPce, + sizeof(CProgramConfig)); + } + } else { + if (CProgramConfig_IsValid(&oldPce)) { + FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, + sizeof(CProgramConfig)); + } else { + FDKpushBack(hBs, adtsHeaderLength); + return TRANSPORTDEC_PARSE_ERROR; + } + } adtsRead_CrcEndReg(pAdts, hBs, crcReg); pceBits = (INT)alignAnchor - (INT)FDKgetValidBits(hBs); diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 7bebbaa..ca35184 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -929,6 +929,11 @@ static TRANSPORTDEC_ERROR transportDec_readHeader( } } } + /* 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; + } } } else { /* Reset CRC because the next bits are the beginning of a -- cgit v1.2.3 From 00285819a2099a5bd0b0ebcdaebf8ee88f02546c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:20:20 +0100 Subject: Fix AACDEC_INTR handling for USAC configuration with multiple pre-roll AUs Bug: 148384920 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I88cd6da0b18c73f7b521ea58ba8b8f364278b64f --- libAACdec/src/aacdecoder_lib.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 86ec899..e90dbef 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1269,9 +1269,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } /* Signal bit stream interruption to other modules if required. */ - if (fTpInterruption || (flags & AACDEC_INTR)) { + if (fTpInterruption || ((flags & AACDEC_INTR) && (accessUnit == 0))) { aacDecoder_SignalInterruption(self); - if (!(flags & AACDEC_INTR)) { + if (!((flags & AACDEC_INTR) && (accessUnit == 0))) { ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR; goto bail; } @@ -1768,7 +1768,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (self->streamInfo.extAot != AOT_AAC_SLS) { INT pcmLimiterScale = 0; PCMDMX_ERROR dmxErr = PCMDMX_OK; - if (flags & (AACDEC_INTR)) { + if ((flags & AACDEC_INTR) && (accessUnit == 0)) { /* delete data from the past (e.g. mixdown coeficients) */ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA); } -- cgit v1.2.3 From 7d437ef090bc03cf628e34f00b3519c15789b0da Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:20:48 +0100 Subject: Request for Expert and Anchor loudness by default. Bug: 148385721 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I06b116b7d144b6959705119908a9db27946a0adb --- libDRCdec/src/drcDec_selectionProcess.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index d806ae9..fe6034c 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -753,8 +753,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams( hSelProcInput->loudnessNormalizationOn = 1; hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7)); hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX; - hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT; - hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT; + hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS; + hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL; hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT; hSelProcInput->deviceCutOffFrequency = 500; hSelProcInput->loudnessNormalizationGainDbMax = -- cgit v1.2.3 From 31f66f6d3ffcfa429c170b2c35250982d11f5082 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:21:07 +0100 Subject: Extend decoder API with audio output loudness info (FDKdec v3.1.3). Bug: 148385721 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I68b09883def21baef259c9ab914922567ab8cee3 --- documentation/aacDecoder.pdf | Bin 488412 -> 494126 bytes libAACdec/include/aacdecoder_lib.h | 28 ++++++++++++++++-------- libAACdec/src/aacdecoder.cpp | 2 ++ libAACdec/src/aacdecoder_lib.cpp | 34 +++++++++++++++++++++++++++++- libDRCdec/include/FDK_drcDecLib.h | 11 +++++++--- libDRCdec/src/FDK_drcDecLib.cpp | 2 ++ libDRCdec/src/drcDec_selectionProcess.cpp | 11 +++++----- libDRCdec/src/drcDec_selectionProcess.h | 2 ++ 8 files changed, 71 insertions(+), 19 deletions(-) diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index eb2a75e..f2131ed 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index 6c2fda4..6084bd3 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -892,15 +892,25 @@ typedef struct { 1770. If no level has been found in the bitstream the value is -1. */ SCHAR - drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, - this field indicates whether light (MPEG-4 Dynamic Range - Control tool) or heavy compression (DVB heavy - compression) dynamic range control shall take priority - on the outputs. For details, see ETSI TS 101 154, table - C.33. Possible values are: \n -1: No corresponding - metadata found in the bitstream \n 0: DRC presentation - mode not indicated \n 1: DRC presentation mode 1 \n 2: - DRC presentation mode 2 \n 3: Reserved */ + drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, + this field indicates whether light (MPEG-4 Dynamic Range + Control tool) or heavy compression (DVB heavy + compression) dynamic range control shall take priority + on the outputs. For details, see ETSI TS 101 154, table + C.33. Possible values are: \n -1: No corresponding + metadata found in the bitstream \n 0: DRC presentation + mode not indicated \n 1: DRC presentation mode 1 \n 2: + DRC presentation mode 2 \n 3: Reserved */ + INT outputLoudness; /*!< Audio output loudness in steps of -0.25 dB. Range: 0 + (0 dBFS) to 231 (-57.75 dBFS).\n A value of -1 + indicates that no loudness metadata is present.\n If + loudness normalization is active, the value corresponds + to the target loudness value set with + ::AAC_DRC_REFERENCE_LEVEL.\n If loudness normalization + is not active, the output loudness value corresponds to + the loudness metadata given in the bitstream.\n + Loudness metadata can originate from MPEG-4 DRC or + MPEG-D DRC. */ } CStreamInfo; diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index bd12d96..f747b2d 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) { pStreamInfo->drcProgRefLev = -1; /* set program reference level to not indicated */ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */ + + pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */ } /*! diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index e90dbef..2ba0e86 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -120,7 +120,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 3 #define AACDECODER_LIB_VL1 1 -#define AACDECODER_LIB_VL2 2 +#define AACDECODER_LIB_VL2 3 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" @@ -1764,6 +1764,38 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } } + if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) { + /* return output loudness information for MPEG-D DRC */ + LONG outputLoudness = + FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS); + if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) { + /* no valid MPEG-D DRC loudness value contained */ + self->streamInfo.outputLoudness = -1; + } else { + if (outputLoudness > 0) { + /* positive output loudness values (very unusual) are limited to 0 + * dB */ + self->streamInfo.outputLoudness = 0; + } else { + self->streamInfo.outputLoudness = + -(INT)outputLoudness >> + 22; /* negate and scale from e = 7 to e = (31-2) */ + } + } + } else { + /* return output loudness information for MPEG-4 DRC */ + if (self->streamInfo.drcProgRefLev < + 0) { /* no MPEG-4 DRC loudness metadata contained */ + self->streamInfo.outputLoudness = -1; + } else { + if (self->defaultTargetLoudness < + 0) { /* loudness normalization is off */ + self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev; + } else { + self->streamInfo.outputLoudness = self->defaultTargetLoudness; + } + } + } if (self->streamInfo.extAot != AOT_AAC_SLS) { INT pcmLimiterScale = 0; diff --git a/libDRCdec/include/FDK_drcDecLib.h b/libDRCdec/include/FDK_drcDecLib.h index 2d28d23..79f8566 100644 --- a/libDRCdec/include/FDK_drcDecLib.h +++ b/libDRCdec/include/FDK_drcDecLib.h @@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de extern "C" { #endif +#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE + typedef struct s_drc_decoder* HANDLE_DRC_DECODER; typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE; typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT; @@ -150,9 +152,12 @@ typedef enum { DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of Dynamic Range Control (DRC) or Loudness Normalization (LN) is activated */ - DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if - appropriate downmixInstruction exists - */ + DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if + appropriate downmixInstruction + exists */ + DRC_DEC_OUTPUT_LOUDNESS /**< output loudness in dB, with exponent e = 7, or + DRC_DEC_LOUDNESS_NOT_PRESENT if no loudness is + contained in the bitstream */ } DRC_DEC_USERPARAM; typedef enum { diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index e43279f..83b5773 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -519,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec, } case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED: return (LONG)hDrcDec->selProcOutput.targetChannelCount; + case DRC_DEC_OUTPUT_LOUDNESS: + return (LONG)hDrcDec->selProcOutput.outputLoudness; default: return 0; } diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index fe6034c..46ed740 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de #include "drcDec_selectionProcess.h" #include "drcDec_tools.h" -#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL - typedef enum { DETR_NONE = 0, DETR_NIGHT = 1, @@ -1136,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( FIXP_DBL loudnessDeviationMax = ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7); - ; - if (hSelProcInput->loudnessNormalizationOn) { + { retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode, hSelProcInput->loudnessMeasurementMethod, hSelProcInput->loudnessMeasurementSystem, @@ -1147,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( hSelProcInput->downmixIdRequested[downmixIdIndex], &loudnessNormalizationGainDb, &loudness); if (retVal) return (retVal); - } else { + } + + if (!hSelProcInput->loudnessNormalizationOn) { loudnessNormalizationGainDb = (FIXP_DBL)0; - loudness = UNDEFINED_LOUDNESS_VALUE; } retVal = _getSignalPeakLevel( @@ -2070,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( pSelectionData->loudnessNormalizationGainDbAdjusted + hSelProcInput->loudnessNormalizationGainModificationDb; hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel; + hSelProcOutput->outputLoudness = pSelectionData->outputLoudness; hSelProcOutput->boost = boost; hSelProcOutput->compress = compress; diff --git a/libDRCdec/src/drcDec_selectionProcess.h b/libDRCdec/src/drcDec_selectionProcess.h index 420bae6..0f878cf 100644 --- a/libDRCdec/src/drcDec_selectionProcess.h +++ b/libDRCdec/src/drcDec_selectionProcess.h @@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS; +#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1) + typedef enum { DRCDEC_SELECTION_PROCESS_NO_ERROR = 0, -- cgit v1.2.3 From 1d451971ca16a2ba3655dec3d23115b0a240a8bb Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:21:57 +0100 Subject: Revise and straighten out useless references from decoder documentation. Bug: 149481606 Test: doc update in header, so just make Change-Id: I656e76762ee336931d4f1938e5c39c8ad7f65954 --- documentation/aacDecoder.pdf | Bin 494126 -> 490978 bytes libAACdec/include/aacdecoder_lib.h | 116 ++++++++++++++----------------------- 2 files changed, 44 insertions(+), 72 deletions(-) diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index f2131ed..d04a7d6 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index 6084bd3..56f4ec1 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -164,9 +164,6 @@ The contents of each file is described in detail in this document. All header files are provided for usage in specific C/C++ programs. The main AAC decoder library API functions are located in aacdecoder_lib.h header file. -In binary releases the decoder core resides in statically linkable libraries, -for example libAACdec.a. - \section Calling_Sequence Calling Sequence @@ -174,19 +171,7 @@ The following sequence is necessary for proper decoding of ISO/MPEG-2/4 AAC, HE-AAC v2, or MPEG-D USAC bitstreams. In the following description, input stream read and output write function details are left out, since they may be implemented in a variety of configurations depending on the user's specific -requirements. The example implementation uses file-based input/output, and in -such case one may call mpegFileRead_Open() to open an input file and to allocate -memory for the required structures, and the corresponding mpegFileRead_Close() -to close opened files and to de-allocate associated structures. -mpegFileRead_Open() will attempt to detect the bitstream format and in case of -MPEG-4 file format or Raw Packets file format (a proprietary Fraunhofer IIS file -format suitable only for testing) it will read the Audio Specific Config data -(ASC). An unsuccessful attempt to recognize the bitstream format requires the -user to provide this information manually. For any other bitstream formats that -are usually applicable in streaming applications, the decoder itself will try to -synchronize and parse the given bitstream fragment using the FDK transport -library. Hence, for streaming applications (without file access) this step is -not necessary. +requirements. -# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder @@ -205,19 +190,17 @@ do { working memory (a client-supplied input buffer "inBuffer" in framework). This buffer will be used to load AAC bitstream data to the decoder. Only when all data in this buffer has been processed will the decoder signal an empty buffer. -For file-based input, you may invoke mpegFileRead_Read() to acquire new -bitstream data. -# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer with the client-supplied bitstream input buffer. Note, if the data loaded in to the internal buffer is not sufficient to decode a frame, aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a sufficient amount of data is loaded in to the internal buffer. For streaming formats (ADTS, LOAS), it is acceptable to load more than one frame to the -decoder. However, for RAW file format (Fraunhofer IIS proprietary format), only -one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For -least amount of communication delay, fill and decode should be performed on a -frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo, -inBuffer, bytesRead, bytesValid); \endcode +decoder. However, for packed based formats, only one frame may be loaded to the +decoder per aacDecoder_DecodeFrame() call. For least amount of communication +delay, fill and decode should be performed on a frame by frame basis. \code + ErrorStatus = aacDecoder_Fill(aacDecoderInfo, inBuffer, bytesRead, +bytesValid); \endcode -# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes decoded PCM audio data to a client-supplied buffer. It is the client's responsibility to allocate a buffer which is large enough to hold the decoded @@ -225,12 +208,9 @@ output data. \code ErrorStatus = aacDecoder_DecodeFrame(aacDecoderInfo, TimeData, OUT_BUF_SIZE, flags); \endcode If the bitstream configuration (number of channels, sample rate, frame size) is not known a priori, you may call aacDecoder_GetStreamInfo() to retrieve a structure that contains this -information. You may use this data to initialize an audio output device. In the -example program, if the number of channels or the sample rate has changed since -program start or the previously decoded frame, the audio output device is then -re-initialized. If WAVE file output is chosen, a new WAVE file for each new -stream configuration is be created. \code p_si = -aacDecoder_GetStreamInfo(aacDecoderInfo); \endcode +information. You may use this data to initialize an audio output device. \code + p_si = aacDecoder_GetStreamInfo(aacDecoderInfo); +\endcode -# Repeat steps 5 to 7 until no data is available to decode any more, or in case of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush || forceContinue); \endcode @@ -239,7 +219,7 @@ structures. \code aacDecoder_Close(aacDecoderInfo); \endcode \image latex decode.png "Decode calling sequence" width=11cm -\image latex change_source.png "Change data source sequence" width 5cm +\image latex change_source.png "Change data source sequence" width=5cm \image latex conceal.png "Error concealment sequence" width=14cm @@ -296,16 +276,14 @@ input buffer, and one to hold the decoded output PCM sample data. In resource limited applications, the output buffer may be reused as an external input buffer prior to the subsequence aacDecoder_Fill() function call. -The external input buffer is set in the example program and its size is defined -by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data -to the decoder-internal input buffer, use the function aacDecoder_Fill(). This -function returns important information regarding the number of bytes in the -external input buffer that have not yet been copied into the internal input -buffer (variable bytesValid). Once the external buffer has been fully copied, it -can be completely re-filled again. In case you wish to refill the buffer while -there are unprocessed bytes (bytesValid is unequal 0), you should preserve the -unconsumed data. However, we recommend to refill the buffer only when bytesValid -returns 0. +To feed the data to the decoder-internal input buffer, use the +function aacDecoder_Fill(). This function returns important information +regarding the number of bytes in the external input buffer that have not yet +been copied into the internal input buffer (variable bytesValid). Once the +external buffer has been fully copied, it can be completely re-filled again. In +case you wish to refill the buffer while there are unprocessed bytes (bytesValid +is unequal 0), you should preserve the unconsumed data. However, we recommend to +refill the buffer only when bytesValid returns 0. The bytesValid parameter is an input and output parameter to the FDK decoder. As an input, it signals how many valid bytes are available in the external buffer. @@ -340,10 +318,7 @@ explanation, please refer to ISO/IEC 13818-7:2005(E), chapter 8.5.3.2. In case a Program Config is included in the audio configuration, the channel mapping described within it will be adopted. -In case of MPEG-D Surround the channel mapping will follow the same criteria -described in ISO/IEC 13818-7:2005(E), but adding corresponding top channels (if -available) to the channel types in order to avoid ambiguity. The examples below -explain these aspects in detail. +The examples below explain these aspects in detail. \section OutputFormatChange Changing the audio output format @@ -689,9 +664,7 @@ typedef enum { 2. If the parameter value is greater than that of ::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same value. \n - 3. This parameter does not affect MPEG Surround processing. - \n - 4. This parameter will be ignored if the number of encoded + 3. This parameter will be ignored if the number of encoded audio channels is greater than 8. */ AAC_PCM_MAX_OUTPUT_CHANNELS = 0x0012, /*!< Maximum number of PCM output channels. If lower than the @@ -718,11 +691,7 @@ typedef enum { 2. If the parameter value is greater than zero but smaller than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same value. \n - 3. The operating mode of the MPEG Surround module will be - set accordingly. \n - 4. Setting this parameter with any value will disable the - binaural processing of the MPEG Surround module - 5. This parameter will be ignored if the number of encoded + 3. This parameter will be ignored if the number of encoded audio channels is greater than 8. */ AAC_METADATA_PROFILE = 0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */ @@ -803,11 +772,11 @@ typedef enum { sequences for fading in and out, if provided in the bitstream.\n Enabled album mode makes use of dedicated album loudness information, if provided in the bitstream.\n */ - AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing - mode. \n -1: Use internal default. Implies MPEG - Surround partially complex accordingly. \n 0: - Use complex QMF data mode. \n 1: Use real (low - power) QMF data mode. \n */ + AAC_QMF_LOWPOWER = + 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n + -1: Use internal default. \n + 0: Use complex QMF data mode. \n + 1: Use real (low power) QMF data mode. \n */ AAC_TPDEC_CLEAR_BUFFER = 0x0603 /*!< Clear internal bit stream buffer of transport layers. The decoder will start decoding at new data passed after this event @@ -1038,21 +1007,24 @@ LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self, const UINT bufferSize[], UINT *bytesValid); -#define AACDEC_CONCEAL \ - 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \ - concealment module to generate a substitute signal for one lost frame. \ - New input data will not be considered. */ -#define AACDEC_FLUSH \ - 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \ - delayed audio without having new input data. Thus new input data will \ - not be considered.*/ -#define AACDEC_INTR \ - 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \ - discontinuity. Resync any internals as necessary. */ -#define AACDEC_CLRHIST \ - 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \ - history buffers. CAUTION: This can cause discontinuities in the output \ - signal. */ +/** Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment + * module to generate a substitute signal for one lost frame. New input data + * will not be considered. + */ +#define AACDEC_CONCEAL 1 +/** Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed + * audio without having new input data. Thus new input data will not be + * considered. + */ +#define AACDEC_FLUSH 2 +/** Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data + * discontinuity. Resync any internals as necessary. + */ +#define AACDEC_INTR 4 +/** Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history + * buffers. CAUTION: This can cause discontinuities in the output signal. + */ +#define AACDEC_CLRHIST 8 /** * \brief Decode one audio frame -- cgit v1.2.3 From 925092e8fcd9f3635fdff6ff34f8a4a290916885 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:22:38 +0100 Subject: Revise and straighten out pointless description from encoder documentation Bug: 149481606 Test: header doc update, so just make Change-Id: If5c7fcf96f97a3a1e8ee06bd24fb247c094508bd --- documentation/aacEncoder.pdf | Bin 461225 -> 443582 bytes libAACenc/include/aacenc_lib.h | 41 +++++++++-------------------------------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/documentation/aacEncoder.pdf b/documentation/aacEncoder.pdf index e438e27..d9300a0 100644 Binary files a/documentation/aacEncoder.pdf and b/documentation/aacEncoder.pdf differ diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h index 2e47571..01a9d36 100644 --- a/libAACenc/include/aacenc_lib.h +++ b/libAACenc/include/aacenc_lib.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -149,12 +149,6 @@ All API header files are located in the folder /include of the release package. All header files are provided for usage in C/C++ programs. The AAC encoder library API functions are located in aacenc_lib.h. -In binary releases the encoder core resides in statically linkable libraries -called for example libAACenc.a/libFDK.a (LINUX) or FDK_fastaaclib.lib (MS Visual -C++) for the plain AAC-LC core encoder and libSBRenc.a (LINUX) or -FDK_sbrEncLib.lib (MS Visual C++) for the SBR (Spectral Band Replication) and PS -(Parametric Stereo) modules. - \section CallingSequence Calling Sequence For encoding of ISO/MPEG-2/4 AAC bitstreams the following sequence is mandatory. @@ -326,18 +320,12 @@ input buffer, simulating a modulo buffer: \code if (outargs.numInSamples>0) { \endcode \section writeOutData Output Bitstream Data -If any AAC bitstream data is available, write it to output file or device. This -can be done once the following condition is true: \code if -(outargs.numOutBytes>0) { - +If any AAC bitstream data is available, write it to output file or device as +follows. \code if (outargs.numOutBytes>0) { FDKfwrite(outputBuffer, +outargs.numOutBytes, 1, pOutFile); } \endcode -If you use file I/O then for example call mpegFileWrite_Write() from the library -libMpegFileWrite \code mpegFileWrite_Write(hMpegFile, outputBuffer, -outargs.numOutBytes, aacEncoder_GetParam(hAacEncoder, AACENC_GRANULE_LENGTH)); -\endcode - \section cfgMetaData Meta Data Configuration If the present library is configured with Metadata support, it is possible to @@ -427,7 +415,7 @@ switch (nChannels) { return chMode; \endcode -\subsection bitreservoir Bitreservoir Configuration +\subsection peakbitrate Peak Bitrate Configuration In AAC, the default bitreservoir configuration depends on the chosen bitrate per frame and the number of effective channels. The size can be determined as below. \f[ @@ -436,17 +424,10 @@ bitreservoir = nEffChannels*6144 - (bitrate*framelength/samplerate) Due to audio quality concerns it is not recommended to change the bitreservoir size to a lower value than the default setting! However, for minimizing the delay for streaming applications or for achieving a constant size of the -bitstream packages in each frame, it may be necessaray to change the -bitreservoir size. This can be done with the ::AACENC_PEAK_BITRATE parameter. -\code +bitstream packages in each frame, it may be necessaray to limit the maximum bits +per frame size. This can be done with the ::AACENC_PEAK_BITRATE parameter. \code aacEncoder_SetParam(hAacEncoder, AACENC_PEAK_BITRATE, value); \endcode -By setting ::AACENC_BITRATEMODE to fixed framing, the bitreservoir is disabled. -A disabled bitreservoir results in a constant size for each bitstream package. -Please note that especially at lower bitrates a disabled bitreservoir can -downgrade the audio quality considerably! The default bitreservoir configuration -can be achieved as follows. \code aacEncoder_SetParam(hAacEncoder, -AACENC_BITRESERVOIR, -1); \endcode To achieve acceptable audio quality with a reduced bitreservoir size setting at least 1000 bits per audio channel is recommended. For a multichannel audio file @@ -967,9 +948,7 @@ in this Fraunhofer IIS AAC encoder. AAC has been designed in that way. \subsection BEHAVIOUR_ESTIM_AVG_FRAMESIZES Estimating Average Frame Sizes -A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel (there is -also one mode with 1920 samples per channel but this is only for special -purposes such as DAB+ digital radio). +A HE-AAC v1 or v2 audio frame contains 2048 PCM samples per channel. The number of HE-AAC frames \f$N\_FRAMES\f$ per second at 44.1 kHz is: @@ -1082,9 +1061,7 @@ typedef struct AACENCODER *HANDLE_AACENCODER; typedef struct { UINT maxOutBufBytes; /*!< Maximum number of encoder bitstream bytes within one frame. Size depends on maximum number of supported - channels in encoder instance. For superframing (as - used for example in DAB+), size has to be a multiple - accordingly. */ + channels in encoder instance. */ UINT maxAncBytes; /*!< Maximum number of ancillary data bytes which can be inserted into bitstream within one frame. */ -- cgit v1.2.3 From 7b5389e63fb048932f27f621c59005071efa3741 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:23:40 +0100 Subject: Ensure that QC_OUT_CHANNEL struct in encoder always uses aligned memory Bug: 149489652 Test: atest android.media.cts.EncoderTest#testAACEncoders Change-Id: Ifc513ef20639f04c7252ade5519cc8e8c2fdbd50 --- libAACenc/src/aacEnc_ram.cpp | 4 ++-- libAACenc/src/aacEnc_ram.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libAACenc/src/aacEnc_ram.cpp b/libAACenc/src/aacEnc_ram.cpp index 77b1131..25e2aec 100644 --- a/libAACenc/src/aacEnc_ram.cpp +++ b/libAACenc/src/aacEnc_ram.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -204,5 +204,5 @@ QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) { * (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned, * so the cast is safe */ return reinterpret_cast(reinterpret_cast( - dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL))); + dynamic_RAM + P_BUF_0 + n * ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)))); } diff --git a/libAACenc/src/aacEnc_ram.h b/libAACenc/src/aacEnc_ram.h index 0775aae..f24eef1 100644 --- a/libAACenc/src/aacEnc_ram.h +++ b/libAACenc/src/aacEnc_ram.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -198,7 +198,7 @@ struct AAC_ENC { +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8))) +#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)) * (8)) #define BUF_SIZE_1 \ (ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \ (BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \ -- cgit v1.2.3 From 6b0aab087dd4230e2e64f0fdc4656276c00e22bc Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:23:56 +0100 Subject: Fix SBR encoder element mapping for channel configurations with more than one layer Bug: 149489652 Test: atest android.media.cts.EncoderTest#testAACEncoders Change-Id: I8cd9e7f9aaeb62629f916f8d0dba7422d9a5e878 --- libAACenc/src/aacenc_lib.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 0f0094f..15b06bd 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -446,6 +446,24 @@ static SBR_PS_SIGNALING getSbrSignalingMode( return sbrSignaling; } +static inline INT getAssociatedChElement(SBR_ELEMENT_INFO *elInfoSbr, + CHANNEL_MAPPING *channelMapping) { + ELEMENT_INFO *elInfo = channelMapping->elInfo; + INT nElements = channelMapping->nElements; + INT associatedChElement = -1; + int i; + + for (i = 0; i < nElements; i++) { + if (elInfoSbr->elType == elInfo[i].elType && + elInfoSbr->instanceTag == elInfo[i].instanceTag) { + associatedChElement = i; + break; + } + } + + return associatedChElement; +} + /**************************************************************************** Allocate Encoder ****************************************************************************/ @@ -1921,7 +1939,15 @@ AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder, { hAacEncoder->extPayload[nExtensions].dataSize = hAacEncoder->pSbrPayload->dataSize[nPayload][i]; - hAacEncoder->extPayload[nExtensions].associatedChElement = i; + hAacEncoder->extPayload[nExtensions].associatedChElement = + getAssociatedChElement( + &hAacEncoder->hEnvEnc->sbrElement[i]->elInfo, + &hAacEncoder->hAacEnc->channelMapping); + if (hAacEncoder->extPayload[nExtensions].associatedChElement == + -1) { + err = AACENC_ENCODE_ERROR; + goto bail; + } } hAacEncoder->extPayload[nExtensions].dataType = EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set -- cgit v1.2.3 From 79305e068e75df9123f114c95606ef49590f0019 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:24:21 +0100 Subject: Improve encoder audio quality for low bitreservoir configuration. Bug: 149489652 Test: atest android.media.cts.EncoderTest#testAACEncoders Change-Id: I87d5695a93b1f130b95b45d48157e6aaf947709d --- libAACenc/src/aacenc.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp index 8b8a1ad..b6f733d 100644 --- a/libAACenc/src/aacenc.cpp +++ b/libAACenc/src/aacenc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" +#define BITRES_MIN \ + 300 /* default threshold for using reduced/disabled bitres mode */ #define BITRES_MAX_LD 4000 #define BITRES_MIN_LD 500 #define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */ @@ -550,7 +552,8 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize( (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0; qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7); } else { - INT bitreservoir = -1; /* default bitrservoir size*/ + INT bitreservoir = -1; /* default bitreservoir size*/ + bitresMin = BITRES_MIN; if (isLowDelay(config->audioObjectType)) { INT brPerChannel = config->bitRate / config->nChannels; brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel)); @@ -601,9 +604,9 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize( qcInit.nSubFrames = config->nSubFrames; qcInit.padding.paddingRest = config->sampleRate; - if (qcInit.bitRes >= bitresMin * config->nChannels) { + if (qcInit.maxBits - qcInit.averageBits >= bitresMin * config->nChannels) { qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */ - } else if (qcInit.bitRes > 0) { + } else if (qcInit.maxBits > qcInit.averageBits) { qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */ } else { qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */ -- cgit v1.2.3 From 443d38963e804ce1133e2338937e1cf389092b52 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:25:55 +0100 Subject: Enhance encoder audio quality for vbr (FDKenc v4.0.1). Bug: 149489652 Test: atest android.media.cts.EncoderTest#testAACEncoders Change-Id: I4af82bd104a94710d1977eaa0bd086aa743d3adf --- documentation/aacEncoder.pdf | Bin 443582 -> 443728 bytes libAACenc/include/aacenc_lib.h | 45 +++++++++++++++++++++-------------------- libAACenc/src/aacenc_lib.cpp | 2 +- libAACenc/src/adj_thr.cpp | 8 -------- libAACenc/src/bandwidth.cpp | 12 +++++------ libAACenc/src/qc_main.cpp | 17 ++++++---------- 6 files changed, 36 insertions(+), 48 deletions(-) diff --git a/documentation/aacEncoder.pdf b/documentation/aacEncoder.pdf index d9300a0..77b8f4c 100644 Binary files a/documentation/aacEncoder.pdf and b/documentation/aacEncoder.pdf differ diff --git a/libAACenc/include/aacenc_lib.h b/libAACenc/include/aacenc_lib.h index 01a9d36..71f7556 100644 --- a/libAACenc/include/aacenc_lib.h +++ b/libAACenc/include/aacenc_lib.h @@ -436,31 +436,32 @@ audio quality. \subsection vbrmode Variable Bitrate Mode -The encoder provides various Variable Bitrate Modes that differ in audio quality -and average overall bitrate. The given values are averages over time, different -encoder settings and strongly depend on the type of audio signal. The VBR -configurations can be adjusted via ::AACENC_BITRATEMODE encoder parameter. +The variable bitrate (VBR) mode coding adapts the bit consumption to the +psychoacoustic requirements of the signal. The encoder ignores the user-defined +bit rate and selects a suitable pre-defined configuration based on the provided +AOT. The VBR mode 1 is tuned for HE-AACv2, for VBR mode 2, HE-AACv1 should be +used. VBR modes 3-5 should be used with Low-Complexity AAC. When encoding +AAC-ELD, the best mode is selected automatically. + +The bitrates given in the table are averages over time and different encoder +settings. They strongly depend on the type of audio signal. The VBR +configurations can be adjusted with the ::AACENC_BITRATEMODE encoder parameter. \verbatim --------------------------------------------- - VBR_MODE | Approx. Bitrate in kbps/channel - | AAC-LC | AAC-LD/AC_ELD -----------+---------------+----------------- - VBR_1 | 32 - 48 | 32 - 56 - VBR_2 | 40 - 56 | 40 - 64 - VBR_3 | 48 - 64 | 48 - 72 - VBR_4 | 64 - 80 | 64 - 88 - VBR_5 | 96 - 120 | 112 - 144 +----------------------------------------------- + VBR_MODE | Approx. Bitrate in kbps for stereo + | AAC-LC | AAC-ELD +----------+---------------+-------------------- + VBR_1 | 32 (HE-AACv2) | 48 + VBR_2 | 72 (HE-AACv1) | 56 + VBR_3 | 112 | 72 + VBR_4 | 148 | 148 + VBR_5 | 228 | 224 -------------------------------------------- \endverbatim -The bitrate ranges apply for individual audio channels. In case of multichannel -configurations the average bitrate might be estimated by multiplying with the -number of effective channels. This corresponds to all audio input channels -exclusively the low frequency channel. At configurations which are making use of -downmix modules the AAC core channels respectively downmix channels shall be -considered. For ::AACENC_AOT which are using SBR, the average bitrate can be -estimated by using the ratio of 0.5 for dualrate SBR and 0.75 for downsampled -SBR configurations. - +Note that these figures are valid for stereo encoding only. VBR modes 2-5 will +yield much lower bit rates when encoding single-channel input. For +configurations which are making use of downmix modules the AAC core channels +respectively downmix channels shall be considered. \subsection encQual Audio Quality Considerations The default encoder configuration is suggested to be used. Encoder tools such as diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 15b06bd..2c2010f 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de /* Encoder library info */ #define AACENCODER_LIB_VL0 4 #define AACENCODER_LIB_VL1 0 -#define AACENCODER_LIB_VL2 0 +#define AACENCODER_LIB_VL2 1 #define AACENCODER_LIB_TITLE "AAC Encoder" #ifdef __ANDROID__ #define AACENCODER_LIB_BUILD_DATE "" diff --git a/libAACenc/src/adj_thr.cpp b/libAACenc/src/adj_thr.cpp index 226d003..239abd0 100644 --- a/libAACenc/src/adj_thr.cpp +++ b/libAACenc/src/adj_thr.cpp @@ -1302,14 +1302,6 @@ static void FDKaacEnc_reduceThresholdsVBR( if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f)) sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); - /* minimum of 29 dB Ratio for Thresholds */ - if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) > - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) { - sfbThrReducedLdData = fixMax( - sfbThrReducedLdData, - sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)); - } - sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData); qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; diff --git a/libAACenc/src/bandwidth.cpp b/libAACenc/src/bandwidth.cpp index 36cd64d..e814f05 100644 --- a/libAACenc/src/bandwidth.cpp +++ b/libAACenc/src/bandwidth.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -151,11 +151,11 @@ typedef struct { static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = { {AACENC_BR_MODE_CBR, 0, 0}, - {AACENC_BR_MODE_VBR_1, 13050, 13050}, - {AACENC_BR_MODE_VBR_2, 13050, 13050}, - {AACENC_BR_MODE_VBR_3, 14260, 14260}, - {AACENC_BR_MODE_VBR_4, 15500, 15500}, - {AACENC_BR_MODE_VBR_5, 48000, 48000}, + {AACENC_BR_MODE_VBR_1, 13000, 13000}, + {AACENC_BR_MODE_VBR_2, 13000, 13000}, + {AACENC_BR_MODE_VBR_3, 15750, 15750}, + {AACENC_BR_MODE_VBR_4, 16500, 16500}, + {AACENC_BR_MODE_VBR_5, 19293, 19293}, {AACENC_BR_MODE_SFR, 0, 0}, {AACENC_BR_MODE_FF, 0, 0} diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp index ba3bc7e..bcfaa23 100644 --- a/libAACenc/src/qc_main.cpp +++ b/libAACenc/src/qc_main.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -121,20 +121,15 @@ typedef struct { static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = { {QCDATA_BR_MODE_VBR_1, - FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56 - (AAC-LD/ELD) kbps/channel */ + FL2FXCONST_DBL(0.150f)}, /* Approx. 32 kbps mono AAC-LC + SBR + PS */ {QCDATA_BR_MODE_VBR_2, - FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64 - (AAC-LD/ELD) kbps/channel */ + FL2FXCONST_DBL(0.162f)}, /* Approx. 64 kbps stereo AAC-LC + SBR */ {QCDATA_BR_MODE_VBR_3, - FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72 - (AAC-LD/ELD) kbps/channel */ + FL2FXCONST_DBL(0.176f)}, /* Approx. 96 kbps stereo AAC-LC */ {QCDATA_BR_MODE_VBR_4, - FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88 - (AAC-LD/ELD) kbps/channel */ + FL2FXCONST_DBL(0.120f)}, /* Approx. 128 kbps stereo AAC-LC */ {QCDATA_BR_MODE_VBR_5, - FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144 - (AAC-LD/ELD) kbps/channel */ + FL2FXCONST_DBL(0.070f)} /* Approx. 192 kbps stereo AAC-LC */ }; static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) { -- cgit v1.2.3 From 548244319396da7ed6a5601e6cfed0fcd946413a Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:27:25 +0100 Subject: Restructure QMF implementation and provide 16/32 bit implementation in parallel. Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I2c6b332a0b5c4966a3f680d7a4d562d9bf18752c --- libFDK/include/FDK_qmf_domain.h | 12 +- libFDK/include/qmf.h | 105 ++++++++----- libFDK/include/qmf_pcm.h | 218 +++++++++++++++++++++++++- libFDK/src/FDK_qmf_domain.cpp | 23 ++- libFDK/src/qmf.cpp | 333 ++-------------------------------------- 5 files changed, 318 insertions(+), 373 deletions(-) diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h index 5c12682..d8bc8ce 100644 --- a/libFDK/include/FDK_qmf_domain.h +++ b/libFDK/include/FDK_qmf_domain.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -145,15 +145,15 @@ H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL) #define QMF_DOMAIN_OV_TIMESLOTS_16 (3) #define QMF_DOMAIN_OV_TIMESLOTS_32 (6) -H_ALLOC_MEM(AnaQmfStates, FIXP_QAS) +H_ALLOC_MEM(AnaQmfStates, FIXP_DBL) H_ALLOC_MEM(SynQmfStates, FIXP_QSS) H_ALLOC_MEM(QmfSlotsReal, FIXP_DBL *) H_ALLOC_MEM(QmfSlotsImag, FIXP_DBL *) H_ALLOC_MEM(QmfOverlapBuffer, FIXP_DBL) -H_ALLOC_MEM(AnaQmfStates16, FIXP_QAS) -H_ALLOC_MEM(AnaQmfStates24, FIXP_QAS) -H_ALLOC_MEM(AnaQmfStates32, FIXP_QAS) +H_ALLOC_MEM(AnaQmfStates16, FIXP_DBL) +H_ALLOC_MEM(AnaQmfStates24, FIXP_DBL) +H_ALLOC_MEM(AnaQmfStates32, FIXP_DBL) H_ALLOC_MEM(QmfSlotsReal16, FIXP_DBL *) H_ALLOC_MEM(QmfSlotsReal32, FIXP_DBL *) H_ALLOC_MEM(QmfSlotsImag16, FIXP_DBL *) @@ -244,7 +244,7 @@ typedef struct { (workBuf_nTimeSlots * workBuf_nBands * CMPLX_MOD). */ USHORT workBufferOffset; /*!< Offset within work buffer. */ USHORT workBufferSectSize; /*!< Size of work buffer section. */ - FIXP_QAS * + FIXP_DBL * pAnaQmfStates; /*!< Pointer to QMF analysis states (persistent memory). */ FIXP_DBL *pOverlapBuffer; /*!< Pointer to QMF overlap/delay memory (persistent diff --git a/libFDK/include/qmf.h b/libFDK/include/qmf.h index 609c6f1..78770b3 100644 --- a/libFDK/include/qmf.h +++ b/libFDK/include/qmf.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -116,6 +116,7 @@ amm-info@iis.fraunhofer.de #define FIXP_QAS FIXP_PCM #define QAS_BITS SAMPLE_BITS +#define INT_PCM_QMFIN INT_PCM #define FIXP_QSS FIXP_DBL #define QSS_BITS DFRACT_BITS @@ -201,66 +202,70 @@ struct QMF_FILTER_BANK { typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK; +int qmfInitAnalysisFilterBank( + HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ +#if SAMPLE_BITS == 16 + +int qmfInitAnalysisFilterBank( + HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_DBL *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ +#endif + void qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ - const LONG *timeIn, /*!< Time signal */ + const INT_PCM *timeIn, /*!< Time signal */ const int timeIn_e, /*!< Exponent of audio data */ const int stride, /*!< Stride factor of audio data */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ ); +#if SAMPLE_BITS == 16 void qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ - const INT_PCM *timeIn, /*!< Time signal */ + const LONG *timeIn, /*!< Time signal */ const int timeIn_e, /*!< Exponent of audio data */ const int stride, /*!< Stride factor of audio data */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ -); - -void qmfSynthesisFiltering( - HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ - FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */ - FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */ - const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ - const int ov_len, /*!< Length of band overlap */ - INT_PCM *timeOut, /*!< Time signal */ - const INT stride, /*!< Stride factor of audio data */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be - aligned */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */ ); - -int qmfInitAnalysisFilterBank( - HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ - FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */ - int noCols, /*!< Number of time slots */ - int lsb, /*!< Number of lower bands */ - int usb, /*!< Number of upper bands */ - int no_channels, /*!< Number of critically sampled bands */ - int flags); /*!< Flags */ +#endif void qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ FIXP_DBL *qmfReal, /*!< Low and High band, real */ FIXP_DBL *qmfImag, /*!< Low and High band, imag */ - const LONG *timeIn, /*!< Pointer to input */ + const INT_PCM *timeIn, /*!< Pointer to input */ const int stride, /*!< stride factor of input */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ ); +#if SAMPLE_BITS == 16 void qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ FIXP_DBL *qmfReal, /*!< Low and High band, real */ FIXP_DBL *qmfImag, /*!< Low and High band, imag */ - const INT_PCM *timeIn, /*!< Pointer to input */ + const LONG *timeIn, /*!< Pointer to input */ const int stride, /*!< stride factor of input */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */ ); +#endif + int qmfInitSynthesisFilterBank( HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */ @@ -270,12 +275,46 @@ int qmfInitSynthesisFilterBank( int no_channels, /*!< Number of critically sampled bands */ int flags); /*!< Flags */ +void qmfSynthesisFiltering( + HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */ + FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */ + const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const int ov_len, /*!< Length of band overlap */ + INT_PCM *timeOut, /*!< Time signal */ + const INT stride, /*!< Stride factor of audio data */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer. It must be + aligned */ +); +#if SAMPLE_BITS == 16 + +void qmfSynthesisFiltering( + HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_DBL **QmfBufferReal, /*!< Pointer to real subband slots */ + FIXP_DBL **QmfBufferImag, /*!< Pointer to imag subband slots */ + const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const int ov_len, /*!< Length of band overlap */ + LONG *timeOut, /*!< Time signal */ + const int timeOut_e, /*!< Target exponent for timeOut */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporary working buffer */ +); +#endif + void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf, const FIXP_DBL *realSlot, const FIXP_DBL *imagSlot, const int scaleFactorLowBand, const int scaleFactorHighBand, INT_PCM *timeOut, const int timeOut_e, FIXP_DBL *pWorkBuffer); +#if SAMPLE_BITS == 16 + +void qmfSynthesisFilteringSlot(HANDLE_QMF_FILTER_BANK synQmf, + const FIXP_DBL *realSlot, + const FIXP_DBL *imagSlot, + const int scaleFactorLowBand, + const int scaleFactorHighBand, LONG *timeOut, + const int timeOut_e, FIXP_DBL *pWorkBuffer); +#endif void qmfChangeOutScalefactor( HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ @@ -291,11 +330,5 @@ void qmfChangeOutGain( FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */ int outputGainScale /*!< New gain for output data (exponent) */ ); -void qmfSynPrototypeFirSlot( - HANDLE_QMF_FILTER_BANK qmf, - FIXP_DBL *RESTRICT realSlot, /*!< Input: Pointer to real Slot */ - FIXP_DBL *RESTRICT imagSlot, /*!< Input: Pointer to imag Slot */ - INT_PCM *RESTRICT timeOut, /*!< Time domain data */ - const int timeOut_e); #endif /*ifndef QMF_H */ diff --git a/libFDK/include/qmf_pcm.h b/libFDK/include/qmf_pcm.h index f24e0cd..5da53db 100644 --- a/libFDK/include/qmf_pcm.h +++ b/libFDK/include/qmf_pcm.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -402,4 +402,220 @@ void qmfSynthesisFiltering( timeOut + (i * L * stride), stride, pWorkBuffer); } /* no_col loop i */ } + +/*! + * + * \brief Create QMF filter bank instance + * + * + * \return 0 if successful + * + */ +int qmfInitAnalysisFilterBank( + HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */ + FIXP_QAS *pFilterStates, /*!< Handle to filter states */ + int noCols, /*!< Number of timeslots per frame */ + int lsb, /*!< lower end of QMF */ + int usb, /*!< upper end of QMF */ + int no_channels, /*!< Number of channels (bands) */ + int flags) /*!< Low Power flag */ +{ + int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, + no_channels, flags, 0); + if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) { + FDKmemclear(h_Qmf->FilterStates, + (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS)); + } + + FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb); + + return err; +} + +#ifndef FUNCTION_qmfAnaPrototypeFirSlot +/*! + \brief Perform Analysis Prototype Filtering on a single slot of input data. +*/ +static void qmfAnaPrototypeFirSlot( + FIXP_DBL *analysisBuffer, + INT no_channels, /*!< Number channels of analysis filter */ + const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */ + FIXP_QAS *RESTRICT pFilterStates) { + INT k; + + FIXP_DBL accu; + const FIXP_PFT *RESTRICT p_flt = p_filter; + FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1; + FIXP_DBL *RESTRICT pData_1 = analysisBuffer; + + FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates; + FIXP_QAS *RESTRICT sta_1 = + (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1; + INT pfltStep = QMF_NO_POLY * (p_stride); + INT staStep1 = no_channels << 1; + INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */ + + /* FIR filters 127..64 0..63 */ + for (k = 0; k < no_channels; k++) { + accu = fMultDiv2(p_flt[0], *sta_1); + sta_1 -= staStep1; + accu += fMultDiv2(p_flt[1], *sta_1); + sta_1 -= staStep1; + accu += fMultDiv2(p_flt[2], *sta_1); + sta_1 -= staStep1; + accu += fMultDiv2(p_flt[3], *sta_1); + sta_1 -= staStep1; + accu += fMultDiv2(p_flt[4], *sta_1); + *pData_1++ = (accu << 1); + sta_1 += staStep2; + + p_flt += pfltStep; + accu = fMultDiv2(p_flt[0], *sta_0); + sta_0 += staStep1; + accu += fMultDiv2(p_flt[1], *sta_0); + sta_0 += staStep1; + accu += fMultDiv2(p_flt[2], *sta_0); + sta_0 += staStep1; + accu += fMultDiv2(p_flt[3], *sta_0); + sta_0 += staStep1; + accu += fMultDiv2(p_flt[4], *sta_0); + *pData_0-- = (accu << 1); + sta_0 -= staStep2; + } +} +#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */ + +#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric +/*! + \brief Perform Analysis Prototype Filtering on a single slot of input data. +*/ +static void qmfAnaPrototypeFirSlot_NonSymmetric( + FIXP_DBL *analysisBuffer, + int no_channels, /*!< Number channels of analysis filter */ + const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */ + FIXP_QAS *RESTRICT pFilterStates) { + const FIXP_PFT *RESTRICT p_flt = p_filter; + int p, k; + + for (k = 0; k < 2 * no_channels; k++) { + FIXP_DBL accu = (FIXP_DBL)0; + + p_flt += QMF_NO_POLY * (p_stride - 1); + + /* + Perform FIR-Filter + */ + for (p = 0; p < QMF_NO_POLY; p++) { + accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]); + } + analysisBuffer[2 * no_channels - 1 - k] = (accu << 1); + pFilterStates++; + } +} +#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */ + +/* + * \brief Perform one QMF slot analysis of the time domain data of timeIn + * with specified stride and stores the real part of the subband + * samples in rSubband, and the imaginary part in iSubband + * + * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case + * of implicit resampling (USAC with reduced 3/4 core frame length). + */ +void qmfAnalysisFilteringSlot( + HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_DBL *qmfReal, /*!< Low and High band, real */ + FIXP_DBL *qmfImag, /*!< Low and High band, imag */ + const INT_PCM_QMFIN *RESTRICT timeIn, /*!< Pointer to input */ + const int stride, /*!< stride factor of input */ + FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ +) { + int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1); + /* + Feed time signal into oldest anaQmf->no_channels states + */ + { + FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset; + + /* Feed and scale actual time in slot */ + for (int i = anaQmf->no_channels >> 1; i != 0; i--) { + /* Place INT_PCM value left aligned in scaledTimeIn */ + *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; + timeIn += stride; + *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; + timeIn += stride; + } + } + + if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { + qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels, + anaQmf->p_filter, anaQmf->p_stride, + (FIXP_QAS *)anaQmf->FilterStates); + } else { + qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter, + anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates); + } + + if (anaQmf->flags & QMF_FLAG_LP) { + if (anaQmf->flags & QMF_FLAG_CLDFB) + qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal); + else + qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal); + + } else { + qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag); + } + /* + Shift filter states + + Should be realized with modulo addressing on a DSP instead of a true buffer + shift + */ + FDKmemmove(anaQmf->FilterStates, + (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels, + offset * sizeof(FIXP_QAS)); +} + +/*! + * + * \brief Perform complex-valued subband filtering of the time domain + * data of timeIn and stores the real part of the subband + * samples in rAnalysis, and the imaginary part in iAnalysis + * The qmf coefficient table is symmetric. The symmetry is expoited by + * shrinking the coefficient table to half the size. The addressing mode + * takes care of the symmetries. + * + * + * \sa PolyphaseFiltering + */ +void qmfAnalysisFiltering( + HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ + FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ + FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ + QMF_SCALE_FACTOR *scaleFactor, + const INT_PCM_QMFIN *timeIn, /*!< Time signal */ + const int timeIn_e, const int stride, + FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ +) { + int i; + int no_channels = anaQmf->no_channels; + + scaleFactor->lb_scale = + -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e; + scaleFactor->lb_scale -= anaQmf->filterScale; + + for (i = 0; i < anaQmf->no_col; i++) { + FIXP_DBL *qmfImagSlot = NULL; + + if (!(anaQmf->flags & QMF_FLAG_LP)) { + qmfImagSlot = qmfImag[i]; + } + + qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride, + pWorkBuffer); + + timeIn += no_channels * stride; + + } /* no_col loop i */ +} #endif /* QMF_PCM_H */ diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 3245deb..5e1d35f 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -128,13 +128,13 @@ C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE, /*! Analysis states buffer.
Dimension: #((8) + (1)) */ -C_ALLOC_MEM2(AnaQmfStates, FIXP_QAS, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS, - ((8) + (1))) +C_AALLOC_MEM2(AnaQmfStates, FIXP_DBL, 10 * QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS, + ((8) + (1))) /*! Synthesis states buffer.
Dimension: #((8) + (1)) */ -C_ALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS, - ((8) + (1))) +C_AALLOC_MEM2(SynQmfStates, FIXP_QSS, 9 * QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS, + ((8) + (1))) /*! Pointer to real qmf data for each time slot.
Dimension: #((8) + (1)) */ @@ -156,18 +156,17 @@ C_AALLOC_MEM2(QmfOverlapBuffer, FIXP_DBL, /*! Analysis states buffer.
Dimension: #((8) + (1)) */ -C_ALLOC_MEM2(AnaQmfStates16, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16, - ((8) + (1))) - +C_AALLOC_MEM2(AnaQmfStates16, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_16, + ((8) + (1))) /*! Analysis states buffer.
Dimension: #((8) + (1)) */ -C_ALLOC_MEM2(AnaQmfStates24, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24, - ((8) + (1))) +C_AALLOC_MEM2(AnaQmfStates24, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_24, + ((8) + (1))) /*! Analysis states buffer.
Dimension: #((8) + (1)) */ -C_ALLOC_MEM2(AnaQmfStates32, FIXP_QAS, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32, - ((8) + (1))) +C_AALLOC_MEM2(AnaQmfStates32, FIXP_DBL, 10 * QMF_DOMAIN_ANALYSIS_QMF_BANDS_32, + ((8) + (1))) /*! Pointer to real qmf data for each time slot.
Dimension: #((8) + (1)) */ diff --git a/libFDK/src/qmf.cpp b/libFDK/src/qmf.cpp index 19f1ea1..440bec2 100644 --- a/libFDK/src/qmf.cpp +++ b/libFDK/src/qmf.cpp @@ -147,88 +147,6 @@ amm-info@iis.fraunhofer.de /* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */ /* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */ -#ifndef FUNCTION_qmfAnaPrototypeFirSlot -/*! - \brief Perform Analysis Prototype Filtering on a single slot of input data. -*/ -static void qmfAnaPrototypeFirSlot( - FIXP_DBL *analysisBuffer, - INT no_channels, /*!< Number channels of analysis filter */ - const FIXP_PFT *p_filter, INT p_stride, /*!< Stride of analysis filter */ - FIXP_QAS *RESTRICT pFilterStates) { - INT k; - - FIXP_DBL accu; - const FIXP_PFT *RESTRICT p_flt = p_filter; - FIXP_DBL *RESTRICT pData_0 = analysisBuffer + 2 * no_channels - 1; - FIXP_DBL *RESTRICT pData_1 = analysisBuffer; - - FIXP_QAS *RESTRICT sta_0 = (FIXP_QAS *)pFilterStates; - FIXP_QAS *RESTRICT sta_1 = - (FIXP_QAS *)pFilterStates + (2 * QMF_NO_POLY * no_channels) - 1; - INT pfltStep = QMF_NO_POLY * (p_stride); - INT staStep1 = no_channels << 1; - INT staStep2 = (no_channels << 3) - 1; /* Rewind one less */ - - /* FIR filters 127..64 0..63 */ - for (k = 0; k < no_channels; k++) { - accu = fMultDiv2(p_flt[0], *sta_1); - sta_1 -= staStep1; - accu += fMultDiv2(p_flt[1], *sta_1); - sta_1 -= staStep1; - accu += fMultDiv2(p_flt[2], *sta_1); - sta_1 -= staStep1; - accu += fMultDiv2(p_flt[3], *sta_1); - sta_1 -= staStep1; - accu += fMultDiv2(p_flt[4], *sta_1); - *pData_1++ = (accu << 1); - sta_1 += staStep2; - - p_flt += pfltStep; - accu = fMultDiv2(p_flt[0], *sta_0); - sta_0 += staStep1; - accu += fMultDiv2(p_flt[1], *sta_0); - sta_0 += staStep1; - accu += fMultDiv2(p_flt[2], *sta_0); - sta_0 += staStep1; - accu += fMultDiv2(p_flt[3], *sta_0); - sta_0 += staStep1; - accu += fMultDiv2(p_flt[4], *sta_0); - *pData_0-- = (accu << 1); - sta_0 -= staStep2; - } -} -#endif /* !defined(FUNCTION_qmfAnaPrototypeFirSlot) */ - -#ifndef FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric -/*! - \brief Perform Analysis Prototype Filtering on a single slot of input data. -*/ -static void qmfAnaPrototypeFirSlot_NonSymmetric( - FIXP_DBL *analysisBuffer, - int no_channels, /*!< Number channels of analysis filter */ - const FIXP_PFT *p_filter, int p_stride, /*!< Stride of analysis filter */ - FIXP_QAS *RESTRICT pFilterStates) { - const FIXP_PFT *RESTRICT p_flt = p_filter; - int p, k; - - for (k = 0; k < 2 * no_channels; k++) { - FIXP_DBL accu = (FIXP_DBL)0; - - p_flt += QMF_NO_POLY * (p_stride - 1); - - /* - Perform FIR-Filter - */ - for (p = 0; p < QMF_NO_POLY; p++) { - accu += fMultDiv2(*p_flt++, pFilterStates[2 * no_channels * p]); - } - analysisBuffer[2 * no_channels - 1 - k] = (accu << 1); - pFilterStates++; - } -} -#endif /* FUNCTION_qmfAnaPrototypeFirSlot_NonSymmetric */ - /*! * * \brief Perform real-valued forward modulation of the time domain @@ -381,211 +299,6 @@ static void qmfForwardModulationHQ( } #endif /* FUNCTION_qmfForwardModulationHQ */ -/* - * \brief Perform one QMF slot analysis of the time domain data of timeIn - * with specified stride and stores the real part of the subband - * samples in rSubband, and the imaginary part in iSubband - * - * Note: anaQmf->lsb can be greater than anaQmf->no_channels in case - * of implicit resampling (USAC with reduced 3/4 core frame length). - */ -#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS) -void qmfAnalysisFilteringSlot( - HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ - FIXP_DBL *qmfReal, /*!< Low and High band, real */ - FIXP_DBL *qmfImag, /*!< Low and High band, imag */ - const LONG *RESTRICT timeIn, /*!< Pointer to input */ - const int stride, /*!< stride factor of input */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ -) { - int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1); - /* - Feed time signal into oldest anaQmf->no_channels states - */ - { - FIXP_DBL *FilterStatesAnaTmp = ((FIXP_DBL *)anaQmf->FilterStates) + offset; - - /* Feed and scale actual time in slot */ - for (int i = anaQmf->no_channels >> 1; i != 0; i--) { - /* Place INT_PCM value left aligned in scaledTimeIn */ - - *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; - timeIn += stride; - *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; - timeIn += stride; - } - } - - if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { - qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels, - anaQmf->p_filter, anaQmf->p_stride, - (FIXP_QAS *)anaQmf->FilterStates); - } else { - qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter, - anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates); - } - - if (anaQmf->flags & QMF_FLAG_LP) { - if (anaQmf->flags & QMF_FLAG_CLDFB) - qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal); - else - qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal); - - } else { - qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag); - } - /* - Shift filter states - - Should be realized with modulo adressing on a DSP instead of a true buffer - shift - */ - FDKmemmove(anaQmf->FilterStates, - (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels, - offset * sizeof(FIXP_QAS)); -} -#endif - -void qmfAnalysisFilteringSlot( - HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ - FIXP_DBL *qmfReal, /*!< Low and High band, real */ - FIXP_DBL *qmfImag, /*!< Low and High band, imag */ - const INT_PCM *RESTRICT timeIn, /*!< Pointer to input */ - const int stride, /*!< stride factor of input */ - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ -) { - int offset = anaQmf->no_channels * (QMF_NO_POLY * 2 - 1); - /* - Feed time signal into oldest anaQmf->no_channels states - */ - { - FIXP_QAS *FilterStatesAnaTmp = ((FIXP_QAS *)anaQmf->FilterStates) + offset; - - /* Feed and scale actual time in slot */ - for (int i = anaQmf->no_channels >> 1; i != 0; i--) { - /* Place INT_PCM value left aligned in scaledTimeIn */ -#if (QAS_BITS == SAMPLE_BITS) - *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; - timeIn += stride; - *FilterStatesAnaTmp++ = (FIXP_QAS)*timeIn; - timeIn += stride; -#elif (QAS_BITS > SAMPLE_BITS) - *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS); - timeIn += stride; - *FilterStatesAnaTmp++ = ((FIXP_QAS)*timeIn) << (QAS_BITS - SAMPLE_BITS); - timeIn += stride; -#else - *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS)); - timeIn += stride; - *FilterStatesAnaTmp++ = (FIXP_QAS)((*timeIn) >> (SAMPLE_BITS - QAS_BITS)); - timeIn += stride; -#endif - } - } - - if (anaQmf->flags & QMF_FLAG_NONSYMMETRIC) { - qmfAnaPrototypeFirSlot_NonSymmetric(pWorkBuffer, anaQmf->no_channels, - anaQmf->p_filter, anaQmf->p_stride, - (FIXP_QAS *)anaQmf->FilterStates); - } else { - qmfAnaPrototypeFirSlot(pWorkBuffer, anaQmf->no_channels, anaQmf->p_filter, - anaQmf->p_stride, (FIXP_QAS *)anaQmf->FilterStates); - } - - if (anaQmf->flags & QMF_FLAG_LP) { - if (anaQmf->flags & QMF_FLAG_CLDFB) - qmfForwardModulationLP_odd(anaQmf, pWorkBuffer, qmfReal); - else - qmfForwardModulationLP_even(anaQmf, pWorkBuffer, qmfReal); - - } else { - qmfForwardModulationHQ(anaQmf, pWorkBuffer, qmfReal, qmfImag); - } - /* - Shift filter states - - Should be realized with modulo adressing on a DSP instead of a true buffer - shift - */ - FDKmemmove(anaQmf->FilterStates, - (FIXP_QAS *)anaQmf->FilterStates + anaQmf->no_channels, - offset * sizeof(FIXP_QAS)); -} - -/*! - * - * \brief Perform complex-valued subband filtering of the time domain - * data of timeIn and stores the real part of the subband - * samples in rAnalysis, and the imaginary part in iAnalysis - * The qmf coefficient table is symmetric. The symmetry is expoited by - * shrinking the coefficient table to half the size. The addressing mode - * takes care of the symmetries. - * - * - * \sa PolyphaseFiltering - */ -#if (SAMPLE_BITS != DFRACT_BITS) && (QAS_BITS == DFRACT_BITS) -void qmfAnalysisFiltering( - HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ - FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ - FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ - QMF_SCALE_FACTOR *scaleFactor, const LONG *timeIn, /*!< Time signal */ - const int timeIn_e, const int stride, - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ -) { - int i; - int no_channels = anaQmf->no_channels; - - scaleFactor->lb_scale = - -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e; - scaleFactor->lb_scale -= anaQmf->filterScale; - - for (i = 0; i < anaQmf->no_col; i++) { - FIXP_DBL *qmfImagSlot = NULL; - - if (!(anaQmf->flags & QMF_FLAG_LP)) { - qmfImagSlot = qmfImag[i]; - } - - qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride, - pWorkBuffer); - - timeIn += no_channels * stride; - - } /* no_col loop i */ -} -#endif - -void qmfAnalysisFiltering( - HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ - FIXP_DBL **qmfReal, /*!< Pointer to real subband slots */ - FIXP_DBL **qmfImag, /*!< Pointer to imag subband slots */ - QMF_SCALE_FACTOR *scaleFactor, const INT_PCM *timeIn, /*!< Time signal */ - const int timeIn_e, const int stride, - FIXP_DBL *pWorkBuffer /*!< pointer to temporal working buffer */ -) { - int i; - int no_channels = anaQmf->no_channels; - - scaleFactor->lb_scale = - -ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK - timeIn_e; - scaleFactor->lb_scale -= anaQmf->filterScale; - - for (i = 0; i < anaQmf->no_col; i++) { - FIXP_DBL *qmfImagSlot = NULL; - - if (!(anaQmf->flags & QMF_FLAG_LP)) { - qmfImagSlot = qmfImag[i]; - } - - qmfAnalysisFilteringSlot(anaQmf, qmfReal[i], qmfImagSlot, timeIn, stride, - pWorkBuffer); - - timeIn += no_channels * stride; - - } /* no_col loop i */ -} - /*! * * \brief Perform low power inverse modulation of the subband @@ -997,35 +710,6 @@ static inline void qmfAdaptFilterStates( } } -/*! - * - * \brief Create QMF filter bank instance - * - * - * \return 0 if succesful - * - */ -int qmfInitAnalysisFilterBank( - HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */ - FIXP_QAS *pFilterStates, /*!< Handle to filter states */ - int noCols, /*!< Number of timeslots per frame */ - int lsb, /*!< lower end of QMF */ - int usb, /*!< upper end of QMF */ - int no_channels, /*!< Number of channels (bands) */ - int flags) /*!< Low Power flag */ -{ - int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb, - no_channels, flags, 0); - if (!(flags & QMF_FLAG_KEEP_STATES) && (h_Qmf->FilterStates != NULL)) { - FDKmemclear(h_Qmf->FilterStates, - (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QAS)); - } - - FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb); - - return err; -} - /*! * * \brief Create QMF filter bank instance @@ -1129,8 +813,21 @@ void qmfChangeOutGain( synQmf->outGain_e = outputGainScale; } -/* When QMF_16IN_32OUT is set, synthesis functions for 16 and 32 bit parallel - * output is compiled */ #define INT_PCM_QMFOUT INT_PCM #define SAMPLE_BITS_QMFOUT SAMPLE_BITS #include "qmf_pcm.h" +#if SAMPLE_BITS == 16 + /* also create a 32 bit output version */ +#undef INT_PCM_QMFOUT +#undef SAMPLE_BITS_QMFOUT +#undef QMF_PCM_H +#undef FIXP_QAS +#undef QAS_BITS +#undef INT_PCM_QMFIN +#define INT_PCM_QMFOUT LONG +#define SAMPLE_BITS_QMFOUT 32 +#define FIXP_QAS FIXP_DBL +#define QAS_BITS 32 +#define INT_PCM_QMFIN LONG +#include "qmf_pcm.h" +#endif -- cgit v1.2.3 From 90c29e0808d2221ae747bad7385036c20b5662b0 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:27:40 +0100 Subject: Revise memory overlay usage and remove deprecated buffers and overlay tags. Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I7aea2898a3c49e06209fae89d734939c100e1184 --- libAACdec/src/aac_ram.cpp | 10 +--------- libAACdec/src/aac_ram.h | 7 +------ libFDK/include/FDK_qmf_domain.h | 3 +-- libFDK/src/FDK_qmf_domain.cpp | 14 +++++--------- libSBRdec/src/sbr_ram.cpp | 5 +---- 5 files changed, 9 insertions(+), 30 deletions(-) diff --git a/libAACdec/src/aac_ram.cpp b/libAACdec/src/aac_ram.cpp index e13167d..aa8f6a6 100644 --- a/libAACdec/src/aac_ram.cpp +++ b/libAACdec/src/aac_ram.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -105,12 +105,7 @@ amm-info@iis.fraunhofer.de #define WORKBUFFER1_TAG 0 #define WORKBUFFER2_TAG 1 - -#define WORKBUFFER3_TAG 4 -#define WORKBUFFER4_TAG 5 - #define WORKBUFFER5_TAG 6 - #define WORKBUFFER6_TAG 7 /*! The structure AAC_DECODER_INSTANCE is the top level structure holding all @@ -169,9 +164,6 @@ C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8)) C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2, WORKBUFFER2_TAG) -C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2, - WORKBUFFER3_TAG) -C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE) C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR, fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE), (INT)sizeof(CAacDecoderCommonData)), diff --git a/libAACdec/src/aac_ram.h b/libAACdec/src/aac_ram.h index a861e25..b9b95b7 100644 --- a/libAACdec/src/aac_ram.h +++ b/libAACdec/src/aac_ram.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -136,12 +136,7 @@ H_ALLOC_MEM(TimeDataFlush, INT_PCM) H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1) H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL) - -H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL) -H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL) - H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC) - H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR) #endif /* #ifndef AAC_RAM_H */ diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h index d8bc8ce..aa247e9 100644 --- a/libFDK/include/FDK_qmf_domain.h +++ b/libFDK/include/FDK_qmf_domain.h @@ -123,11 +123,10 @@ typedef enum { #define QMF_WB_SECTION_SIZE (1024 * 2) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL) -H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL) -H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL) H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL) +H_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL) #define QMF_DOMAIN_MAX_ANALYSIS_QMF_BANDS (64) #define QMF_DOMAIN_MAX_SYNTHESIS_QMF_BANDS (QMF_MAX_SYNTHESIS_BANDS) diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 5e1d35f..71e2ef5 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -106,25 +106,21 @@ amm-info@iis.fraunhofer.de #include "common_fix.h" #define WORKBUFFER1_TAG 0 -#define WORKBUFFER2_TAG 1 - #define WORKBUFFER3_TAG 4 #define WORKBUFFER4_TAG 5 -#define WORKBUFFER5_TAG 6 #define WORKBUFFER6_TAG 7 +#define WORKBUFFER7_TAG 8 C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore1, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L1, WORKBUFFER1_TAG) -C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore2, FIXP_DBL, QMF_WB_SECTION_SIZE, - SECT_DATA_L2, WORKBUFFER2_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore3, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER3_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore4, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER4_TAG) -C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore5, FIXP_DBL, QMF_WB_SECTION_SIZE, - SECT_DATA_L2, WORKBUFFER5_TAG) C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore6, FIXP_DBL, QMF_WB_SECTION_SIZE, SECT_DATA_L2, WORKBUFFER6_TAG) +C_ALLOC_MEM_OVERLAY(QmfWorkBufferCore7, FIXP_DBL, QMF_WB_SECTION_SIZE, + SECT_DATA_L2, WORKBUFFER7_TAG) /*! Analysis states buffer.
Dimension: #((8) + (1)) */ @@ -949,7 +945,7 @@ QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) { if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) { /* get work buffer of size QMF_WB_SECTION_SIZE */ - pWorkBuffer[4] = GetQmfWorkBufferCore5(); + pWorkBuffer[4] = GetQmfWorkBufferCore7(); } /* 8. distribute workbuffer over processing channels */ @@ -995,7 +991,7 @@ static void FDK_QmfDomain_FreeWorkBuffer(HANDLE_FDK_QMF_DOMAIN hqd) { if (pWorkBuffer[1]) FreeQmfWorkBufferCore1(&pWorkBuffer[1]); if (pWorkBuffer[2]) FreeQmfWorkBufferCore3(&pWorkBuffer[2]); if (pWorkBuffer[3]) FreeQmfWorkBufferCore4(&pWorkBuffer[3]); - if (pWorkBuffer[4]) FreeQmfWorkBufferCore5(&pWorkBuffer[4]); + if (pWorkBuffer[4]) FreeQmfWorkBufferCore7(&pWorkBuffer[4]); } void FDK_QmfDomain_FreeMem(HANDLE_FDK_QMF_DOMAIN hqd) { diff --git a/libSBRdec/src/sbr_ram.cpp b/libSBRdec/src/sbr_ram.cpp index 8b35fd2..a759d71 100644 --- a/libSBRdec/src/sbr_ram.cpp +++ b/libSBRdec/src/sbr_ram.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,9 +109,6 @@ amm-info@iis.fraunhofer.de #include "sbr_ram.h" -#define WORKBUFFER1_TAG 2 -#define WORKBUFFER2_TAG 3 - /*! \name StaticSbrData -- cgit v1.2.3 From 57c9355de0269afb462ad4a8aa8814f6a6486ff1 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:27:53 +0100 Subject: Create new applyDrcLevelNormalization() function for subsequent usage. Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I23cc3081ff71830bc96766a31131594499dbdd04 --- libAACdec/src/aacdec_drc.cpp | 165 +++++++++++++++++++++++++++++++++++++++ libAACdec/src/aacdec_drc.h | 50 +++++++++++- libAACdec/src/aacdec_drc_types.h | 9 ++- 3 files changed, 222 insertions(+), 2 deletions(-) diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 4129d0f..6066a64 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -149,6 +149,20 @@ static INT convert_drcParam(FIXP_DBL param_dbl) { return (INT)param_long; } +/*! +\brief Reset DRC information + +\self Handle of DRC info + +\return none +*/ +void aacDecoder_drcReset(HANDLE_AAC_DRC self) { + self->applyExtGain = 0; + self->additionalGainPrev = AACDEC_DRC_GAIN_INIT_VALUE; + self->additionalGainFilterState = AACDEC_DRC_GAIN_INIT_VALUE; + self->additionalGainFilterState1 = AACDEC_DRC_GAIN_INIT_VALUE; +} + /*! \brief Initialize DRC information @@ -192,6 +206,8 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) { self->progRefLevelPresent = 0; self->presMode = -1; self->uniDrcPrecedence = 0; + + aacDecoder_drcReset(self); } /*! @@ -1353,3 +1369,152 @@ void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode, } } } + +/** + * \brief Apply DRC Level Normalization. + * + * This function prepares/applies the gain values for the DRC Level + * Normalization and returns the exponent of the time data. The following two + * cases are handled: + * + * - Limiter enabled: + * The input data must be interleaved. + * One gain per sample is written to the buffer pGainPerSample. + * If necessary the time data is rescaled. + * + * - Limiter disabled: + * The input data can be interleaved or deinterleaved. + * The gain values are applied to the time data. + * If necessary the time data is rescaled. + * + * \param hDrcInfo [i/o] handle to drc data structure. + * \param samplesIn [i/o] pointer to time data. + * \param pGain [i ] pointer to gain to be applied to + * the time data. + * \param pGainPerSample [o ] pointer to the gain per sample to + * be applied to the time data in the limiter. + * \param gain_scale [i ] exponent to be applied to the time + * data. + * \param gain_delay [i ] delay[samples] with which the gains + * in pGain shall be applied (gain_delay <= nSamples). + * \param nSamples [i ] number of samples per frame. + * \param channels [i ] number of channels. + * \param stride [i ] channel stride of time data. + * \param limiterEnabled [i ] 1 if limiter is enabled, otherwise + * 0. + * + * \return exponent of time data + */ +INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn, + FIXP_DBL *pGain, FIXP_DBL *pGainPerSample, + const INT gain_scale, const UINT gain_delay, + const UINT nSamples, const UINT channels, + const UINT stride, const UINT limiterEnabled) { + UINT i; + INT additionalGain_scaling; + FIXP_DBL additionalGain; + + FDK_ASSERT(gain_delay <= nSamples); + + FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState; + FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1; + + if (!gain_delay) { + additionalGain = pGain[0]; + + /* Apply the additional scaling gain_scale[0] that has no delay and no + * smoothing */ + additionalGain_scaling = + fMin(gain_scale, CntLeadingZeros(additionalGain) - 1); + additionalGain = scaleValue(additionalGain, additionalGain_scaling); + + /* if it's not possible to fully apply gain_scale to additionalGain, apply + * it to the input signal */ + additionalGain_scaling -= gain_scale; + + if (additionalGain_scaling) { + scaleValuesSaturate(samplesIn, channels * nSamples, + -additionalGain_scaling); + } + + if (limiterEnabled) { + FDK_ASSERT(pGainPerSample != NULL); + + for (i = 0; i < nSamples; i++) { + pGainPerSample[i] = additionalGain; + } + } else { + for (i = 0; i < channels * nSamples; i++) { + samplesIn[i] = FIXP_DBL2PCM_DEC(fMult(samplesIn[i], additionalGain)); + } + } + } else { + UINT inc; + FIXP_DBL additionalGainUnfiltered; + + inc = (stride == 1) ? channels : 1; + + for (i = 0; i < nSamples; i++) { + if (i < gain_delay) { + additionalGainUnfiltered = hDrcInfo->additionalGainPrev; + } else { + additionalGainUnfiltered = pGain[0]; + } + + /* Smooth additionalGain */ + + /* [b,a] = butter(1, 0.01) */ + static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0), + FL2FXCONST_SGL(0.015466 * 2.0)}; + static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL, + FL2FXCONST_SGL(-0.96907)}; + + additionalGain = -fMult(additionalGainSmoothState, a[1]) + + fMultDiv2(additionalGainUnfiltered, b[0]) + + fMultDiv2(additionalGainSmoothState1, b[1]); + additionalGainSmoothState1 = additionalGainUnfiltered; + additionalGainSmoothState = additionalGain; + + /* Apply the additional scaling gain_scale[0] that has no delay and no + * smoothing */ + additionalGain_scaling = + fMin(gain_scale, CntLeadingZeros(additionalGain) - 1); + additionalGain = scaleValue(additionalGain, additionalGain_scaling); + + /* if it's not possible to fully apply gain_scale[0] to additionalGain, + * apply it to the input signal */ + additionalGain_scaling -= gain_scale; + + if (limiterEnabled) { + FDK_ASSERT(stride == 1); + FDK_ASSERT(pGainPerSample != NULL); + + if (additionalGain_scaling) { + scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling); + } + + pGainPerSample[i] = additionalGain; + } else { + if (additionalGain_scaling) { + for (UINT k = 0; k < channels; k++) { + scaleValuesSaturate(&samplesIn[k * stride], 1, + -additionalGain_scaling); + } + } + + for (UINT k = 0; k < channels; k++) { + samplesIn[k * stride] = + FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain)); + } + } + + samplesIn += inc; + } + } + + hDrcInfo->additionalGainPrev = pGain[0]; + hDrcInfo->additionalGainFilterState = additionalGainSmoothState; + hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1; + + return (AACDEC_DRC_GAIN_SCALING); +} diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 924ec6f..1873c5b 100644 --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,6 +109,11 @@ amm-info@iis.fraunhofer.de #include "channel.h" #include "FDK_bitstream.h" +#define AACDEC_DRC_GAIN_SCALING (11) /* Scaling of DRC gains */ +#define AACDEC_DRC_GAIN_INIT_VALUE \ + (FL2FXCONST_DBL( \ + 1.0f / (1 << AACDEC_DRC_GAIN_SCALING))) /* Init value for DRC gains */ + #define AACDEC_DRC_DFLT_EXPIRY_FRAMES \ (0) /* Default DRC data expiry time in AAC frames */ @@ -136,6 +141,8 @@ typedef enum { /** * \brief DRC module interface functions */ +void aacDecoder_drcReset(HANDLE_AAC_DRC self); + void aacDecoder_drcInit(HANDLE_AAC_DRC self); void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel); @@ -189,4 +196,45 @@ int aacDecoder_drcEpilog( void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode, SCHAR *pProgRefLevel); +/** + * \brief Apply DRC Level Normalization. + * + * This function prepares/applies the gain values for the DRC Level + * Normalization and returns the exponent of the time data. The following two + * cases are handled: + * + * - Limiter enabled: + * The input data must be interleaved. + * One gain per sample is written to the buffer pGainPerSample. + * If necessary the time data is rescaled. + * + * - Limiter disabled: + * The input data can be interleaved or deinterleaved. + * The gain values are applied to the time data. + * If necessary the time data is rescaled. + * + * \param hDrcInfo [i/o] handle to drc data structure. + * \param samplesIn [i/o] pointer to time data. + * \param pGain [i ] pointer to gain to be applied to + * the time data. + * \param pGainPerSample [o ] pointer to the gain per sample to + * be applied to the time data in the limiter. + * \param gain_scale [i ] exponent to be applied to the time + * data. + * \param gain_delay [i ] delay[samples] with which the gains + * in pGain shall be applied (gain_delay <= nSamples). + * \param nSamples [i ] number of samples per frame. + * \param channels [i ] number of channels. + * \param stride [i ] channel stride of time data. + * \param limiterEnabled [i ] 1 if limiter is enabled, otherwise + * 0. + * + * \return exponent of time data + */ +INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn, + FIXP_DBL *pGain, FIXP_DBL *pGainPerSample, + const INT gain_scale, const UINT gain_delay, + const UINT nSamples, const UINT channels, + const UINT stride, const UINT limiterEnabled); + #endif /* AACDEC_DRC_H */ diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index 76c35d0..873bd60 100644 --- a/libAACdec/src/aacdec_drc_types.h +++ b/libAACdec/src/aacdec_drc_types.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -213,6 +213,13 @@ typedef struct { uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes precedence over legacy DRC */ + UCHAR applyExtGain; /* Flag is 1 if extGain has to be applied, otherwise 0. */ + + FIXP_DBL additionalGainPrev; /* Gain of previous frame to be applied to the + time data */ + FIXP_DBL additionalGainFilterState; /* Filter state for the gain smoothing */ + FIXP_DBL additionalGainFilterState1; /* Filter state for the gain smoothing */ + } CDrcInfo; typedef CDrcInfo *HANDLE_AAC_DRC; -- cgit v1.2.3 From e016635f0d3a5c7532b00711ce461f97a13f7bc2 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:28:15 +0100 Subject: Avoid decoder internal clipping by converting the whole audio sample data path from 16 to 32 bit data width (FDKdec v3.2.0). Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I8a504ab709e42e27a61fe29840212953742283a5 --- documentation/aacDecoder.pdf | Bin 490978 -> 490978 bytes libAACdec/src/FDK_delay.cpp | 26 ++--- libAACdec/src/FDK_delay.h | 6 +- libAACdec/src/aac_rom.h | 3 +- libAACdec/src/aacdecoder.cpp | 49 ++++---- libAACdec/src/aacdecoder.h | 11 +- libAACdec/src/aacdecoder_lib.cpp | 232 +++++++++++++++++++++---------------- libAACdec/src/block.cpp | 12 +- libAACdec/src/block.h | 8 +- libAACdec/src/conceal.cpp | 42 ++++--- libAACdec/src/conceal.h | 4 +- libAACdec/src/conceal_types.h | 4 +- libAACdec/src/ldfiltbank.cpp | 35 +++--- libAACdec/src/ldfiltbank.h | 5 +- libAACdec/src/usacdec_lpd.cpp | 34 +++--- libAACdec/src/usacdec_lpd.h | 19 +-- libFDK/include/FDK_qmf_domain.h | 5 - libFDK/include/mdct.h | 14 +-- libFDK/src/FDK_core.cpp | 4 +- libFDK/src/FDK_qmf_domain.cpp | 12 +- libPCMutils/include/limiter.h | 36 ++---- libPCMutils/src/limiter.cpp | 116 ++++++++----------- libPCMutils/src/version.h | 4 +- libSACdec/include/sac_dec_lib.h | 13 ++- libSACdec/src/sac_dec.cpp | 23 ++-- libSACdec/src/sac_dec.h | 5 +- libSACdec/src/sac_dec_interface.h | 8 +- libSACdec/src/sac_dec_lib.cpp | 24 ++-- libSACdec/src/sac_process.cpp | 30 +++-- libSACdec/src/sac_qmf.cpp | 4 +- libSACdec/src/sac_qmf.h | 4 +- libSACdec/src/sac_reshapeBBEnv.cpp | 18 +-- libSACdec/src/sac_rom.h | 15 --- libSBRdec/include/sbrdecoder.h | 15 ++- libSBRdec/src/HFgen_preFlat.cpp | 4 +- libSBRdec/src/hbe.cpp | 2 +- libSBRdec/src/hbe.h | 10 +- libSBRdec/src/sbr_dec.cpp | 26 +++-- libSBRdec/src/sbr_dec.h | 11 +- libSBRdec/src/sbr_ram.h | 5 +- libSBRdec/src/sbrdecoder.cpp | 32 ++--- 41 files changed, 488 insertions(+), 442 deletions(-) diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index d04a7d6..cc7cf41 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/src/FDK_delay.cpp b/libAACdec/src/FDK_delay.cpp index 0ab1a66..0cc869c 100644 --- a/libAACdec/src/FDK_delay.cpp +++ b/libAACdec/src/FDK_delay.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -113,7 +113,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, if (delay > 0) { data->delay_line = - (INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM)); + (PCM_DEC*)FDKcalloc(num_channels * delay, sizeof(PCM_DEC)); if (data->delay_line == NULL) { return -1; } @@ -126,36 +126,36 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, return 0; } -void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer, +void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer, const UINT frame_length, const UCHAR channel) { FDK_ASSERT(data != NULL); if (data->delay > 0) { - C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH) + C_ALLOC_SCRATCH_START(tmp, PCM_DEC, MAX_FRAME_LENGTH) FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH); FDK_ASSERT(channel < data->num_channels); FDK_ASSERT(time_buffer != NULL); if (frame_length >= data->delay) { FDKmemcpy(tmp, &time_buffer[frame_length - data->delay], - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); FDKmemmove(&time_buffer[data->delay], &time_buffer[0], - (frame_length - data->delay) * sizeof(FIXP_PCM)); + (frame_length - data->delay) * sizeof(PCM_DEC)); FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay], - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay], tmp, - data->delay * sizeof(FIXP_PCM)); + data->delay * sizeof(PCM_DEC)); } else { - FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM)); + FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(PCM_DEC)); FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay], - frame_length * sizeof(FIXP_PCM)); + frame_length * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay], &data->delay_line[channel * data->delay + frame_length], - (data->delay - frame_length) * sizeof(FIXP_PCM)); + (data->delay - frame_length) * sizeof(PCM_DEC)); FDKmemcpy(&data->delay_line[channel * data->delay + (data->delay - frame_length)], - tmp, frame_length * sizeof(FIXP_PCM)); + tmp, frame_length * sizeof(PCM_DEC)); } - C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH) + C_ALLOC_SCRATCH_END(tmp, PCM_DEC, MAX_FRAME_LENGTH) } return; diff --git a/libAACdec/src/FDK_delay.h b/libAACdec/src/FDK_delay.h index f89c3a2..6317d9d 100644 --- a/libAACdec/src/FDK_delay.h +++ b/libAACdec/src/FDK_delay.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,7 +109,7 @@ amm-info@iis.fraunhofer.de * Structure representing one delay element for multiple channels. */ typedef struct { - INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */ + PCM_DEC* delay_line; /*!< Pointer which stores allocated delay line. */ USHORT delay; /*!< Delay required in samples (per channel). */ UCHAR num_channels; /*!< Number of channels to delay. */ } FDK_SignalDelay; @@ -137,7 +137,7 @@ INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay, * * \return void */ -void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer, +void FDK_Delay_Apply(FDK_SignalDelay* data, PCM_DEC* time_buffer, const UINT frame_length, const UCHAR channel); /** diff --git a/libAACdec/src/aac_rom.h b/libAACdec/src/aac_rom.h index ffaf951..7a1597c 100644 --- a/libAACdec/src/aac_rom.h +++ b/libAACdec/src/aac_rom.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -108,6 +108,7 @@ amm-info@iis.fraunhofer.de #include "aacdec_hcr_types.h" #include "aacdec_hcrs.h" +#define PCM_AAC LONG #define PCM_DEC FIXP_DBL #define MAXVAL_PCM_DEC MAXVAL_DBL #define MINVAL_PCM_DEC MINVAL_DBL diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index f747b2d..6a0254d 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1281,6 +1281,7 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open( /* Set default frame delay */ aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, CConcealment_GetDelay(&self->concealCommonData)); + self->workBufferCore1 = (FIXP_DBL *)GetWorkBufferCore1(); self->workBufferCore2 = GetWorkBufferCore2(); if (self->workBufferCore2 == NULL) goto bail; @@ -1456,6 +1457,10 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) { FreeDrcInfo(&self->hDrcInfo); } + if (self->workBufferCore1 != NULL) { + FreeWorkBufferCore1((CWorkBufferCore1 **)&self->workBufferCore1); + } + /* Free WorkBufferCore2 */ if (self->workBufferCore2 != NULL) { FreeWorkBufferCore2(&self->workBufferCore2); @@ -1493,6 +1498,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, UCHAR downscaleFactor = self->downscaleFactor; UCHAR downscaleFactorInBS = self->downscaleFactorInBS; + self->aacOutDataHeadroom = (3); + // set profile and check for supported aot // leave profile on default (=-1) for all other supported MPEG-4 aot's except // aot=2 (=AAC-LC) @@ -2394,7 +2401,7 @@ bail: } LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData, + HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData, const INT timeDataSize, const int timeDataChannelOffset) { AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK; @@ -3170,10 +3177,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR)); } - /* Turn on/off DRC modules level normalization in digital domain depending - * on the limiter status. */ - aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, - (self->limiterEnableCurr) ? 0 : 1); + /* Turn off DRC modules level normalization in digital domain. */ + aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, 0); /* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is * present and one of DRC or Loudness Normalization is switched on */ @@ -3325,9 +3330,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( &pAacDecoderStaticChannelInfo->drcData); } } + /* The DRC module demands to be called with the gain field holding the * gain scale. */ - self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING; + self->extGain[0] = (FIXP_DBL)AACDEC_DRC_GAIN_SCALING; + /* DRC processing */ aacDecoder_drcApply( self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo, @@ -3343,7 +3350,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( if (self->flushStatus && (self->flushCnt > 0) && !(flags & AACDEC_CONCEAL)) { FDKmemclear(pTimeData + offset, - sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame); + sizeof(PCM_DEC) * self->streamInfo.aacSamplesPerFrame); } else switch (pAacDecoderChannelInfo->renderMode) { case AACDEC_RENDER_IMDCT: @@ -3355,7 +3362,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( !frameOk_butConceal), pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1 ->mdctOutTemp, - self->elFlags[el], elCh); + self->aacOutDataHeadroom, self->elFlags[el], elCh); self->extGainDelay = self->streamInfo.aacSamplesPerFrame; break; @@ -3376,7 +3383,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( &self->samplingRateInfo[streamIndex], (self->frameOK && !(flags & AACDEC_CONCEAL) && !frameOk_butConceal), - flags, self->flags[streamIndex]); + self->aacOutDataHeadroom, flags, self->flags[streamIndex]); self->extGainDelay = self->streamInfo.aacSamplesPerFrame; break; @@ -3388,7 +3395,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( if (!CConceal_TDFading_Applied[c]) { CConceal_TDFading_Applied[c] = CConcealment_TDFading( self->streamInfo.aacSamplesPerFrame, - &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0); + &self->pAacDecoderStaticChannelInfo[c], self->aacOutDataHeadroom, + pTimeData + offset, 0); if (c + 1 < (8) && c < aacChannels - 1) { /* update next TDNoise Seed to avoid muting in case of Parametric * Stereo */ @@ -3409,27 +3417,18 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( * LR) */ if ((aacChannels == 2) && bsPseudoLr) { int i, offset2; - const FIXP_SGL invSqrt2 = - FL2FXCONST_SGL(0.353553390593273f); /* scaled by -1 */ - FIXP_PCM *pTD = pTimeData; + const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f); + PCM_DEC *pTD = pTimeData; offset2 = timeDataChannelOffset; for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) { - FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]); - FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]); + FIXP_DBL L = PCM_DEC2FIXP_DBL(pTD[0]); + FIXP_DBL R = PCM_DEC2FIXP_DBL(pTD[offset2]); L = fMult(L, invSqrt2); R = fMult(R, invSqrt2); -#if (SAMPLE_BITS == 16) - pTD[0] = (FIXP_SGL)SATURATE_RIGHT_SHIFT(L + R + (FIXP_DBL)(1 << 14), - 15, FRACT_BITS); - pTD[offset2] = (FIXP_SGL)SATURATE_RIGHT_SHIFT( - L - R + (FIXP_DBL)(1 << 14), 15, FRACT_BITS); -#else - pTD[0] = SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L + R), 1, DFRACT_BITS); - pTD[offset2] = - SATURATE_LEFT_SHIFT(FX_DBL2FX_PCM(L - R), 1, DFRACT_BITS); -#endif + pTD[0] = L + R; + pTD[offset2] = L - R; pTD++; } } diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index 20f4c45..bd1f38f 100644 --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -191,6 +191,9 @@ struct AAC_DECODER_INSTANCE { INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved). */ + INT aacOutDataHeadroom; /*!< Headroom of the output time signal to prevent + clipping */ + HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */ SamplingRateInfo @@ -235,6 +238,7 @@ struct AAC_DECODER_INSTANCE { CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */ + FIXP_DBL *workBufferCore1; FIXP_DBL *workBufferCore2; PCM_DEC *pTimeData2; INT timeData2Size; @@ -311,11 +315,10 @@ This structure is allocated once for each CPE. */ UCHAR limiterEnableUser; /*!< The limiter configuration requested by the library user */ UCHAR limiterEnableCurr; /*!< The current limiter configuration. */ + FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */ - INT_PCM pcmOutputBuffer[(8) * (1024 * 2)]; - HANDLE_DRC_DECODER hUniDrcDecoder; UCHAR multibandDrcPresent; UCHAR numTimeSlots; @@ -427,7 +430,7 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, \return error status */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData, + HANDLE_AACDECODER self, const UINT flags, PCM_DEC *pTimeData, const INT timeDataSize, const int timeDataChannelOffset); /* Free config dependent AAC memory */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 2ba0e86..f5ce7e0 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -119,8 +119,8 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 3 -#define AACDECODER_LIB_VL1 1 -#define AACDECODER_LIB_VL2 3 +#define AACDECODER_LIB_VL1 2 +#define AACDECODER_LIB_VL2 0 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" @@ -1131,35 +1131,31 @@ static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) { return n; } -LINKSPEC_CPP AAC_DECODER_ERROR -aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, - const INT timeDataSize_extern, const UINT flags) { +LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, + INT_PCM *pTimeData, + const INT timeDataSize, + const UINT flags) { AAC_DECODER_ERROR ErrorStatus; INT layer; INT nBits; + INT timeData2Size; + INT timeData3Size; + INT timeDataHeadroom; HANDLE_FDK_BITSTREAM hBs; int fTpInterruption = 0; /* Transport originated interruption detection. */ int fTpConceal = 0; /* Transport originated concealment. */ - INT_PCM *pTimeData = NULL; - INT timeDataSize = 0; UINT accessUnit = 0; UINT numAccessUnits = 1; UINT numPrerollAU = 0; - int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */ - int applyCrossfade = 1; /* flag indicates if flushing was possible */ - FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM - processing */ - INT timeDataFixpPcmSize; - PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */ - INT timeDataPcmPostSize; + int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */ + int applyCrossfade = 1; /* flag indicates if flushing was possible */ + PCM_DEC *pTimeData2; + PCM_AAC *pTimeData3; if (self == NULL) { return AAC_DEC_INVALID_HANDLE; } - pTimeData = self->pcmOutputBuffer; - timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer); - if (flags & AACDEC_INTR) { self->streamInfo.numLostAccessUnits = 0; } @@ -1315,19 +1311,23 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, /* Use limiter configuration as requested. */ self->limiterEnableCurr = self->limiterEnableUser; } - /* reset limiter gain on a per frame basis */ - self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING)); - pTimeDataFixpPcm = pTimeData; - timeDataFixpPcmSize = timeDataSize; + /* reset DRC level normalization gain on a per frame basis */ + self->extGain[0] = AACDEC_DRC_GAIN_INIT_VALUE; + + pTimeData2 = self->pTimeData2; + timeData2Size = self->timeData2Size / sizeof(PCM_DEC); + pTimeData3 = (PCM_AAC *)self->pTimeData2; + timeData3Size = self->timeData2Size / sizeof(PCM_AAC); ErrorStatus = CAacDecoder_DecodeFrame( self, flags | (fTpConceal ? AACDEC_CONCEAL : 0) | ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH : 0), - pTimeDataFixpPcm + 0, timeDataFixpPcmSize, - self->streamInfo.aacSamplesPerFrame + 0); + pTimeData2 + 0, timeData2Size, self->streamInfo.aacSamplesPerFrame + 0); + + timeDataHeadroom = self->aacOutDataHeadroom; /* if flushing for USAC DASH IPF was not possible go on with decoding * preroll */ @@ -1352,7 +1352,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - /* If the current pTimeDataFixpPcm does not contain a valid signal, there + /* If the current pTimeData2 does not contain a valid signal, there * nothing else we can do, so bail. */ if (!IS_OUTPUT_VALID(ErrorStatus)) { goto bail; @@ -1366,10 +1366,10 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, self->streamInfo.numChannels = self->streamInfo.aacNumChannels; { - FDK_Delay_Apply(&self->usacResidualDelay, - pTimeDataFixpPcm + - 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, - self->streamInfo.frameSize, 0); + FDK_Delay_Apply( + &self->usacResidualDelay, + pTimeData2 + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, + self->streamInfo.frameSize, 0); } /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode @@ -1416,8 +1416,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - self->qmfDomain.globalConf.TDinput = pTimeData; - switch (FDK_QmfDomain_Configure(&self->qmfDomain)) { default: case QMF_DOMAIN_INIT_ERROR: @@ -1474,18 +1472,18 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, (self->mpsEnableCurr) ? 2 : 0); - INT_PCM *input; - input = (INT_PCM *)self->workBufferCore2; - FDKmemcpy(input, pTimeData, - sizeof(INT_PCM) * (self->streamInfo.numChannels) * + PCM_AAC *input; + input = (PCM_AAC *)self->workBufferCore2; + FDKmemcpy(input, pTimeData3, + sizeof(PCM_AAC) * (self->streamInfo.numChannels) * (self->streamInfo.frameSize)); /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); + sbrError = sbrDecoder_Apply( + self->hSbrDecoder, input, pTimeData3, timeData3Size, + &self->streamInfo.numChannels, &self->streamInfo.sampleRate, + &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, + self->aacOutDataHeadroom, &timeDataHeadroom); if (sbrError == SBRDEC_OK) { /* Update data in streaminfo structure. Assume that the SBR upsampling @@ -1564,10 +1562,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (err == 0) { err = mpegSurroundDecoder_Apply( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, - (INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize, + (PCM_AAC *)self->workBufferCore2, pTimeData3, timeData3Size, self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize, self->streamInfo.sampleRate, self->streamInfo.aot, - self->channelType, self->channelIndices, &self->mapDescr); + self->channelType, self->channelIndices, &self->mapDescr, + self->aacOutDataHeadroom, &timeDataHeadroom); } if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) { @@ -1590,8 +1589,8 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, self->streamInfo.frameSize = self->mpsFrameSizeLast; /* ... and clear output buffer so that potentially corrupted data does * not reach the framework. */ - FDKmemclear(pTimeData, self->mpsOutChannelsLast * - self->mpsFrameSizeLast * sizeof(INT_PCM)); + FDKmemclear(pTimeData3, self->mpsOutChannelsLast * + self->mpsFrameSizeLast * sizeof(PCM_AAC)); /* Additionally proclaim that this frame had errors during decoding. */ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; @@ -1612,11 +1611,11 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); + sbrError = sbrDecoder_Apply( + self->hSbrDecoder, pTimeData3, pTimeData3, timeData3Size, + &self->streamInfo.numChannels, &self->streamInfo.sampleRate, + &self->mapDescr, self->chMapIndex, self->frameOK, &self->psPossible, + self->aacOutDataHeadroom, &timeDataHeadroom); if (sbrError == SBRDEC_OK) { /* Update data in streaminfo structure. Assume that the SBR upsampling @@ -1644,17 +1643,15 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - /* Use dedicated memory for PCM postprocessing */ - pTimeDataPcmPost = self->pTimeData2; - timeDataPcmPostSize = self->timeData2Size; - { - const int size = - self->streamInfo.frameSize * self->streamInfo.numChannels; - FDK_ASSERT(timeDataPcmPostSize >= size); - for (int i = 0; i < size; i++) { - pTimeDataPcmPost[i] = - (PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM; + if ((INT)PCM_OUT_HEADROOM != timeDataHeadroom) { + for (int i = ((self->streamInfo.frameSize * + self->streamInfo.numChannels) - + 1); + i >= 0; i--) { + pTimeData2[i] = + (PCM_DEC)pTimeData3[i] >> (PCM_OUT_HEADROOM - timeDataHeadroom); + } } } @@ -1709,22 +1706,21 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if ((self->streamInfo.numChannels > 1) && (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) { /* interleaving/deinterleaving is performed on upper part of - * pTimeDataPcmPost. Check if this buffer is large enough. */ - if (timeDataPcmPostSize < - (INT)(2 * self->streamInfo.numChannels * - self->streamInfo.frameSize * sizeof(PCM_DEC))) { + * pTimeData2. Check if this buffer is large enough. */ + if (timeData2Size < (INT)(2 * self->streamInfo.numChannels * + self->streamInfo.frameSize)) { ErrorStatus = AAC_DEC_UNKNOWN; goto bail; } needsDeinterleaving = 1; drcWorkBuffer = - (FIXP_DBL *)pTimeDataPcmPost + + (FIXP_DBL *)pTimeData2 + self->streamInfo.numChannels * self->streamInfo.frameSize; FDK_deinterleave( - pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels, + pTimeData2, drcWorkBuffer, self->streamInfo.numChannels, self->streamInfo.frameSize, self->streamInfo.frameSize); } else { - drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost; + drcWorkBuffer = pTimeData2; } /* prepare Loudness Normalisation gain */ @@ -1759,7 +1755,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (needsDeinterleaving) { FDK_interleave( - drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels, + drcWorkBuffer, pTimeData2, self->streamInfo.numChannels, self->streamInfo.frameSize, self->streamInfo.frameSize); } } @@ -1799,6 +1795,9 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, if (self->streamInfo.extAot != AOT_AAC_SLS) { INT pcmLimiterScale = 0; + INT interleaved = 0; + interleaved |= (self->sbrEnabled) ? 1 : 0; + interleaved |= (self->mpsEnableCurr) ? 1 : 0; PCMDMX_ERROR dmxErr = PCMDMX_OK; if ((flags & AACDEC_INTR) && (accessUnit == 0)) { /* delete data from the past (e.g. mixdown coeficients) */ @@ -1811,17 +1810,12 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } - INT interleaved = 0; - interleaved |= (self->sbrEnabled) ? 1 : 0; - interleaved |= (self->mpsEnableCurr) ? 1 : 0; - /* do PCM post processing */ - dmxErr = pcmDmx_ApplyFrame( - self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize, - self->streamInfo.frameSize, &self->streamInfo.numChannels, - interleaved, self->channelType, self->channelIndices, - &self->mapDescr, - (self->limiterEnableCurr) ? &pcmLimiterScale : NULL); + dmxErr = pcmDmx_ApplyFrame(self->hPcmUtils, pTimeData2, timeData2Size, + self->streamInfo.frameSize, + &self->streamInfo.numChannels, interleaved, + self->channelType, self->channelIndices, + &self->mapDescr, &pcmLimiterScale); if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) { ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; goto bail; @@ -1833,13 +1827,35 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; } + pcmLimiterScale += PCM_OUT_HEADROOM; + if (flags & AACDEC_CLRHIST) { if (!(self->flags[0] & AC_USAC)) { + /* Reset DRC data */ + aacDecoder_drcReset(self->hDrcInfo); /* Delete the delayed signal. */ pcmLimiter_Reset(self->hLimiter); } } + /* Set applyExtGain if DRC processing is enabled and if + progRefLevelPresent is present for the first time. Consequences: The + headroom of the output signal can be set to AACDEC_DRC_GAIN_SCALING + only for audio formats which support legacy DRC Level Normalization. + For all other audio formats the headroom of the output + signal is set to PCM_OUT_HEADROOM. */ + if (self->hDrcInfo->enable && + (self->hDrcInfo->progRefLevelPresent == 1)) { + self->hDrcInfo->applyExtGain |= 1; + } + + /* Check whether time data buffer is large enough. */ + if (timeDataSize < + (self->streamInfo.numChannels * self->streamInfo.frameSize)) { + ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; + goto bail; + } + if (self->limiterEnableCurr) { /* use workBufferCore2 buffer for interleaving */ PCM_LIM *pInterleaveBuffer; @@ -1848,44 +1864,72 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, /* Set actual signal parameters */ pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels); pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); - pcmLimiterScale += PCM_OUT_HEADROOM; if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || (self->mpsEnableCurr)) { - pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost; + pInterleaveBuffer = (PCM_LIM *)pTimeData2; } else { - pInterleaveBuffer = (PCM_LIM *)pTimeData; + pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2; + /* applyLimiter requests for interleaved data */ /* Interleave ouput buffer */ - FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer, + FDK_interleave(pTimeData2, pInterleaveBuffer, self->streamInfo.numChannels, blockLength, self->streamInfo.frameSize); } + FIXP_DBL *pGainPerSample = NULL; + + if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { + pGainPerSample = self->workBufferCore1; + + if ((INT)GetRequiredMemWorkBufferCore1() < + (INT)(self->streamInfo.frameSize * sizeof(FIXP_DBL))) { + ErrorStatus = AAC_DEC_UNKNOWN; + goto bail; + } + + pcmLimiterScale = applyDrcLevelNormalization( + self->hDrcInfo, (PCM_DEC *)pInterleaveBuffer, self->extGain, + pGainPerSample, pcmLimiterScale, self->extGainDelay, + self->streamInfo.frameSize, self->streamInfo.numChannels, 1, 1); + } + pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData, - self->extGain, &pcmLimiterScale, 1, - self->extGainDelay, self->streamInfo.frameSize); + pGainPerSample, pcmLimiterScale, + self->streamInfo.frameSize); { /* Announce the additional limiter output delay */ self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter); } } else { + if (self->hDrcInfo->enable && self->hDrcInfo->applyExtGain) { + pcmLimiterScale = applyDrcLevelNormalization( + self->hDrcInfo, pTimeData2, self->extGain, NULL, + pcmLimiterScale, self->extGainDelay, self->streamInfo.frameSize, + self->streamInfo.numChannels, + (interleaved || (self->streamInfo.numChannels == 1)) + ? 1 + : self->streamInfo.frameSize, + 0); + } + /* If numChannels = 1 we do not need interleaving. The same applies if SBR or MPS are used, since their output is interleaved already (resampled or not) */ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || (self->mpsEnableCurr)) { scaleValuesSaturate( - pTimeData, pTimeDataPcmPost, + pTimeData, pTimeData2, self->streamInfo.frameSize * self->streamInfo.numChannels, - PCM_OUT_HEADROOM); + pcmLimiterScale); } else { scaleValuesSaturate( - (INT_PCM *)self->workBufferCore2, pTimeDataPcmPost, + (INT_PCM *)self->workBufferCore2, pTimeData2, self->streamInfo.frameSize * self->streamInfo.numChannels, - PCM_OUT_HEADROOM); + pcmLimiterScale); /* Interleave ouput buffer */ FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, self->streamInfo.numChannels, @@ -1981,20 +2025,8 @@ bail: ErrorStatus = AAC_DEC_UNKNOWN; } - /* Check whether external output buffer is large enough. */ - if (timeDataSize_extern < - self->streamInfo.numChannels * self->streamInfo.frameSize) { - ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; - } - - /* Update external output buffer. */ - if (IS_OUTPUT_VALID(ErrorStatus)) { - FDKmemcpy(pTimeData_extern, pTimeData, - self->streamInfo.numChannels * self->streamInfo.frameSize * - sizeof(*pTimeData)); - } else { - FDKmemclear(pTimeData_extern, - timeDataSize_extern * sizeof(*pTimeData_extern)); + if (!IS_OUTPUT_VALID(ErrorStatus)) { + FDKmemclear(pTimeData, timeDataSize * sizeof(*pTimeData)); } return ErrorStatus; diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp index b3d09a6..0bca577 100644 --- a/libAACdec/src/block.cpp +++ b/libAACdec/src/block.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1015,9 +1015,9 @@ FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) { void CBlock_FrequencyToTime( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1, - UINT elFlags, INT elCh) { + const INT aacOutDataHeadroom, UINT elFlags, INT elCh) { int fr, fl, tl, nSpec; #if defined(FDK_ASSERT_ENABLE) @@ -1213,6 +1213,7 @@ void CBlock_FrequencyToTime( bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen, (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR, frameLen - (LpdSfd + 4) * L_SUBFR, outSamples, + aacOutDataHeadroom, pAacDecoderStaticChannelInfo->mem_bpf); } @@ -1236,7 +1237,8 @@ void CBlock_FrequencyToTime( ? MLT_FLAG_CURR_ALIAS_SYMMETRY : 0); - scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM); + scaleValuesSaturate(outSamples, tmp, frameLen, + MDCT_OUT_HEADROOM - aacOutDataHeadroom); } } @@ -1251,7 +1253,7 @@ void CBlock_FrequencyToTime( #include "ldfiltbank.h" void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const short frameLen) { InvMdctTransformLowDelay_fdk( SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), diff --git a/libAACdec/src/block.h b/libAACdec/src/block.h index f0f56cd..f5118a2 100644 --- a/libAACdec/src/block.h +++ b/libAACdec/src/block.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -218,16 +218,16 @@ void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[], */ void CBlock_FrequencyToTime( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1, - UINT elFlags, INT elCh); + const INT aacOutDataHeadroom, UINT elFlags, INT elCh); /** * \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain. */ void CBlock_FrequencyToTimeLowDelay( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC outSamples[], const short frameLen); AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData( diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 379e63a..0939bb5 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -226,7 +226,7 @@ static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec, /* TimeDomainFading */ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata); + FIXP_DBL fadeStop, PCM_DEC *pcmdata); static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations, int *fadingSteps, FIXP_DBL fadeStop, @@ -242,7 +242,9 @@ static int CConcealment_ApplyFadeOut( static int CConcealment_TDNoise_Random(ULONG *seed); static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata); + const int len, + const INT aacOutDataHeadroom, + PCM_DEC *const pcmdata); static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) { BLOCK_TYPE newWinSeq = BLOCK_LONG; @@ -1844,7 +1846,7 @@ Target fading level is determined by fading index cntFadeFrames. INT CConcealment_TDFading( int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) { + const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1) { /* Do the fading in Time domain based on concealment states and core mode */ @@ -1957,7 +1959,8 @@ INT CConcealment_TDFading( start += len; } } - CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata); + CConcealment_TDNoise_Apply(pConcealmentInfo, len, aacOutDataHeadroom, + pcmdata); /* Save end-of-frame attenuation and fading type */ pConcealmentInfo->lastFadingType = fadingType; @@ -1969,12 +1972,11 @@ INT CConcealment_TDFading( /* attenuate pcmdata in Time Domain Fading process */ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, - FIXP_DBL fadeStop, FIXP_PCM *pcmdata) { + FIXP_DBL fadeStop, PCM_DEC *pcmdata) { int i; FIXP_DBL dStep; FIXP_DBL dGain; FIXP_DBL dGain_apply; - int bitshift = (DFRACT_BITS - SAMPLE_BITS); /* set start energy */ dGain = fadeStart; @@ -1987,7 +1989,7 @@ static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart, */ dGain_apply = fMax((FIXP_DBL)0, dGain); /* finally, attenuate samples */ - pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift); + pcmdata[i] = FIXP_DBL2PCM_DEC(fMult(pcmdata[i], dGain_apply)); } } @@ -2050,9 +2052,11 @@ static int CConcealment_TDNoise_Random(ULONG *seed) { } static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, - const int len, FIXP_PCM *const pcmdata) { - FIXP_PCM *states = pConcealmentInfo->TDNoiseStates; - FIXP_PCM noiseVal; + const int len, + const INT aacOutDataHeadroom, + PCM_DEC *const pcmdata) { + PCM_DEC *states = pConcealmentInfo->TDNoiseStates; + PCM_DEC noiseVal; FIXP_DBL noiseValLong; FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef; FIXP_DBL TDNoiseAtt; @@ -2070,18 +2074,20 @@ static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo, /* create filtered noise */ states[2] = states[1]; states[1] = states[0]; - states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed)); + states[0] = + FIXP_DBL2PCM_DEC((FIXP_DBL)CConcealment_TDNoise_Random(&seed)); noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) + fMult(states[2], coef[2]); - noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt)); + noiseVal = FIXP_DBL2PCM_DEC(fMult(noiseValLong, TDNoiseAtt) >> + aacOutDataHeadroom); /* add filtered noise - check for clipping, before */ - if (noiseVal > (FIXP_PCM)0 && - pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) { - noiseVal = noiseVal * (FIXP_PCM)-1; - } else if (noiseVal < (FIXP_PCM)0 && - pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) { - noiseVal = noiseVal * (FIXP_PCM)-1; + if (noiseVal > (PCM_DEC)0 && + pcmdata[ii] > (PCM_DEC)MAXVAL_PCM_DEC - noiseVal) { + noiseVal = noiseVal * (PCM_DEC)-1; + } else if (noiseVal < (PCM_DEC)0 && + pcmdata[ii] < (PCM_DEC)MINVAL_PCM_DEC - noiseVal) { + noiseVal = noiseVal * (PCM_DEC)-1; } pcmdata[ii] += noiseVal; diff --git a/libAACdec/src/conceal.h b/libAACdec/src/conceal.h index e01a796..0c002a5 100644 --- a/libAACdec/src/conceal.h +++ b/libAACdec/src/conceal.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -147,6 +147,6 @@ int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, INT CConcealment_TDFading( int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo, - FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1); + const INT aacOutDataHeadroom, PCM_DEC *pcmdata, PCM_DEC *pcmdata_1); #endif /* #ifndef CONCEAL_H */ diff --git a/libAACdec/src/conceal_types.h b/libAACdec/src/conceal_types.h index d90374e..36e7dec 100644 --- a/libAACdec/src/conceal_types.h +++ b/libAACdec/src/conceal_types.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -194,7 +194,7 @@ typedef struct { FIXP_DBL last_tcx_gain; INT last_tcx_gain_e; ULONG TDNoiseSeed; - FIXP_PCM TDNoiseStates[3]; + PCM_DEC TDNoiseStates[3]; FIXP_SGL TDNoiseCoef[3]; FIXP_SGL TDNoiseAtt; diff --git a/libAACdec/src/ldfiltbank.cpp b/libAACdec/src/ldfiltbank.cpp index 1898557..13e61a5 100644 --- a/libAACdec/src/ldfiltbank.cpp +++ b/libAACdec/src/ldfiltbank.cpp @@ -112,17 +112,20 @@ amm-info@iis.fraunhofer.de #if defined(__arm__) #endif -static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, +static void multE2_DinvF_fdk(PCM_DEC *output, FIXP_DBL *x, const FIXP_WTB *fb, FIXP_DBL *z, const int N) { int i; - /* scale for FIXP_DBL -> INT_PCM conversion. */ - const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM; -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) + /* scale for FIXP_DBL -> PCM_DEC conversion: */ + const int scale = (DFRACT_BITS - PCM_OUT_BITS) - LDFB_HEADROOM + (3); + +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0; FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0; +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - WTS0 - 1) > 0) if (-WTS0 - 1 + scale) rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1)); +#endif if (-WTS1 - 1 + scale) rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1)); #endif @@ -141,16 +144,16 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N + N / 2 + i])); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS1 - 1 + scale) >= 0); FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts1)); /* rounding must not cause overflow */ - output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS1 + 1 - scale) >= 0); output[(N * 3 / 4 - 1 - i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS); #endif z[i] = z0; @@ -173,22 +176,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + fMultDiv2(z[i], fb[N + N / 2 + i])); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS0 - 1 + scale) >= 0); FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts0)); /* rounding must not cause overflow */ FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts1)); /* rounding must not cause overflow */ - output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(i - N / 4)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS); - output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 - 1 - i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS0 + 1 - scale) >= 0); output[(i - N / 4)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); output[(N * 3 / 4 - 1 - i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS); #endif z[i] = z0; z[N + i] = z2; @@ -198,22 +201,22 @@ static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb, for (i = 0; i < N / 4; i++) { FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]); -#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0) +#if ((DFRACT_BITS - PCM_OUT_BITS - LDFB_HEADROOM + (3) - 1) > 0) FDK_ASSERT((-WTS0 - 1 + scale) >= 0); FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF - rnd_val_wts0)); /* rounding must not cause overflow */ - output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT( + output[(N * 3 / 4 + i)] = (PCM_DEC)SATURATE_RIGHT_SHIFT( tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS); #else FDK_ASSERT((WTS0 + 1 - scale) >= 0); output[(N * 3 / 4 + i)] = - (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); + (PCM_DEC)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS); #endif } } int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e, - FIXP_PCM *output, FIXP_DBL *fs_buffer, + PCM_DEC *output, FIXP_DBL *fs_buffer, const int N) { const FIXP_WTB *coef; FIXP_DBL gain = (FIXP_DBL)0; diff --git a/libAACdec/src/ldfiltbank.h b/libAACdec/src/ldfiltbank.h index b63da6b..02971d0 100644 --- a/libAACdec/src/ldfiltbank.h +++ b/libAACdec/src/ldfiltbank.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -104,9 +104,10 @@ amm-info@iis.fraunhofer.de #define LDFILTBANK_H #include "common_fix.h" +#include "aac_rom.h" int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e, - FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer, + PCM_DEC *mdctOut, FIXP_DBL *fs_buffer, const int frameLength); #endif diff --git a/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp index de0c2de..fbf6fab 100644 --- a/libAACdec/src/usacdec_lpd.cpp +++ b/libAACdec/src/usacdec_lpd.cpp @@ -122,18 +122,21 @@ amm-info@iis.fraunhofer.de #include "ac_arith_coder.h" -void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, - const FIXP_SGL *filt, INT stop, int len) { +void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise, + const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop, + int len) { INT i, j; FIXP_DBL tmp; + FDK_ASSERT((aacOutDataHeadroom - 1) >= -(MDCT_OUTPUT_SCALE)); + for (i = 0; i < stop; i++) { tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16 for (j = 1; j <= len; j++) { tmp += fMult((noise[i - j] >> 1) + (noise[i + j] >> 1), filt[j]); } - syn_out[i] = (FIXP_PCM)(SATURATE_SHIFT( - (syn[i] >> 1) - (tmp >> 1), (MDCT_OUTPUT_SCALE - 1), PCM_OUT_BITS)); + syn_out[i] = (PCM_DEC)( + IMDCT_SCALE((syn[i] >> 1) - (tmp >> 1), aacOutDataHeadroom - 1)); } } @@ -143,8 +146,10 @@ void bass_pf_1sf_delay( FIXP_DBL *pit_gain, const int frame_length, /* (i) : frame length (should be 768|1024) */ const INT l_frame, - const INT l_next, /* (i) : look ahead for symmetric filtering */ - FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */ + const INT l_next, /* (i) : look ahead for symmetric filtering */ + PCM_DEC *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */ + const INT aacOutDataHeadroom, /* (i) : headroom of the output time signal to + prevent clipping */ FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */ { INT i, sf, i_subfr, T, T2, lg; @@ -370,7 +375,7 @@ void bass_pf_1sf_delay( { filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise, - fdk_dec_filt_lp, L_SUBFR, L_FILT); + fdk_dec_filt_lp, aacOutDataHeadroom, L_SUBFR, L_FILT); } } @@ -383,9 +388,9 @@ void bass_pf_1sf_delay( /* Output scaling of the BPF memory */ scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1); /* Copy the rest of the signal (after the fac) */ - scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame], - (FIXP_DBL *)&syn[l_frame - L_SUBFR], - (frame_length - l_frame), MDCT_OUT_HEADROOM); + scaleValuesSaturate( + (PCM_DEC *)&synth_out[l_frame], (FIXP_DBL *)&syn[l_frame - L_SUBFR], + (frame_length - l_frame), MDCT_OUT_HEADROOM - aacOutDataHeadroom); } return; @@ -1552,9 +1557,9 @@ void CLpdChannelStream_Decode( AAC_DECODER_ERROR CLpd_RenderTimeSignal( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData, - INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags, - UINT strmFlags) { + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData, + INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, + const INT aacOutDataHeadroom, UINT flags, UINT strmFlags) { UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod; AAC_DECODER_ERROR error = AAC_DEC_OK; int k, i_offset; @@ -2017,7 +2022,8 @@ AAC_DECODER_ERROR CLpd_RenderTimeSignal( { bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB, mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay, - pTimeData, pAacDecoderStaticChannelInfo->mem_bpf); + pTimeData, aacOutDataHeadroom, + pAacDecoderStaticChannelInfo->mem_bpf); } } diff --git a/libAACdec/src/usacdec_lpd.h b/libAACdec/src/usacdec_lpd.h index 3e7938d..448dc55 100644 --- a/libAACdec/src/usacdec_lpd.h +++ b/libAACdec/src/usacdec_lpd.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -140,13 +140,14 @@ void CLpdChannelStream_Decode( * \param pTimeData pointer to output buffer * \param samplesPerFrame amount of output samples * \param pSamplingRateInfo holds the sampling rate information - * \param pWorkBuffer1 pointer to work buffer for temporal data + * \param aacOutDataHeadroom headroom of the output time signal to prevent + * clipping */ AAC_DECODER_ERROR CLpd_RenderTimeSignal( CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData, + CAacDecoderChannelInfo *pAacDecoderChannelInfo, PCM_DEC *pTimeData, INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, - UINT flags, UINT strmFlags); + const INT aacOutDataHeadroom, UINT flags, UINT strmFlags); static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) { if (fNotShortBlock) { @@ -156,8 +157,9 @@ static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) { } } -void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, - const FIXP_SGL *filt, INT stop, int len); +void filtLP(const FIXP_DBL *syn, PCM_DEC *syn_out, FIXP_DBL *noise, + const FIXP_SGL *filt, const INT aacOutDataHeadroom, INT stop, + int len); /** * \brief perform a low-frequency pitch enhancement on time domain signal @@ -171,13 +173,14 @@ void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise, * \param[in] l_frame length of filtering, must be multiple of L_SUBFR * \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next * \param[out] synth_out pointer to time domain output signal + * \param[in] headroom of the output time signal to prevent clipping * \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR) */ void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain, const int frame_length, const INT l_frame, - const INT l_next, FIXP_PCM *synth_out, - FIXP_DBL mem_bpf[]); + const INT l_next, PCM_DEC *synth_out, + const INT aacOutDataHeadroom, FIXP_DBL mem_bpf[]); /** * \brief random sign generator for FD and TCX noise filling diff --git a/libFDK/include/FDK_qmf_domain.h b/libFDK/include/FDK_qmf_domain.h index aa247e9..0e83da3 100644 --- a/libFDK/include/FDK_qmf_domain.h +++ b/libFDK/include/FDK_qmf_domain.h @@ -160,8 +160,6 @@ H_ALLOC_MEM(QmfSlotsImag32, FIXP_DBL *) H_ALLOC_MEM(QmfOverlapBuffer16, FIXP_DBL) H_ALLOC_MEM(QmfOverlapBuffer32, FIXP_DBL) -#define QDOM_PCM INT_PCM - /** * Structure to hold the configuration data which is global whithin a QMF domain * instance. @@ -181,9 +179,6 @@ typedef struct { park a channel if only one processing channel is available. */ UCHAR parkChannel_requested; - QDOM_PCM - *TDinput; /*!< Pointer to time domain data used as input for the QMF - analysis. */ FIXP_DBL * pWorkBuffer[QMF_MAX_WB_SECTIONS]; /*!< Pointerarray to volatile memory. */ UINT flags; /*!< Flags to be set on all QMF analysis/synthesis filter diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h index 1382374..e7cf3ad 100644 --- a/libFDK/include/mdct.h +++ b/libFDK/include/mdct.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -106,18 +106,16 @@ amm-info@iis.fraunhofer.de #include "common_fix.h" #define MDCT_OUT_HEADROOM 2 /* Output additional headroom */ -#define PCM_OUT_BITS SAMPLE_BITS + +#define PCM_OUT_BITS DFRACT_BITS #define PCM_OUT_HEADROOM 8 /* Must have the same values as DMXH_HEADROOM */ -#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - SAMPLE_BITS)) +#define MDCT_OUTPUT_SCALE (-MDCT_OUT_HEADROOM + (DFRACT_BITS - PCM_OUT_BITS)) /* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */ #define MDCT_OUTPUT_GAIN 16 -#if (MDCT_OUTPUT_SCALE >= 0) -#define IMDCT_SCALE(x) SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, PCM_OUT_BITS) -#else -#define IMDCT_SCALE(x) SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, PCM_OUT_BITS) -#endif +#define IMDCT_SCALE(x, s) \ + SATURATE_RIGHT_SHIFT((x), ((s) + MDCT_OUTPUT_SCALE), PCM_OUT_BITS) #define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) #define IMDCT_SCALE_DBL_LSH1(x) SATURATE_LEFT_SHIFT_ALT((x), 1, DFRACT_BITS) diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index 75ea8a2..2f77179 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -104,7 +104,7 @@ amm-info@iis.fraunhofer.de /* FDK tools library info */ #define FDK_TOOLS_LIB_VL0 3 -#define FDK_TOOLS_LIB_VL1 0 +#define FDK_TOOLS_LIB_VL1 1 #define FDK_TOOLS_LIB_VL2 0 #define FDK_TOOLS_LIB_TITLE "FDK Tools" #ifdef __ANDROID__ diff --git a/libFDK/src/FDK_qmf_domain.cpp b/libFDK/src/FDK_qmf_domain.cpp index 71e2ef5..77c5ca2 100644 --- a/libFDK/src/FDK_qmf_domain.cpp +++ b/libFDK/src/FDK_qmf_domain.cpp @@ -637,10 +637,10 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts, if (pQmfOutImag == NULL) { for (; b < fMin(lsb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], lb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf); } for (; b < fMin(usb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], hb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf); } for (; b < stop_band; b++) { pQmfOutReal[b] = (FIXP_DBL)0; @@ -648,12 +648,12 @@ void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts, } else { FDK_ASSERT(imag != NULL); for (; b < fMin(lsb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], lb_sf); - pQmfOutImag[b] = scaleValue(imag[b], lb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], lb_sf); + pQmfOutImag[b] = scaleValueSaturate(imag[b], lb_sf); } for (; b < fMin(usb, stop_band); b++) { - pQmfOutReal[b] = scaleValue(real[b], hb_sf); - pQmfOutImag[b] = scaleValue(imag[b], hb_sf); + pQmfOutReal[b] = scaleValueSaturate(real[b], hb_sf); + pQmfOutImag[b] = scaleValueSaturate(imag[b], hb_sf); } for (; b < stop_band; b++) { pQmfOutReal[b] = (FIXP_DBL)0; diff --git a/libPCMutils/include/limiter.h b/libPCMutils/include/limiter.h index fab7226..419e891 100644 --- a/libPCMutils/include/limiter.h +++ b/libPCMutils/include/limiter.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -109,8 +109,6 @@ amm-info@iis.fraunhofer.de #define TDL_ATTACK_DEFAULT_MS (15) /* default attack time in ms */ #define TDL_RELEASE_DEFAULT_MS (50) /* default release time in ms */ -#define TDL_GAIN_SCALING (15) /* scaling of gain value. */ - #ifdef __cplusplus extern "C" { #endif @@ -128,10 +126,7 @@ struct TDLimiter { unsigned int maxBufIdx, delayBufIdx; FIXP_DBL smoothState0; FIXP_DBL minGain; - - FIXP_DBL additionalGainPrev; - FIXP_DBL additionalGainFilterState; - FIXP_DBL additionalGainFilterState1; + INT scaling; }; typedef enum { @@ -255,27 +250,16 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter, /****************************************************************************** * pcmLimiter_Apply * - * limiter: limiter handle * - * pGain : pointer to gains to be applied to the signal before limiting, * - * which are downscaled by TDL_GAIN_SCALING bit. * - * These gains are delayed by gain_delay, and smoothed. * - * Smoothing is done by a butterworth lowpass filter with a cutoff * - * frequency which is fixed with respect to the sampling rate. * - * It is a substitute for the smoothing due to windowing and * - * overlap/add, if a gain is applied in frequency domain. * - * gain_scale: pointer to scaling exponents to be applied to the signal before * - * limiting, without delay and without smoothing * - * gain_size: number of elements in pGain, currently restricted to 1 * - * gain_delay: delay [samples] with which the gains in pGain shall be applied * - * gain_delay <= nSamples * - * samples: input/output buffer containing interleaved samples * - * precision of output will be DFRACT_BITS-TDL_GAIN_SCALING bits * - * nSamples: number of samples per channel * + * limiter: limiter handle * + * samplesIn: pointer to input buffer containing interleaved samples * + * samplesOut: pointer to output buffer containing interleaved samples * + * pGainPerSample: pointer to gains for each sample * + * scaling: scaling of output samples * + * nSamples: number of samples per channel * * returns: error code * ******************************************************************************/ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, - INT_PCM* samplesOut, FIXP_DBL* pGain, - const INT* gain_scale, const UINT gain_size, - const UINT gain_delay, const UINT nSamples); + INT_PCM* samplesOut, FIXP_DBL* pGainPerSample, + const INT scaling, const UINT nSamples); #endif /* #ifndef LIMITER_H */ diff --git a/libPCMutils/src/limiter.cpp b/libPCMutils/src/limiter.cpp index 60e3e3b..598dc0c 100644 --- a/libPCMutils/src/limiter.cpp +++ b/libPCMutils/src/limiter.cpp @@ -152,7 +152,7 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs, limiter->attack = attack; limiter->attackConst = attackConst; limiter->releaseConst = releaseConst; - limiter->threshold = threshold >> TDL_GAIN_SCALING; + limiter->threshold = threshold; limiter->channels = maxChannels; limiter->maxChannels = maxChannels; limiter->sampleRate = maxSampleRate; @@ -165,18 +165,13 @@ TDLimiterPtr pcmLimiter_Create(unsigned int maxAttackMs, unsigned int releaseMs, /* apply limiter */ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, - INT_PCM* samplesOut, FIXP_DBL* RESTRICT pGain, - const INT* RESTRICT gain_scale, - const UINT gain_size, const UINT gain_delay, - const UINT nSamples) { + INT_PCM* samplesOut, FIXP_DBL* pGainPerSample, + const INT scaling, const UINT nSamples) { unsigned int i, j; - FIXP_DBL tmp1; FIXP_DBL tmp2; - FIXP_DBL tmp, old, gain, additionalGain = 0, additionalGainUnfiltered; + FIXP_DBL tmp, old, gain, additionalGain = 0; FIXP_DBL minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); - - FDK_ASSERT(gain_size == 1); - FDK_ASSERT(gain_delay <= nSamples); + UINT additionalGainAvailable = 1; if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; @@ -185,7 +180,7 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, unsigned int attack = limiter->attack; FIXP_DBL attackConst = limiter->attackConst; FIXP_DBL releaseConst = limiter->releaseConst; - FIXP_DBL threshold = limiter->threshold; + FIXP_DBL threshold = limiter->threshold >> scaling; FIXP_DBL max = limiter->max; FIXP_DBL* maxBuf = limiter->maxBuf; @@ -195,55 +190,34 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, unsigned int delayBufIdx = limiter->delayBufIdx; FIXP_DBL smoothState0 = limiter->smoothState0; - FIXP_DBL additionalGainSmoothState = limiter->additionalGainFilterState; - FIXP_DBL additionalGainSmoothState1 = limiter->additionalGainFilterState1; - if (!gain_delay) { - additionalGain = pGain[0]; - if (gain_scale[0] > 0) { - additionalGain <<= gain_scale[0]; - } else { - additionalGain >>= -gain_scale[0]; - } + if (limiter->scaling != scaling) { + scaleValuesSaturate(delayBuf, attack * channels, + limiter->scaling - scaling); + scaleValuesSaturate(maxBuf, attack + 1, limiter->scaling - scaling); + max = scaleValueSaturate(max, limiter->scaling - scaling); + limiter->scaling = scaling; } - for (i = 0; i < nSamples; i++) { - if (gain_delay) { - if (i < gain_delay) { - additionalGainUnfiltered = limiter->additionalGainPrev; - } else { - additionalGainUnfiltered = pGain[0]; - } + if (pGainPerSample == NULL) { + additionalGainAvailable = 0; + } - /* Smooth additionalGain */ - /* [b,a] = butter(1, 0.01) */ - static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0), - FL2FXCONST_SGL(0.015466 * 2.0)}; - static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL, - FL2FXCONST_SGL(-0.96907)}; - additionalGain = -fMult(additionalGainSmoothState, a[1]) + - fMultDiv2(additionalGainUnfiltered, b[0]) + - fMultDiv2(additionalGainSmoothState1, b[1]); - additionalGainSmoothState1 = additionalGainUnfiltered; - additionalGainSmoothState = additionalGain; - - /* Apply the additional scaling that has no delay and no smoothing */ - if (gain_scale[0] > 0) { - additionalGain <<= gain_scale[0]; - } else { - additionalGain >>= -gain_scale[0]; - } - } + for (i = 0; i < nSamples; i++) { /* get maximum absolute sample value of all channels, including the * additional gain. */ - tmp1 = (FIXP_DBL)0; + tmp = (FIXP_DBL)0; for (j = 0; j < channels; j++) { tmp2 = PCM_LIM2FIXP_DBL(samplesIn[j]); tmp2 = (tmp2 == (FIXP_DBL)MINVAL_DBL) ? (FIXP_DBL)MAXVAL_DBL : fAbs(tmp2); - tmp1 = fMax(tmp1, tmp2); + tmp = fMax(tmp, tmp2); + } + + if (additionalGainAvailable) { + additionalGain = pGainPerSample[i]; + tmp = fMult(tmp, additionalGain); } - tmp = fMult(tmp1, additionalGain); /* set threshold as lower border to save calculations in running maximum * algorithm */ @@ -314,22 +288,42 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, /* lookahead delay, apply gain */ for (j = 0; j < channels; j++) { tmp = p_delayBuf[j]; - p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + + if (additionalGainAvailable) { + p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + } else { + p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]); + } /* Apply gain to delayed signal */ tmp = fMultDiv2(tmp, gain); - +#if (SAMPLE_BITS == DFRACT_BITS) + samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM( + (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling + 1, DFRACT_BITS)); +#else samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( - tmp, TDL_GAIN_SCALING + 1, DFRACT_BITS)); + tmp + ((FIXP_DBL)0x8000 >> (scaling + 1)), scaling + 1, + DFRACT_BITS)); +#endif } gain >>= 1; } else { /* lookahead delay, apply gain=1.0f */ for (j = 0; j < channels; j++) { tmp = p_delayBuf[j]; - p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + if (additionalGainAvailable) { + p_delayBuf[j] = fMult((FIXP_PCM_LIM)samplesIn[j], additionalGain); + } else { + p_delayBuf[j] = PCM_LIM2FIXP_DBL(samplesIn[j]); + } + +#if (SAMPLE_BITS == DFRACT_BITS) + samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM( + (FIXP_DBL)SATURATE_LEFT_SHIFT(tmp, scaling, DFRACT_BITS)); +#else samplesOut[j] = (INT_PCM)FX_DBL2FX_PCM((FIXP_DBL)SATURATE_LEFT_SHIFT( - tmp, TDL_GAIN_SCALING, DFRACT_BITS)); + tmp + ((FIXP_DBL)0x8000 >> scaling), scaling, DFRACT_BITS)); +#endif } } @@ -354,13 +348,9 @@ TDLIMITER_ERROR pcmLimiter_Apply(TDLimiterPtr limiter, PCM_LIM* samplesIn, limiter->delayBufIdx = delayBufIdx; limiter->smoothState0 = smoothState0; - limiter->additionalGainFilterState = additionalGainSmoothState; - limiter->additionalGainFilterState1 = additionalGainSmoothState1; limiter->minGain = minGain; - limiter->additionalGainPrev = pGain[0]; - return TDLIMIT_OK; } } @@ -370,7 +360,7 @@ TDLIMITER_ERROR pcmLimiter_SetThreshold(TDLimiterPtr limiter, FIXP_DBL threshold) { if (limiter == NULL) return TDLIMIT_INVALID_HANDLE; - limiter->threshold = threshold >> TDL_GAIN_SCALING; + limiter->threshold = threshold; return TDLIMIT_OK; } @@ -384,13 +374,7 @@ TDLIMITER_ERROR pcmLimiter_Reset(TDLimiterPtr limiter) { limiter->cor = FL2FXCONST_DBL(1.0f / (1 << 1)); limiter->smoothState0 = FL2FXCONST_DBL(1.0f / (1 << 1)); limiter->minGain = FL2FXCONST_DBL(1.0f / (1 << 1)); - - limiter->additionalGainPrev = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); - limiter->additionalGainFilterState = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); - limiter->additionalGainFilterState1 = - FL2FXCONST_DBL(1.0f / (1 << TDL_GAIN_SCALING)); + limiter->scaling = 0; FDKmemset(limiter->maxBuf, 0, (limiter->attack + 1) * sizeof(FIXP_DBL)); FDKmemset(limiter->delayBuf, 0, diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h index fa31af1..05371f8 100644 --- a/libPCMutils/src/version.h +++ b/libPCMutils/src/version.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -105,7 +105,7 @@ amm-info@iis.fraunhofer.de /* library info */ #define PCMUTIL_LIB_VL0 3 -#define PCMUTIL_LIB_VL1 0 +#define PCMUTIL_LIB_VL1 1 #define PCMUTIL_LIB_VL2 0 #define PCMUTIL_LIB_TITLE "PCM Utility Lib" #ifdef __ANDROID__ diff --git a/libSACdec/include/sac_dec_lib.h b/libSACdec/include/sac_dec_lib.h index 9913279..1827504 100644 --- a/libSACdec/include/sac_dec_lib.h +++ b/libSACdec/include/sac_dec_lib.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -252,7 +252,7 @@ typedef enum { scenario. Default parameter value is 3 frames. */ } SACDEC_PARAM; -#define PCM_MPS INT_PCM +#define PCM_MPS LONG /** * \brief MPEG Surround decoder handle. @@ -401,17 +401,22 @@ int mpegSurroundDecoder_Parse(CMpegSurroundDecoder *pMpegSurroundDecoder, * for each output audio channel is stored into. * \param mapDescr Channep map descriptor for output channel mapping * to be used (From MPEG PCE ordering to whatever is required). + * \param inDataHeadroom Headroom of SAC input time signal to prevent + * clipping. + * \param outDataHeadroom Pointer to headroom of SAC output time signal to + * prevent clipping. * * \return Error code. */ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, - INT_PCM *input, PCM_MPS *pTimeData, + PCM_MPS *input, PCM_MPS *pTimeData, const int timeDataSize, int timeDataFrameSize, int *nChannels, int *frameSize, int sampleRate, AUDIO_OBJECT_TYPE coreCodec, AUDIO_CHANNEL_TYPE channelType[], UCHAR channelIndices[], - const FDK_channelMapDescr *const mapDescr); + const FDK_channelMapDescr *const mapDescr, + const INT inDataHeadroom, INT *outDataHeadroom); /** * \brief Deallocate a MPEG Surround decoder instance. diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp index c1832f1..a7b50df 100644 --- a/libSACdec/src/sac_dec.cpp +++ b/libSACdec/src/sac_dec.cpp @@ -766,7 +766,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame, /* output scaling */ for (nCh = 0; nCh < self->numOutputChannelsAT; nCh++) { - int outputScale = 0, outputGain_e = 0, scale = 0; + int outputScale = 0, outputGain_e = 0, scale = -(8) + (1); FIXP_DBL outputGain_m = getChGain(self, nCh, &outputGain_e); if (!isTwoChMode(self->upmixType) && !bypassMode) { @@ -775,7 +775,7 @@ SACDEC_ERROR FDK_SpatialDecInit(spatialDec *self, SPATIAL_BS_FRAME *frame, synthesis qmf */ } - scale = outputScale; + scale += outputScale; qmfChangeOutScalefactor(&self->pQmfDomain->QmfDomainOut[nCh].fb, scale); qmfChangeOutGain(&self->pQmfDomain->QmfDomainOut[nCh].fb, outputGain_m, @@ -1223,18 +1223,24 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( !(self->stereoConfigIndex == 3)) { for (i = 0; i < self->qmfBands; i++) { self_qmfResidualReal__FDK_0_0[i] = - fMult(self_qmfResidualReal__FDK_0_0[i] << 1, + fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i], + 1 + self->sacInDataHeadroom - (1)), self->clipProtectGain__FDK); self_qmfResidualImag__FDK_0_0[i] = - fMult(self_qmfResidualImag__FDK_0_0[i] << 1, + fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i], + 1 + self->sacInDataHeadroom - (1)), self->clipProtectGain__FDK); } } else { for (i = 0; i < self->qmfBands; i++) { - self_qmfResidualReal__FDK_0_0[i] = fMult( - self_qmfResidualReal__FDK_0_0[i], self->clipProtectGain__FDK); - self_qmfResidualImag__FDK_0_0[i] = fMult( - self_qmfResidualImag__FDK_0_0[i], self->clipProtectGain__FDK); + self_qmfResidualReal__FDK_0_0[i] = + fMult(scaleValueSaturate(self_qmfResidualReal__FDK_0_0[i], + self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); + self_qmfResidualImag__FDK_0_0[i] = + fMult(scaleValueSaturate(self_qmfResidualImag__FDK_0_0[i], + self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); } } } @@ -1416,6 +1422,7 @@ SACDEC_ERROR SpatialDecApplyFrame( FDK_ASSERT(self != NULL); FDK_ASSERT(pControlFlags != NULL); FDK_ASSERT(pcmOutBuf != NULL); + FDK_ASSERT(self->sacInDataHeadroom >= (1)); self->errInt = err; /* Init internal error */ diff --git a/libSACdec/src/sac_dec.h b/libSACdec/src/sac_dec.h index 992acad..1c3df71 100644 --- a/libSACdec/src/sac_dec.h +++ b/libSACdec/src/sac_dec.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -523,6 +523,9 @@ struct spatialDec_struct { new frame after SSC change (aka decodeAfterConfigHasChangedFlag). */ SpatialDecConcealmentInfo concealInfo; + + INT sacInDataHeadroom; /* Headroom of the SAC input time signal to prevent + clipping */ }; #define SACDEC_SYNTAX_MPS 1 diff --git a/libSACdec/src/sac_dec_interface.h b/libSACdec/src/sac_dec_interface.h index a2eea92..05a9a75 100644 --- a/libSACdec/src/sac_dec_interface.h +++ b/libSACdec/src/sac_dec_interface.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -249,10 +249,10 @@ typedef struct { } MEM_REQUIREMENTS; -#define PCM_MPS INT_PCM -#define PCM_MPSF FIXP_PCM +#define PCM_MPS LONG +#define PCM_MPSF FIXP_DBL -#define FIXP_DBL2PCM_MPS(x) ((INT_PCM)FX_DBL2FX_PCM(x)) +#define FIXP_DBL2PCM_MPS(x) ((LONG)(x)) /* exposed functions (library interface) */ diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index bf6dedf..856a923 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_lib.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1507,15 +1507,17 @@ bail: } int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, - INT_PCM *input, PCM_MPS *pTimeData, + PCM_MPS *input, PCM_MPS *pTimeData, const int timeDataSize, int timeDataFrameSize, int *nChannels, int *frameSize, int sampleRate, AUDIO_OBJECT_TYPE coreCodec, AUDIO_CHANNEL_TYPE channelType[], UCHAR channelIndices[], - const FDK_channelMapDescr *const mapDescr) { + const FDK_channelMapDescr *const mapDescr, + const INT inDataHeadroom, INT *outDataHeadroom) { SACDEC_ERROR err = MPS_OK; PCM_MPS *pTimeOut = pTimeData; + PCM_MPS *TDinput = NULL; UINT initControlFlags = 0, controlFlags = 0; int timeDataRequiredSize = 0; int newData; @@ -1534,6 +1536,9 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, return MPS_NOTOK; } + pMpegSurroundDecoder->pSpatialDec->sacInDataHeadroom = inDataHeadroom; + *outDataHeadroom = (INT)(8); + pMpegSurroundDecoder->pSpatialDec->pConfigCurrent = &pMpegSurroundDecoder ->spatialSpecificConfig[pMpegSurroundDecoder->bsFrameDecode]; @@ -1682,8 +1687,7 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, (timeDataFrameSize * pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsSynthesis) / pMpegSurroundDecoder->pQmfDomain->globalConf.nBandsAnalysis; - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = - pTimeData + timeDataFrameSizeOut - timeDataFrameSize; + TDinput = pTimeData + timeDataFrameSizeOut - timeDataFrameSize; for (int i = *nChannels - 1; i >= 0; i--) { FDKmemmove(pTimeData + (i + 1) * timeDataFrameSizeOut - timeDataFrameSize, pTimeData + timeDataFrameSize * i, @@ -1694,8 +1698,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, } else { if (pMpegSurroundDecoder->mpegSurroundUseTimeInterface) { FDKmemcpy(input, pTimeData, - sizeof(INT_PCM) * (*nChannels) * (*frameSize)); - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput = input; + sizeof(PCM_MPS) * (*nChannels) * (*frameSize)); + TDinput = input; } } @@ -1707,8 +1711,8 @@ int mpegSurroundDecoder_Apply(CMpegSurroundDecoder *pMpegSurroundDecoder, &pMpegSurroundDecoder->bsFrames[pMpegSurroundDecoder->bsFrameDecode], pMpegSurroundDecoder->mpegSurroundUseTimeInterface ? INPUTMODE_TIME : INPUTMODE_QMF_SBR, - pMpegSurroundDecoder->pQmfDomain->globalConf.TDinput, NULL, NULL, - pTimeOut, *frameSize, &controlFlags, *nChannels, mapDescr); + TDinput, NULL, NULL, pTimeOut, *frameSize, &controlFlags, *nChannels, + mapDescr); *nChannels = pMpegSurroundDecoder->pSpatialDec->numOutputChannelsAT; if (err != @@ -1781,7 +1785,7 @@ void mpegSurroundDecoder_Close(CMpegSurroundDecoder *pMpegSurroundDecoder) { } #define SACDEC_VL0 2 -#define SACDEC_VL1 0 +#define SACDEC_VL1 1 #define SACDEC_VL2 0 int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) { diff --git a/libSACdec/src/sac_process.cpp b/libSACdec/src/sac_process.cpp index 95128f3..22091a9 100644 --- a/libSACdec/src/sac_process.cpp +++ b/libSACdec/src/sac_process.cpp @@ -187,8 +187,12 @@ SACDEC_ERROR SpatialDecQMFAnalysis(spatialDec *self, const PCM_MPS *inData, if (!isTwoChMode(self->upmixType) && !bypassMode) { int i; for (i = 0; i < self->qmfBands; i++) { - qmfReal[ch][i] = fMult(qmfReal[ch][i], self->clipProtectGain__FDK); - qmfImag[ch][i] = fMult(qmfImag[ch][i], self->clipProtectGain__FDK); + qmfReal[ch][i] = fMult( + scaleValueSaturate(qmfReal[ch][i], self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); + qmfImag[ch][i] = fMult( + scaleValueSaturate(qmfImag[ch][i], self->sacInDataHeadroom - (1)), + self->clipProtectGain__FDK); } } } @@ -216,16 +220,17 @@ SACDEC_ERROR SpatialDecFeedQMF(spatialDec *self, FIXP_DBL **qmfInDataReal, /* Write Input data to pQmfRealAnalysis. */ if (self->bShareDelayWithSBR) { - FDK_QmfDomain_GetSlot( - &self->pQmfDomain->QmfDomainIn[ch], ts + HYBRID_FILTER_DELAY, 0, - MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, pQmfImagAnalysis, 15); + FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], + ts + HYBRID_FILTER_DELAY, 0, + MAX_QMF_BANDS_TO_HYBRID, pQmfRealAnalysis, + pQmfImagAnalysis, 15 + (1)); FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, MAX_QMF_BANDS_TO_HYBRID, self->qmfBands, - pQmfRealAnalysis, pQmfImagAnalysis, 15); + pQmfRealAnalysis, pQmfImagAnalysis, 15 + (1)); } else { FDK_QmfDomain_GetSlot(&self->pQmfDomain->QmfDomainIn[ch], ts, 0, self->qmfBands, pQmfRealAnalysis, - pQmfImagAnalysis, 15); + pQmfImagAnalysis, 15 + (1)); } if (ts == self->pQmfDomain->globalConf.nQmfTimeSlots - 1) { /* Is currently also needed in case we dont have any overlap. We need to @@ -501,8 +506,8 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding( for (pb = 0, qs = 3; pb < 2; pb++) { INT s; FIXP_DBL maxVal; - FIXP_SGL mReal1; - FIXP_SGL mReal0, mImag0; + FIXP_DBL mReal1; + FIXP_DBL mReal0, mImag0; FIXP_DBL iReal0, iImag0, iReal1; iReal0 = interpolateParameter(alpha, MReal0[pb], MRealPrev0[pb]); @@ -515,9 +520,9 @@ SACDEC_ERROR SpatialDecApplyM2_Mode212_ResidualsPlusPhaseCoding( s = fMax(CntLeadingZeros(maxVal) - 1, 0); s = fMin(s, scale_param_m2); - mReal0 = FX_DBL2FX_SGL(iReal0 << s); - mImag0 = FX_DBL2FX_SGL(iImag0 << s); - mReal1 = FX_DBL2FX_SGL(iReal1 << s); + mReal0 = iReal0 << s; + mImag0 = iImag0 << s; + mReal1 = iReal1 << s; s = scale_param_m2 - s; @@ -934,6 +939,7 @@ SACDEC_ERROR SpatialDecSynthesis(spatialDec *self, const INT ts, self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= self->clipProtectGainSF__FDK; + self->pQmfDomain->QmfDomainIn[outCh].scaling.lb_scale -= (1); } else { /* Call the QMF synthesis for dry. */ err = CalculateSpaceSynthesisQmf(&self->pQmfDomain->QmfDomainOut[outCh], diff --git a/libSACdec/src/sac_qmf.cpp b/libSACdec/src/sac_qmf.cpp index a075490..fd7599d 100644 --- a/libSACdec/src/sac_qmf.cpp +++ b/libSACdec/src/sac_qmf.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de SACDEC_ERROR CalculateSpaceSynthesisQmf( const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr, - const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig) { + const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig) { SACDEC_ERROR err = MPS_OK; if (hQmfDomainOutCh == NULL) { diff --git a/libSACdec/src/sac_qmf.h b/libSACdec/src/sac_qmf.h index d1dc837..5cd573e 100644 --- a/libSACdec/src/sac_qmf.h +++ b/libSACdec/src/sac_qmf.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -124,7 +124,7 @@ amm-info@iis.fraunhofer.de */ SACDEC_ERROR CalculateSpaceSynthesisQmf( const HANDLE_FDK_QMF_DOMAIN_OUT hQmfDomainOutCh, const FIXP_DBL *Sr, - const FIXP_DBL *Si, const INT stride, INT_PCM *timeSig); + const FIXP_DBL *Si, const INT stride, PCM_MPS *timeSig); /** * \brief Convert audio input data to qmf representation. diff --git a/libSACdec/src/sac_reshapeBBEnv.cpp b/libSACdec/src/sac_reshapeBBEnv.cpp index b44ce4e..272d009 100644 --- a/libSACdec/src/sac_reshapeBBEnv.cpp +++ b/libSACdec/src/sac_reshapeBBEnv.cpp @@ -253,17 +253,17 @@ static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry, dry = wet = FL2FXCONST_DBL(0.0f); for (qs = 0; qs < cplxBands; qs++) { - dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) + - fPow2Div2(pHybOutputImagDry[qs])); - wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) + - fPow2Div2(pHybOutputImagWet[qs])); + dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1)) + + fPow2Div2(pHybOutputImagDry[qs] << (1))); + wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1)) + + fPow2Div2(pHybOutputImagWet[qs] << (1))); } for (; qs < hybBands; qs++) { - dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs])); - wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs])); + dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs] << (1))); + wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs] << (1))); } - *slotAmp_dry = dry; - *slotAmp_wet = wet; + *slotAmp_dry = dry >> (2 * (1)); + *slotAmp_wet = wet >> (2 * (1)); } #if defined(__aarch64__) @@ -327,7 +327,7 @@ static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels, INT shapeActiv = 1; INT hybBands = fixMin(42, self->hybridBands); - INT staticScale = self->staticDecScale; + INT staticScale = self->staticDecScale + (1); INT cplxBands; cplxBands = fixMin(42, self->hybridBands); diff --git a/libSACdec/src/sac_rom.h b/libSACdec/src/sac_rom.h index 38f17f2..d317856 100644 --- a/libSACdec/src/sac_rom.h +++ b/libSACdec/src/sac_rom.h @@ -111,21 +111,12 @@ amm-info@iis.fraunhofer.de #include "machine_type.h" /* Global ROM table data type: */ -#ifndef ARCH_PREFER_MULT_32x32 -#define FIXP_CFG FIXP_SGL -#define FX_CFG2FX_DBL FX_SGL2FX_DBL -#define FX_CFG2FX_SGL -#define CFG(a) (FX_DBL2FXCONST_SGL(a)) -#define FL2FXCONST_CFG FL2FXCONST_SGL -#define FX_DBL2FX_CFG(x) FX_DBL2FX_SGL((FIXP_DBL)(x)) -#else #define FIXP_CFG FIXP_DBL #define FX_CFG2FX_DBL #define FX_CFG2FX_SGL FX_DBL2FX_SGL #define CFG(a) FIXP_DBL(a) #define FL2FXCONST_CFG FL2FXCONST_DBL #define FX_DBL2FX_CFG(x) ((FIXP_DBL)(x)) -#endif /* others */ #define SCALE_INV_ICC (2) @@ -133,15 +124,9 @@ amm-info@iis.fraunhofer.de #define QCC_SCALE 1 #define M1M2_DATA FIXP_DBL -#ifndef ARCH_PREFER_MULT_32x32 -#define M1M2_CDATA FIXP_SGL -#define M1M2_CDATA2FX_DBL(a) FX_SGL2FX_DBL(a) -#define FX_DBL2M1M2_CDATA(a) FX_DBL2FX_SGL(a) -#else #define M1M2_CDATA FIXP_DBL #define M1M2_CDATA2FX_DBL(a) (a) #define FX_DBL2M1M2_CDATA(a) (a) -#endif #define CLIP_PROTECT_GAIN_0(x) FL2FXCONST_CFG(((x) / (float)(1 << 0))) #define CLIP_PROTECT_GAIN_1(x) FL2FXCONST_CFG(((x) / (float)(1 << 1))) diff --git a/libSBRdec/include/sbrdecoder.h b/libSBRdec/include/sbrdecoder.h index cc55572..c09c985 100644 --- a/libSBRdec/include/sbrdecoder.h +++ b/libSBRdec/include/sbrdecoder.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -361,15 +361,20 @@ SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, * error (0: core decoder found errors, 1: no errors). * \param psDecoded Pointer to a buffer holding a flag. Input: PS is * possible, Output: PS has been rendered. + * \param inDataHeadroom Headroom of the SBR input time signal to prevent + * clipping. + * \param outDataHeadroom Pointer to headroom of the SBR output time signal to + * prevent clipping. * * \return Error code. */ -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, +SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData, + const int timeDataSize, int *numChannels, + int *sampleRate, const FDK_channelMapDescr *const mapDescr, const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded); + UCHAR *psDecoded, const INT inDataHeadroom, + INT *outDataHeadroom); /** * \brief Close SBR decoder instance and free memory. diff --git a/libSBRdec/src/HFgen_preFlat.cpp b/libSBRdec/src/HFgen_preFlat.cpp index 268011e..ad4caba 100644 --- a/libSBRdec/src/HFgen_preFlat.cpp +++ b/libSBRdec/src/HFgen_preFlat.cpp @@ -897,10 +897,10 @@ void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, for (i = startSample; i < stopSample; i++) { maxVal |= (FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^ - ((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1))); + ((LONG)sourceBufferReal[i][loBand] >> (DFRACT_BITS - 1))); maxVal |= (FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^ - ((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1))); + ((LONG)sourceBufferImag[i][loBand] >> (DFRACT_BITS - 1))); } if (maxVal != FL2FX_DBL(0.0f)) { diff --git a/libSBRdec/src/hbe.cpp b/libSBRdec/src/hbe.cpp index 2284c42..d210bb6 100644 --- a/libSBRdec/src/hbe.cpp +++ b/libSBRdec/src/hbe.cpp @@ -957,7 +957,7 @@ QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize, hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1); hQmfTran->inBuf_F = - (INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM)); + (LONG*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(LONG)); /* buffered time signal needs to be delayed by synthesis_size; max * synthesis_size = 20; */ if (hQmfTran->inBuf_F == NULL) { diff --git a/libSBRdec/src/hbe.h b/libSBRdec/src/hbe.h index fdffe1e..3556783 100644 --- a/libSBRdec/src/hbe.h +++ b/libSBRdec/src/hbe.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -132,6 +132,9 @@ typedef enum { } KEEP_STATES_SYNCED_MODE; struct hbeTransposer { + FIXP_DBL anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE]; + FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE]; + int xOverQmf[MAX_NUM_PATCHES_HBE]; int maxStretch; @@ -144,7 +147,7 @@ struct hbeTransposer { int stopBand; int bSbr41; - INT_PCM *inBuf_F; + LONG *inBuf_F; FIXP_DBL **qmfInBufReal_F; FIXP_DBL **qmfInBufImag_F; @@ -156,9 +159,6 @@ struct hbeTransposer { FIXP_DBL const *synthesisQmfPreModCos_F; FIXP_DBL const *synthesisQmfPreModSin_F; - FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE]; - FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE]; - FIXP_DBL **qmfHBEBufReal_F; FIXP_DBL **qmfHBEBufImag_F; diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index 30611e7..b1fb0da 100644 --- a/libSBRdec/src/sbr_dec.cpp +++ b/libSBRdec/src/sbr_dec.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -259,17 +259,18 @@ static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal, void sbr_dec( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ + LONG *timeIn, /*!< pointer to input time signal */ + LONG *timeOut, /*!< pointer to output time signal */ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ + LONG *timeOutRight, /*!< pointer to output time signal */ const int strideOut, /*!< Time data traversal strideOut */ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ - HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize) { + HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize, + const INT sbrInDataHeadroom) { int i, slot, reserve; int saveLbScale; int lastSlotOffs; @@ -278,7 +279,7 @@ void sbr_dec( /* temporary pointer / variable for QMF; required as we want to use temporary buffer creating one frame delay for HBE in LP mode */ - INT_PCM *pTimeInQmf = timeIn; + LONG *pTimeInQmf = timeIn; /* Number of QMF timeslots in the overlap buffer: */ int ov_len = hSbrDec->LppTrans.pSettings->overlap; @@ -341,8 +342,8 @@ void sbr_dec( } else { C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64)); qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag, - &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1, - qmfTemp); + &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, + 0 + sbrInDataHeadroom, 1, qmfTemp); C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64)); } @@ -658,7 +659,7 @@ void sbr_dec( if (!(flags & SBRDEC_PS_DECODED)) { if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - int outScalefactor = 0; + int outScalefactor = -(8); if (h_ps_d != NULL) { h_ps_d->procFrameBased = 1; /* we here do frame based processing */ @@ -743,6 +744,7 @@ void sbr_dec( */ FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= QMF_MAX_SYNTHESIS_BANDS); + qmfChangeOutScalefactor(synQmfRight, -(8)); FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * sizeof(FIXP_QSS)); @@ -814,7 +816,8 @@ void sbr_dec( : scaleFactorLowBand_no_ov, scaleFactorHighBand, synQmf->lsb, synQmf->usb); - outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */ + outScalefactorL = outScalefactorR = + 1 + sbrInDataHeadroom; /* psDiffScale! (MPEG-PS) */ } sbrDecoder_drcApplySlot(/* right channel */ @@ -831,6 +834,9 @@ void sbr_dec( outScalefactorL += maxShift; if (!(flags & SBRDEC_SKIP_QMF_SYN)) { + qmfChangeOutScalefactor(synQmf, -(8)); + qmfChangeOutScalefactor(synQmfRight, -(8)); + qmfSynthesisFilteringSlot( synQmfRight, rQmfReal, /* QMF real buffer */ rQmfImag, /* QMF imag buffer */ diff --git a/libSBRdec/src/sbr_dec.h b/libSBRdec/src/sbr_dec.h index 156da03..eb9c394 100644 --- a/libSBRdec/src/sbr_dec.h +++ b/libSBRdec/src/sbr_dec.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -176,17 +176,18 @@ typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL; void sbr_dec( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ + LONG *timeIn, /*!< pointer to input time signal */ + LONG *timeOut, /*!< pointer to output time signal */ HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ + LONG *timeOutRight, /*!< pointer to output time signal */ INT strideOut, /*!< Time data traversal strideOut */ HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ - HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize); + HANDLE_PS_DEC h_ps_d, const UINT flags, const int codecFrameSize, + const INT sbrInDataHeadroom); SBR_ERROR createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData, diff --git a/libSBRdec/src/sbr_ram.h b/libSBRdec/src/sbr_ram.h index e00f8b5..452f835 100644 --- a/libSBRdec/src/sbr_ram.h +++ b/libSBRdec/src/sbr_ram.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -170,6 +170,9 @@ struct SBR_DECODER_INSTANCE { flushed consecutively. */ UINT flags; + + INT sbrInDataHeadroom; /* Headroom of the SBR input time signal to prevent + clipping */ }; H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT) diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 52403f6..6e4aad4 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -155,7 +155,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define SBRDECODER_LIB_VL0 3 -#define SBRDECODER_LIB_VL1 0 +#define SBRDECODER_LIB_VL1 1 #define SBRDECODER_LIB_VL2 0 #define SBRDECODER_LIB_TITLE "SBR Decoder" #ifdef __ANDROID__ @@ -1570,10 +1570,10 @@ bail: * \return SBRDEC_OK if successfull, else error code */ static SBR_ERROR sbrDecoder_DecodeElement( - HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData, - const int timeDataSize, const FDK_channelMapDescr *const mapDescr, - const int mapIdx, int channelIndex, const int elementIndex, - const int numInChannels, int *numOutChannels, const int psPossible) { + HANDLE_SBRDECODER self, LONG *input, LONG *timeData, const int timeDataSize, + const FDK_channelMapDescr *const mapDescr, const int mapIdx, + int channelIndex, const int elementIndex, const int numInChannels, + int *numOutChannels, const int psPossible) { SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex]; HANDLE_SBR_CHANNEL *pSbrChannel = self->pSbrElement[elementIndex]->pSbrChannel; @@ -1743,7 +1743,7 @@ static SBR_ERROR sbrDecoder_DecodeElement( timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags, - codecFrameSize); + codecFrameSize, self->sbrInDataHeadroom); if (stereo) { /* Process right channel */ @@ -1751,7 +1751,7 @@ static SBR_ERROR sbrDecoder_DecodeElement( timeData + offset1, NULL, NULL, strideOut, hSbrHeader, hFrameDataRight, &pSbrChannel[1]->prevFrameData, (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags, - codecFrameSize); + codecFrameSize, self->sbrInDataHeadroom); } C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) @@ -1771,14 +1771,14 @@ static SBR_ERROR sbrDecoder_DecodeElement( int copyFrameSize = codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels; copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels; - INT_PCM *ptr; + LONG *ptr; INT i; FDK_ASSERT(strideOut == 2); ptr = timeData; for (i = copyFrameSize >> 1; i--;) { - INT_PCM tmp; /* This temporal variable is required because some - compilers can't do *ptr++ = *ptr++ correctly. */ + LONG tmp; /* This temporal variable is required because some compilers + can't do *ptr++ = *ptr++ correctly. */ tmp = *ptr++; *ptr++ = tmp; tmp = *ptr++; @@ -1791,12 +1791,13 @@ static SBR_ERROR sbrDecoder_DecodeElement( return errorStatus; } -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, +SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, LONG *input, LONG *timeData, + const int timeDataSize, int *numChannels, + int *sampleRate, const FDK_channelMapDescr *const mapDescr, const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded) { + UCHAR *psDecoded, const INT inDataHeadroom, + INT *outDataHeadroom) { SBR_ERROR errorStatus = SBRDEC_OK; int psPossible; @@ -1833,6 +1834,9 @@ SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, psPossible = 0; } + self->sbrInDataHeadroom = inDataHeadroom; + *outDataHeadroom = (INT)(8); + /* Make sure that even if no SBR data was found/parsed *psDecoded is returned * 1 if psPossible was 0. */ if (psPossible == 0) { -- cgit v1.2.3 From 261fadc3a2221829196158824a512f11268756ef Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:28:33 +0100 Subject: Remove outdated apply_normalization parameter from legacy DRC module. Bug: 149514474 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I9b894007fc9d80da6aaee09d84c2b356f2c06ff7 --- libAACdec/src/aacdec_drc.cpp | 22 +++------------------- libAACdec/src/aacdec_drc.h | 1 - libAACdec/src/aacdec_drc_types.h | 1 - libAACdec/src/aacdecoder.cpp | 3 --- 4 files changed, 3 insertions(+), 24 deletions(-) diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 6066a64..b6f5b49 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -190,7 +190,6 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) { pParams->usrBoost = FL2FXCONST_DBL(0.0f); pParams->targetRefLevel = 96; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; - pParams->applyDigitalNorm = ON; pParams->applyHeavyCompression = OFF; pParams->usrApplyHeavyCompression = OFF; @@ -274,11 +273,8 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self, return AAC_DEC_INVALID_HANDLE; } if (value < 0) { - self->params.applyDigitalNorm = OFF; self->params.targetRefLevel = -1; } else { - /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ - self->params.applyDigitalNorm = ON; if (self->params.targetRefLevel != (SCHAR)value) { self->params.targetRefLevel = (SCHAR)value; self->progRefLevel = (SCHAR)value; /* Always set the program reference @@ -289,16 +285,6 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self, self->update = 1; } break; - case APPLY_NORMALIZATION: - if ((value != OFF) && (value != ON)) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - /* Store new parameter value */ - self->params.applyDigitalNorm = (UCHAR)value; - break; case APPLY_HEAVY_COMPRESSION: if ((value != OFF) && (value != ON)) { return AAC_DEC_SET_PARAM_FAIL; @@ -926,11 +912,9 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec, FDK_ASSERT(0); } } - if (self->params.applyDigitalNorm == OFF) { - /* Reset normalization gain since this module must not apply it */ - norm_mantissa = FL2FXCONST_DBL(0.5f); - norm_exponent = 1; - } + /* Reset normalization gain since this module must not apply it */ + norm_mantissa = FL2FXCONST_DBL(0.5f); + norm_exponent = 1; /* calc scale factors */ for (band = 0; band < numBands; band++) { diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 1873c5b..76a44d6 100644 --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -130,7 +130,6 @@ typedef enum { TARGET_REF_LEVEL, DRC_BS_DELAY, DRC_DATA_EXPIRY_FRAME, - APPLY_NORMALIZATION, APPLY_HEAVY_COMPRESSION, DEFAULT_PRESENTATION_MODE, ENCODER_TARGET_LEVEL, diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index 873bd60..d4393f7 100644 --- a/libAACdec/src/aacdec_drc_types.h +++ b/libAACdec/src/aacdec_drc_types.h @@ -168,7 +168,6 @@ typedef struct { UINT expiryFrame; UCHAR bsDelayEnable; - UCHAR applyDigitalNorm; AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode; UCHAR encoderTargetLevel; diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 6a0254d..965631b 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -3177,9 +3177,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR)); } - /* Turn off DRC modules level normalization in digital domain. */ - aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION, 0); - /* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is * present and one of DRC or Loudness Normalization is switched on */ aacDecoder_drcSetParam( -- cgit v1.2.3 From 7f7bbce892d9e8ed45e4ee2ee7dcefc1cd87a763 Mon Sep 17 00:00:00 2001 From: Anuj Joshi Date: Fri, 27 Mar 2020 10:43:08 +0530 Subject: Stop using __DATE__/__TIME__ on all builds Test: mmma external/libaac Bug: 151595970 Change-Id: Icd937cad3e4e2f70a5486cca424544eb410be26f --- Android.bp | 1 + libAACdec/src/aacdecoder_lib.cpp | 2 +- libAACenc/src/aacenc_lib.cpp | 2 +- libDRCdec/src/FDK_drcDecLib.cpp | 2 +- libFDK/src/FDK_core.cpp | 2 +- libMpegTPDec/src/tpdec_lib.cpp | 2 +- libMpegTPEnc/src/tpenc_lib.cpp | 2 +- libPCMutils/src/version.h | 2 +- libSACdec/src/sac_dec_lib.cpp | 2 +- libSACenc/src/sacenc_lib.cpp | 2 +- libSBRdec/src/sbrdecoder.cpp | 2 +- libSBRenc/src/sbr_encoder.cpp | 2 +- 12 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Android.bp b/Android.bp index 80a0347..4d52b71 100644 --- a/Android.bp +++ b/Android.bp @@ -23,6 +23,7 @@ cc_library_static { "-Wuninitialized", "-Wno-self-assign", "-Wno-implicit-fallthrough", + "-DSUPPRESS_BUILD_DATE_INFO", ], sanitize: { misc_undefined:[ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 86ec899..3a1fc48 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -122,7 +122,7 @@ amm-info@iis.fraunhofer.de #define AACDECODER_LIB_VL1 1 #define AACDECODER_LIB_VL2 2 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define AACDECODER_LIB_BUILD_DATE "" #define AACDECODER_LIB_BUILD_TIME "" #else diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 0f0094f..a152c0d 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de #define AACENCODER_LIB_VL1 0 #define AACENCODER_LIB_VL2 0 #define AACENCODER_LIB_TITLE "AAC Encoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define AACENCODER_LIB_BUILD_DATE "" #define AACENCODER_LIB_BUILD_TIME "" #else diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index 4f8ebc7..98a73ca 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de #define DRCDEC_LIB_VL1 1 #define DRCDEC_LIB_VL2 0 #define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define DRCDEC_LIB_BUILD_DATE "" #define DRCDEC_LIB_BUILD_TIME "" #else diff --git a/libFDK/src/FDK_core.cpp b/libFDK/src/FDK_core.cpp index 75ea8a2..52f8915 100644 --- a/libFDK/src/FDK_core.cpp +++ b/libFDK/src/FDK_core.cpp @@ -107,7 +107,7 @@ amm-info@iis.fraunhofer.de #define FDK_TOOLS_LIB_VL1 0 #define FDK_TOOLS_LIB_VL2 0 #define FDK_TOOLS_LIB_TITLE "FDK Tools" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define FDK_TOOLS_LIB_BUILD_DATE "" #define FDK_TOOLS_LIB_BUILD_TIME "" #else diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 506aed3..0b8ff24 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1750,7 +1750,7 @@ TRANSPORTDEC_ERROR transportDec_GetLibInfo(LIB_INFO *info) { info += i; info->module_id = FDK_TPDEC; -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libMpegTPEnc/src/tpenc_lib.cpp b/libMpegTPEnc/src/tpenc_lib.cpp index 14ea5fe..77c19b5 100644 --- a/libMpegTPEnc/src/tpenc_lib.cpp +++ b/libMpegTPEnc/src/tpenc_lib.cpp @@ -647,7 +647,7 @@ TRANSPORTENC_ERROR transportEnc_GetLibInfo(LIB_INFO *info) { info->module_id = FDK_TPENC; info->version = LIB_VERSION(TP_LIB_VL0, TP_LIB_VL1, TP_LIB_VL2); LIB_VERSION_STRING(info); -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libPCMutils/src/version.h b/libPCMutils/src/version.h index fa31af1..8e537ee 100644 --- a/libPCMutils/src/version.h +++ b/libPCMutils/src/version.h @@ -108,7 +108,7 @@ amm-info@iis.fraunhofer.de #define PCMUTIL_LIB_VL1 0 #define PCMUTIL_LIB_VL2 0 #define PCMUTIL_LIB_TITLE "PCM Utility Lib" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define PCMUTIL_LIB_BUILD_DATE "" #define PCMUTIL_LIB_BUILD_TIME "" #else diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index bf6dedf..a07e1c9 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_lib.cpp @@ -1800,7 +1800,7 @@ int mpegSurroundDecoder_GetLibInfo(LIB_INFO *info) { info += i; info->module_id = FDK_MPSDEC; -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else diff --git a/libSACenc/src/sacenc_lib.cpp b/libSACenc/src/sacenc_lib.cpp index d6a1658..fcfe39b 100644 --- a/libSACenc/src/sacenc_lib.cpp +++ b/libSACenc/src/sacenc_lib.cpp @@ -130,7 +130,7 @@ Description of file contents #define SACENC_LIB_VL1 0 #define SACENC_LIB_VL2 0 #define SACENC_LIB_TITLE "MPEG Surround Encoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define SACENC_LIB_BUILD_DATE "" #define SACENC_LIB_BUILD_TIME "" #else diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index c827ced..89a2338 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -160,7 +160,7 @@ amm-info@iis.fraunhofer.de #define SBRDECODER_LIB_VL1 0 #define SBRDECODER_LIB_VL2 0 #define SBRDECODER_LIB_TITLE "SBR Decoder" -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO #define SBRDECODER_LIB_BUILD_DATE "" #define SBRDECODER_LIB_BUILD_TIME "" #else diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp index df9e996..c1e083f 100644 --- a/libSBRenc/src/sbr_encoder.cpp +++ b/libSBRenc/src/sbr_encoder.cpp @@ -2560,7 +2560,7 @@ INT sbrEncoder_GetLibInfo(LIB_INFO *info) { info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); LIB_VERSION_STRING(info); -#ifdef __ANDROID__ +#ifdef SUPPRESS_BUILD_DATE_INFO info->build_date = ""; info->build_time = ""; #else -- cgit v1.2.3 From b09c5ae9f054cc33ac492f729f845cda61971da0 Mon Sep 17 00:00:00 2001 From: Anuj Joshi Date: Fri, 27 Mar 2020 10:44:41 +0530 Subject: aacdec: Add host support Test: Build libFraunhoferAAC on host Bug: 151595970 Change-Id: I4870251b6fe2143dca6b5eed9c2643705c63952c --- Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Android.bp b/Android.bp index 4d52b71..c0937dd 100644 --- a/Android.bp +++ b/Android.bp @@ -1,6 +1,7 @@ cc_library_static { name: "libFraunhoferAAC", vendor_available: true, + host_supported:true, srcs: [ "libAACdec/src/*.cpp", "libAACenc/src/*.cpp", @@ -52,4 +53,10 @@ cc_library_static { "libSACdec/include", "libSACenc/include", ], + + target: { + darwin: { + enabled: false, + }, + }, } -- cgit v1.2.3 From d41cddf9e9f46a1596c19505967261140a5bd6f8 Mon Sep 17 00:00:00 2001 From: Anuj Joshi Date: Thu, 26 Mar 2020 11:51:15 +0530 Subject: Added aac_dec_fuzzer Test: ./aac_dec_fuzzer Bug: 151595970 Change-Id: Iad37ae766288e9490520d858a6de0dd755e70681 --- fuzzer/Android.bp | 39 ++++++++++++++++++++++ fuzzer/README.md | 59 +++++++++++++++++++++++++++++++++ fuzzer/aac_dec_fuzzer.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 fuzzer/Android.bp create mode 100644 fuzzer/README.md create mode 100644 fuzzer/aac_dec_fuzzer.cpp diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp new file mode 100644 index 0000000..ae01dad --- /dev/null +++ b/fuzzer/Android.bp @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +cc_fuzz { + name: "aac_dec_fuzzer", + host_supported:true, + + static_libs: [ + "libFraunhoferAAC", + "liblog", + ], + + srcs: [ + "aac_dec_fuzzer.cpp", + ], + + target: { + darwin: { + enabled: false, + }, + }, +} diff --git a/fuzzer/README.md b/fuzzer/README.md new file mode 100644 index 0000000..d99bc75 --- /dev/null +++ b/fuzzer/README.md @@ -0,0 +1,59 @@ +# Fuzzer for libFraunhoferAAC decoder + +## Plugin Design Considerations +The fuzzer plugin for aac decoder is designed based on the understanding of the +codec and tries to achieve the following: + +##### Maximize code coverage + +This fuzzer makes use of the following config parameters: +1. Transport type (parameter name: `TRANSPORT_TYPE`) + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +| `TRANSPORT_TYPE` | 0.`TT_UNKNOWN ` 1.`TT_MP4_RAW ` 2.`TT_MP4_ADIF ` 3.`TT_MP4_ADTS ` 4.`TT_MP4_LATM_MCP1 ` 5.`TT_MP4_LATM_MCP0 ` 6.`TT_MP4_LOAS ` 7.`TT_DRM ` | `TT_MP4_ADIF ` | + +Note: Value of `TRANSPORT_TYPE` could be set to any of these values. +It is set to `TT_MP4_ADIF` in the fuzzer plugin. + +##### Maximize utilization of input data +The plugin feeds the entire input data to the codec using a loop. + * If the decode operation was successful, the input is advanced by an + offset calculated using valid bytes. + * If the decode operation was un-successful, the input is advanced by 1 byte + till it reaches a valid frame or end of stream. + +This ensures that the plugin tolerates any kind of input (empty, huge, +malformed, etc) and doesnt `exit()` on any input and thereby increasing the +chance of identifying vulnerabilities. + +## Build + +This describes steps to build aac_dec_fuzzer binary. + +## Android + +### Steps to build +Build the fuzzer +``` + $ mm -j$(nproc) aac_dec_fuzzer +``` + +### Steps to run +Create a directory CORPUS_DIR and copy some aac files to that folder. +Push this directory to device. + +To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/arm64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR +``` +To run on host +``` + $ $ANDROID_HOST_OUT/fuzz/x86_64/aac_dec_fuzzer/aac_dec_fuzzer CORPUS_DIR +``` + +## References: + * http://llvm.org/docs/LibFuzzer.html + * https://github.com/google/oss-fuzz + diff --git a/fuzzer/aac_dec_fuzzer.cpp b/fuzzer/aac_dec_fuzzer.cpp new file mode 100644 index 0000000..686c42f --- /dev/null +++ b/fuzzer/aac_dec_fuzzer.cpp @@ -0,0 +1,84 @@ +/****************************************************************************** + * + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "aacdecoder_lib.h" + +constexpr uint8_t kNumberOfLayers = 1; +constexpr uint8_t kMaxChannelCount = 8; + +class Codec { + public: + Codec() = default; + ~Codec() { deInitDecoder(); } + bool initDecoder(); + void decodeFrames(UCHAR *data, UINT size); + void deInitDecoder(); + + private: + HANDLE_AACDECODER mAacDecoderHandle = nullptr; + AAC_DECODER_ERROR mErrorCode = AAC_DEC_OK; +}; + +bool Codec::initDecoder() { + mAacDecoderHandle = aacDecoder_Open(TT_MP4_ADIF, kNumberOfLayers); + if (!mAacDecoderHandle) { + return false; + } + return true; +} + +void Codec::deInitDecoder() { + aacDecoder_Close(mAacDecoderHandle); + mAacDecoderHandle = nullptr; +} + +void Codec::decodeFrames(UCHAR *data, UINT size) { + while (size > 0) { + UINT inputSize = size; + UINT valid = size; + mErrorCode = aacDecoder_Fill(mAacDecoderHandle, &data, &inputSize, &valid); + if (mErrorCode != AAC_DEC_OK) { + ++data; + --size; + } else { + INT_PCM outputBuf[2048 * kMaxChannelCount]; + aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, 2048 * kMaxChannelCount, 0); + if (valid >= inputSize) { + return; + } + UINT offset = inputSize - valid; + data += offset; + size = valid; + } + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + Codec *codec = new Codec(); + if (!codec) { + return 0; + } + if (codec->initDecoder()) { + codec->decodeFrames((UCHAR *)(data), static_cast(size)); + } + delete codec; + return 0; +} -- cgit v1.2.3 From d40f05a61897c4ba746dd2b383fff0c158026c1f Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 16 Apr 2020 18:48:25 +0900 Subject: Set min_sdk_version to be part of mainline modules Modules contributing mainline modules (APK/APEX) should set min_sdk_version as well as apex_available. For now setting min_sdk_version doesn't change build outputs. But build-time checks will be added soon. Bug: 152655956 Test: m Change-Id: I662ad951a3221f967b53e7af65cb203a4b4a5e5d --- Android.bp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Android.bp b/Android.bp index c0937dd..555223b 100644 --- a/Android.bp +++ b/Android.bp @@ -1,7 +1,7 @@ cc_library_static { name: "libFraunhoferAAC", vendor_available: true, - host_supported:true, + host_supported: true, srcs: [ "libAACdec/src/*.cpp", "libAACenc/src/*.cpp", @@ -27,10 +27,10 @@ cc_library_static { "-DSUPPRESS_BUILD_DATE_INFO", ], sanitize: { - misc_undefined:[ - "unsigned-integer-overflow", - "signed-integer-overflow", - "bounds", + misc_undefined: [ + "unsigned-integer-overflow", + "signed-integer-overflow", + "bounds", ], // Enable CFI if this becomes a shared library. // cfi: true, @@ -59,4 +59,11 @@ cc_library_static { enabled: false, }, }, + + apex_available: [ + "//apex_available:platform", + "com.android.bluetooth.updatable", + "com.android.media.swcodec", + ], + min_sdk_version: "29", } -- cgit v1.2.3 From 4f10c70ca27dbf4caf3b7f92d9224d5e79121460 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Tue, 28 Apr 2020 09:39:28 -0700 Subject: Add METADATA to aac: Apache2=NOTICE Bug: 68860345 Bug: 69058154 Bug: 151953481 Test: no code changes Change-Id: I71f5c419c31c1758d4ee49158d40a50aef6abf5d --- METADATA | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 METADATA diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..d97975c --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: NOTICE +} -- cgit v1.2.3 From 71c477bae4e0b1bfad90fd4e4dbba496aa6d9c68 Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Thu, 16 Apr 2020 18:48:25 +0900 Subject: Set min_sdk_version to be part of mainline modules Modules contributing mainline modules (APK/APEX) should set min_sdk_version as well as apex_available. For now setting min_sdk_version doesn't change build outputs. But build-time checks will be added soon. Exempt-From-Owner-Approval: cherry-pick from aosp Bug: 152655956 Test: m Merged-In: I662ad951a3221f967b53e7af65cb203a4b4a5e5d Change-Id: I662ad951a3221f967b53e7af65cb203a4b4a5e5d (cherry picked from commit d40f05a61897c4ba746dd2b383fff0c158026c1f) --- Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Android.bp b/Android.bp index 80a0347..1cf54fd 100644 --- a/Android.bp +++ b/Android.bp @@ -51,4 +51,11 @@ cc_library_static { "libSACdec/include", "libSACenc/include", ], + + apex_available: [ + "//apex_available:platform", + "com.android.bluetooth.updatable", + "com.android.media.swcodec", + ], + min_sdk_version: "29", } -- cgit v1.2.3 From 64e4f25b299fed46eb4cf3fef21b25b916911515 Mon Sep 17 00:00:00 2001 From: Ayushi Khopkar Date: Mon, 18 May 2020 12:19:41 +0530 Subject: Added fuzz_config field in aac_dec_fuzzer Test: ./aac_dec_fuzzer Bug: 156871294 Change-Id: Idfc93a6f6c71a78c2b7759443161d8e75dfc4670 --- fuzzer/Android.bp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp index ae01dad..28a21b9 100644 --- a/fuzzer/Android.bp +++ b/fuzzer/Android.bp @@ -36,4 +36,11 @@ cc_fuzz { enabled: false, }, }, + + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, } -- cgit v1.2.3 From 92c9b7ea9a5bc19a9a6d33117ac902ce0f9e88dc Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Thu, 21 May 2020 12:49:18 -0700 Subject: Fix license type s/b BY_EXCEPTION_ONLY The Fraunhofer license has special requirements. Test: no code change Change-Id: I439354498c0a28d6ff078cea9a4f8e9bfc02145f --- METADATA | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/METADATA b/METADATA index d97975c..5c12860 100644 --- a/METADATA +++ b/METADATA @@ -1,3 +1,3 @@ third_party { - license_type: NOTICE + license_type: BY_EXCEPTION_ONLY } -- cgit v1.2.3 From ebc1030f65bb1e1e7dccf99e56a5d0221f097fdb Mon Sep 17 00:00:00 2001 From: Ray Essick Date: Tue, 26 May 2020 16:29:58 -0700 Subject: point to new repo hooks for mainline uploads Bug: 157501573 Test: upload Change-Id: I0e4764db6516d17a81dc5a31bf9d9427b2c570d6 --- PREUPLOAD.cfg | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 PREUPLOAD.cfg diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg new file mode 100644 index 0000000..ecf8b8e --- /dev/null +++ b/PREUPLOAD.cfg @@ -0,0 +1,2 @@ +[Hook Scripts] +mainline_hook = ${REPO_ROOT}/frameworks/av/tools/mainline_hook_project.sh -- cgit v1.2.3 From c1a75279a113d9cab3b2639ab9bd4070351655c5 Mon Sep 17 00:00:00 2001 From: S Vasudev Prasad Date: Fri, 15 May 2020 23:11:05 +0530 Subject: Improve code coverage for aac_dec_fuzzer Test: ./aac_dec_fuzzer Bug: 158206619 Change-Id: I42d57ec832dbd273f66ce149ce81bfcb1c514add --- fuzzer/aac_dec_fuzzer.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/fuzzer/aac_dec_fuzzer.cpp b/fuzzer/aac_dec_fuzzer.cpp index 686c42f..b5545fc 100644 --- a/fuzzer/aac_dec_fuzzer.cpp +++ b/fuzzer/aac_dec_fuzzer.cpp @@ -19,10 +19,58 @@ */ #include +#include +#include #include "aacdecoder_lib.h" constexpr uint8_t kNumberOfLayers = 1; constexpr uint8_t kMaxChannelCount = 8; +constexpr uint32_t kMaxConfigurationSize = 1024; +constexpr uint32_t kMaxOutBufferSize = 2048 * kMaxChannelCount; + +// Value indicating the start of AAC Header Segment +constexpr const char *kAacSegStartSeq = "AAC_STRT"; +constexpr uint8_t kAacSegStartSeqLen = sizeof(kAacSegStartSeq); +// Value indicating the end of AAC Header Segment +constexpr const char *kAacSegEndSeq = "AAC_ENDS"; +constexpr uint8_t kAacSegEndSeqLen = sizeof(kAacSegEndSeq); + +// Number of bytes used to signal the length of the header +constexpr uint8_t kHeaderLengthBytes = 2; +// Minimum size of an AAC header is 2 +// Minimum data required is +// strlen(AAC_STRT) + strlen(AAC_ENDS) + kHeaderLengthBytes + 2; +constexpr UINT kMinDataSize = kAacSegStartSeqLen + kAacSegEndSeqLen + kHeaderLengthBytes + 2; + +UINT getHeaderSize(UCHAR *data, UINT size) { + if (size < kMinDataSize) { + return 0; + } + + int32_t result = memcmp(data, kAacSegStartSeq, kAacSegStartSeqLen); + if (result) { + return 0; + } + data += kAacSegStartSeqLen; + size -= kAacSegStartSeqLen; + + uint32_t headerLengthInBytes = (data[0] << 8 | data[1]) & 0xFFFF; + data += kHeaderLengthBytes; + size -= kHeaderLengthBytes; + + if (headerLengthInBytes + kAacSegEndSeqLen > size) { + return 0; + } + + data += headerLengthInBytes; + size -= headerLengthInBytes; + result = memcmp(data, kAacSegEndSeq, kAacSegEndSeqLen); + if (result) { + return 0; + } + + return std::min(headerLengthInBytes, kMaxConfigurationSize); +} class Codec { public: @@ -51,6 +99,14 @@ void Codec::deInitDecoder() { } void Codec::decodeFrames(UCHAR *data, UINT size) { + UINT headerSize = getHeaderSize(data, size); + if (headerSize != 0) { + data += kAacSegStartSeqLen + kHeaderLengthBytes; + size -= kAacSegStartSeqLen + kHeaderLengthBytes; + aacDecoder_ConfigRaw(mAacDecoderHandle, &data, &headerSize); + data += headerSize + kAacSegEndSeqLen; + size -= headerSize + kAacSegEndSeqLen; + } while (size > 0) { UINT inputSize = size; UINT valid = size; @@ -59,11 +115,11 @@ void Codec::decodeFrames(UCHAR *data, UINT size) { ++data; --size; } else { - INT_PCM outputBuf[2048 * kMaxChannelCount]; - aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, 2048 * kMaxChannelCount, 0); - if (valid >= inputSize) { - return; - } + INT_PCM outputBuf[kMaxOutBufferSize]; + do { + mErrorCode = + aacDecoder_DecodeFrame(mAacDecoderHandle, outputBuf, sizeof(outputBuf), 0); + } while (mErrorCode == AAC_DEC_OK); UINT offset = inputSize - valid; data += offset; size = valid; -- cgit v1.2.3 From ffff95538e9994d312ffdfbba94d88ed226ef7bf Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Mon, 6 Jul 2020 16:37:38 +0200 Subject: Fix heap buffer overflow in sbrDecoder_AssignQmfChannels2SbrChannels(). In the bug the SBR decoder has already set up 9 channels and tries to allocate one more channel. The assignment of the QMF channels to SBR channels fails since the QMF domain manages only 8+1 channels instead of 10 channels as reqeusted by SBR. Here we have added a check in sbrDecoder_InitElement() which will return with a parse error in case additional SBR channels would exceed the maximum number of SBR channels. This solves the potential heap buffer overflow. Bug: 158762825 Test: atest DecoderTestAacDrc DecoderTestAacFormat DecoderTestXheAac Change-Id: I0150ac6d5a47ffce883010f531928656eebc619e Merged-In: I0150ac6d5a47ffce883010f531928656eebc619e (cherry picked from commit bb8f983bf36ee2ad8af6acebf4823a58060004ab) --- libSBRdec/src/sbrdecoder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libSBRdec/src/sbrdecoder.cpp b/libSBRdec/src/sbrdecoder.cpp index 6e4aad4..55f929f 100644 --- a/libSBRdec/src/sbrdecoder.cpp +++ b/libSBRdec/src/sbrdecoder.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -617,10 +617,6 @@ SBR_ERROR sbrDecoder_InitElement( self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels; } - /* Save element ID for sanity checks and to have a fallback for concealment. - */ - self->pSbrElement[elementIndex]->elementID = elementID; - /* Determine amount of channels for this element */ switch (elementID) { case ID_NONE: @@ -653,12 +649,16 @@ SBR_ERROR sbrDecoder_InitElement( } /* Sanity check to avoid memory leaks */ - if (elChannels < self->pSbrElement[elementIndex]->nChannels) { + if (elChannels < self->pSbrElement[elementIndex]->nChannels || + (self->numSbrChannels + elChannels) > (8) + (1)) { self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels; sbrError = SBRDEC_PARSE_ERROR; goto bail; } + /* Save element ID for sanity checks and to have a fallback for concealment. + */ + self->pSbrElement[elementIndex]->elementID = elementID; self->pSbrElement[elementIndex]->nChannels = elChannels; for (ch = 0; ch < elChannels; ch++) { -- cgit v1.2.3