From 8f2e68d5c4d2a1d67952c8af68005aa22de179ce Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:55:38 +0200 Subject: Introduce aacDecoder_drcDisable() and always disable legacy DRC for USAC. Bug: 176246647 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I75edf24b18e1f5392b6eb179d5574cb93fcbc7c2 --- libAACdec/src/aacdecoder.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 965631b..414c3e2 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -2383,8 +2383,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (*configChanged) { if (asc->m_aot == AOT_USAC) { - self->hDrcInfo->enable = 0; - self->hDrcInfo->progRefLevelPresent = 0; + aacDecoder_drcDisable(self->hDrcInfo); } } @@ -3194,11 +3193,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( * data in the bitstream. */ self->flags[streamIndex] |= AC_DRC_PRESENT; } else { - self->hDrcInfo->enable = 0; - self->hDrcInfo->progRefLevelPresent = 0; ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; } } + if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) { + aacDecoder_drcDisable(self->hDrcInfo); + } /* Create a reverse mapping table */ UCHAR Reverse_chMapping[((8) * 2)]; @@ -3441,11 +3441,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( * data in the bitstream. */ self->flags[streamIndex] |= AC_DRC_PRESENT; } else { - self->hDrcInfo->enable = 0; - self->hDrcInfo->progRefLevelPresent = 0; ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT; } } + if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) { + aacDecoder_drcDisable(self->hDrcInfo); + } } /* Add additional concealment delay */ -- cgit v1.2.3 From 9f2d1a18d451a3a9c5f0cd05120ddb0eea731d47 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:57:27 +0200 Subject: ELD downscale factor 3 is only allowed for framesize 480. Bug: 176246647 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I9681942ba39761e4f1d66236ad80c2420ca5abe9 --- libAACdec/src/aacdecoder.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 414c3e2..08128c0 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1791,9 +1791,17 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, downscaleFactorInBS = asc->m_samplingFrequency / asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency; - if (downscaleFactorInBS == 1 || downscaleFactorInBS == 2 || - downscaleFactorInBS == 3 || downscaleFactorInBS == 4) { + if ((downscaleFactorInBS == 1 || downscaleFactorInBS == 2 || + (downscaleFactorInBS == 3 && + asc->m_sc.m_eldSpecificConfig.m_frameLengthFlag) || + downscaleFactorInBS == 4) && + ((asc->m_samplingFrequency % + asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency) == + 0)) { downscaleFactor = downscaleFactorInBS; + } else { + downscaleFactorInBS = 1; + downscaleFactor = 1; } } } else { -- cgit v1.2.3 From bfd912da32b1253c9020a82d5520f1754dadcfc5 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:57:46 +0200 Subject: Improve decoder robustness by storing flags and elFlags temporarily. Bug: 176246647 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I6aaeef87e1f2ce5d5031f088b8c57e6f5806929d --- libAACdec/src/aacdecoder.cpp | 135 ++++++++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 53 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 08128c0..c6d1832 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1396,6 +1396,31 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self, self->samplingRateInfo[subStreamIndex].samplingRate = 0; } +/*! + * \brief CAacDecoder_AcceptFlags Accept flags and element flags + * + * \param self [o] handle to AACDECODER structure + * \param asc [i] handle to ASC structure + * \param flags [i] flags + * \param elFlags [i] pointer to element flags + * \param streamIndex [i] stream index + * \param elementOffset [i] element offset + * + * \return void + */ +static void CAacDecoder_AcceptFlags(HANDLE_AACDECODER self, + const CSAudioSpecificConfig *asc, + UINT flags, UINT *elFlags, int streamIndex, + int elementOffset) { + { + FDKmemcpy( + self->elFlags, elFlags, + sizeof(*elFlags) * (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)); + } + + self->flags[streamIndex] = flags; +} + /*! * \brief CAacDecoder_CtrlCFGChange Set config change parameters. * @@ -1493,6 +1518,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, const int streamIndex = 0; INT flushChannels = 0; + UINT flags; + UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)]; + if (!self) return AAC_DEC_INVALID_HANDLE; UCHAR downscaleFactor = self->downscaleFactor; @@ -1649,8 +1677,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } /* Set syntax flags */ - self->flags[streamIndex] = 0; - { FDKmemclear(self->elFlags, sizeof(self->elFlags)); } + flags = 0; + { FDKmemclear(elFlags, sizeof(elFlags)); } if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) { if (IS_USAC(asc->m_aot)) { @@ -1700,31 +1728,30 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } } - self->elFlags[el] |= - (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling) - ? AC_EL_USAC_NOISE - : 0; - self->elFlags[el] |= + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling) + ? AC_EL_USAC_NOISE + : 0; + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0) ? AC_EL_USAC_MPS212 : 0; - self->elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes) - ? AC_EL_USAC_ITES - : 0; - self->elFlags[el] |= + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes) + ? AC_EL_USAC_ITES + : 0; + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0; - self->elFlags[el] |= + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE) ? AC_EL_USAC_LFE : 0; - self->elFlags[el] |= + elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE) ? AC_EL_LFE : 0; if ((asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_CPE) && ((self->usacStereoConfigIndex[el] == 0))) { - self->elFlags[el] |= AC_EL_USAC_CP_POSSIBLE; + elFlags[el] |= AC_EL_USAC_CP_POSSIBLE; } } @@ -1846,8 +1873,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (configMode & AC_CM_ALLOC_MEM) { self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency; } - self->flags[streamIndex] |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; - self->flags[streamIndex] |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; + flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; + flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; if (asc->m_sbrPresentFlag) { self->sbrEnabled = 1; self->sbrEnabledPrev = 1; @@ -1873,51 +1900,47 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } /* --------- vcb11 ------------ */ - self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; + flags |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; /* ---------- rvlc ------------ */ - self->flags[streamIndex] |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0; + flags |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0; /* ----------- hcr ------------ */ - self->flags[streamIndex] |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; + flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; if (asc->m_aot == AOT_ER_AAC_ELD) { self->mpsEnableCurr = 0; - self->flags[streamIndex] |= AC_ELD; - self->flags[streamIndex] |= - (asc->m_sbrPresentFlag) - ? AC_SBR_PRESENT - : 0; /* Need to set the SBR flag for backward-compatibility - reasons. Even if SBR is not supported. */ - self->flags[streamIndex] |= - (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; - self->flags[streamIndex] |= - (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_MPS_PRESENT - : 0; + flags |= AC_ELD; + flags |= (asc->m_sbrPresentFlag) + ? AC_SBR_PRESENT + : 0; /* Need to set the SBR flag for backward-compatibility + reasons. Even if SBR is not supported. */ + flags |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; + flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) + ? AC_MPS_PRESENT + : 0; if (self->mpsApplicable) { self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; } } - self->flags[streamIndex] |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; - self->flags[streamIndex] |= (asc->m_epConfig >= 0) ? AC_ER : 0; + flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; + flags |= (asc->m_epConfig >= 0) ? AC_ER : 0; if (asc->m_aot == AOT_USAC) { - self->flags[streamIndex] |= AC_USAC; - self->flags[streamIndex] |= - (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0) - ? AC_MPS_PRESENT - : 0; + flags |= AC_USAC; + flags |= (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0) + ? AC_MPS_PRESENT + : 0; } if (asc->m_aot == AOT_DRM_AAC) { - self->flags[streamIndex] |= AC_DRM | AC_SBRCRC | AC_SCALABLE; + flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE; } if (asc->m_aot == AOT_DRM_SURROUND) { - self->flags[streamIndex] |= - AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT; + flags |= AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT; FDK_ASSERT(!asc->m_psPresentFlag); } if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) { - self->flags[streamIndex] |= AC_SCALABLE; + flags |= AC_SCALABLE; } if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) { @@ -1968,6 +1991,10 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (ascChanged != 0) { *configChanged = 1; } + + CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex, + elementOffset); + return err; } @@ -1996,7 +2023,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } if (usacStereoConfigIndex == 3) { - self->flags[streamIndex] |= AC_USAC_SCFGI3; + flags |= AC_USAC_SCFGI3; } } break; @@ -2077,14 +2104,14 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, ch = aacChannelsOffset; int _numElements; _numElements = (((8)) + (8)); - if (self->flags[streamIndex] & (AC_RSV603DA | AC_USAC)) { + if (flags & (AC_RSV603DA | AC_USAC)) { _numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements; } for (int _el = 0; _el < _numElements; _el++) { int el_channels = 0; int el = elementOffset + _el; - if (self->flags[streamIndex] & + if (flags & (AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) { if (ch >= ascChannels) { break; @@ -2184,15 +2211,14 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) { goto bail; } - if (self->flags[streamIndex] & - (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) { + if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) { self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create(); if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) { goto bail; } } - if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) { + if (!(flags & (AC_USAC | AC_RSV603DA))) { CPns_UpdateNoiseState( &self->pAacDecoderChannelInfo[ch]->data.aac.PnsData, &self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed, @@ -2203,7 +2229,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, chIdx++; } - if (self->flags[streamIndex] & AC_USAC) { + if (flags & AC_USAC) { for (int _ch = 0; _ch < flushChannels; _ch++) { ch = aacChannelsOffset + _ch; if (self->pTimeDataFlush[ch] == NULL) { @@ -2215,7 +2241,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } } - if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) { + if (flags & (AC_USAC | AC_RSV603DA)) { int complexStereoPredPossible = 0; ch = aacChannelsOffset; chIdx = aacChannelsOffsetIdx; @@ -2231,7 +2257,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, elCh = 1; } - if (self->elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) { + if (elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) { complexStereoPredPossible = 1; if (self->cpeStaticData[el2] == NULL) { self->cpeStaticData[el2] = GetCpePersistentData(); @@ -2368,9 +2394,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } } - /* Update externally visible copy of flags */ - self->streamInfo.flags = self->flags[0]; - if (*configChanged) { int drcDecSampleRate, drcDecFrameSize; @@ -2400,6 +2423,12 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f)); } + CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex, + elementOffset); + + /* Update externally visible copy of flags */ + self->streamInfo.flags = self->flags[0]; + return err; bail: -- cgit v1.2.3 From 3495808c8348ca8df31b0fdb051c135656931cb4 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 17 Apr 2020 15:07:13 +0200 Subject: Fix USAC time domain limiter latency at config change. We have observed quality problems regarding config switching for USAC streams. Crossfading did not consider the USAC time domain limiter latency correctly. The limiter memory still contained the last part of the frame before the config change. With this patch we were able to improve the quality by moving the limiter processing to the end of the processing chain (crossfade -> DRC -> limiter). By that we don't have to consider the limiter latency at the crossfader anymore and can resolve the quality issue. Bug: 176246647 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: I0dfd3b76ff2b0daf495ad406283f56a39982ad8f Change-Id: I26f5da65ef8344602007e180e837820c6a25f173 --- libAACdec/src/aac_ram.cpp | 4 +- libAACdec/src/aac_ram.h | 4 +- libAACdec/src/aacdecoder.cpp | 23 ++-- libAACdec/src/aacdecoder.h | 18 ++- libAACdec/src/aacdecoder_lib.cpp | 248 ++++++++++++++++++++------------------- 5 files changed, 156 insertions(+), 141 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aac_ram.cpp b/libAACdec/src/aac_ram.cpp index aa8f6a6..fac1540 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 - 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 @@ -148,7 +148,7 @@ C_ALLOC_MEM(CplxPredictionData, CCplxPredictionData, 1) /*! The buffer holds time samples for the crossfade in case of an USAC DASH IPF config change Dimension: (8) */ -C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8)) +C_ALLOC_MEM2(TimeDataFlush, PCM_DEC, TIME_DATA_FLUSH_SIZE, (8)) /* @} */ diff --git a/libAACdec/src/aac_ram.h b/libAACdec/src/aac_ram.h index b9b95b7..395b2b2 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 - 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 @@ -132,7 +132,7 @@ H_ALLOC_MEM(CplxPredictionData, CCplxPredictionData) H_ALLOC_MEM(SpectralCoeffs, FIXP_DBL) H_ALLOC_MEM(SpecScale, SHORT) -H_ALLOC_MEM(TimeDataFlush, INT_PCM) +H_ALLOC_MEM(TimeDataFlush, PCM_DEC) H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1) H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL) diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index c6d1832..c18e5e9 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -568,7 +568,7 @@ static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs, \return Error code */ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( - const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, + const PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels, const INT frameSize, const INT interleaved) { int i, ch, s1, s2; AAC_DECODER_ERROR ErrorStatus; @@ -584,7 +584,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( } for (ch = 0; ch < numChannels; ch++) { - const INT_PCM *pIn = &pTimeData[ch * s1]; + const PCM_DEC *pIn = &pTimeData[ch * s1]; for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { pTimeDataFlush[ch][i] = *pIn; pIn += s2; @@ -606,7 +606,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( \return Error code */ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade( - INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, + PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels, const INT frameSize, const INT interleaved) { int i, ch, s1, s2; AAC_DECODER_ERROR ErrorStatus; @@ -622,15 +622,15 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade( } for (ch = 0; ch < numChannels; ch++) { - INT_PCM *pIn = &pTimeData[ch * s1]; + PCM_DEC *pIn = &pTimeData[ch * s1]; for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { FIXP_SGL alpha = (FIXP_SGL)i << (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF); - FIXP_DBL time = FX_PCM2FX_DBL(*pIn); - FIXP_DBL timeFlush = FX_PCM2FX_DBL(pTimeDataFlush[ch][i]); + FIXP_DBL time = PCM_DEC2FIXP_DBL(*pIn); + FIXP_DBL timeFlush = PCM_DEC2FIXP_DBL(pTimeDataFlush[ch][i]); - *pIn = (INT_PCM)(FIXP_PCM)FX_DBL2FX_PCM( - timeFlush - fMult(timeFlush, alpha) + fMult(time, alpha)); + *pIn = FIXP_DBL2PCM_DEC(timeFlush - fMult(timeFlush, alpha) + + fMult(time, alpha)); pIn += s2; } } @@ -753,7 +753,12 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse( /* We are interested in preroll AUs if an explicit or an implicit config * change is signalized in other words if the build up status is set. */ if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) { - self->applyCrossfade |= FDKreadBit(hBs); + UCHAR applyCrossfade = FDKreadBit(hBs); + if (applyCrossfade) { + self->applyCrossfade |= AACDEC_CROSSFADE_BITMASK_PREROLL; + } else { + self->applyCrossfade &= ~AACDEC_CROSSFADE_BITMASK_PREROLL; + } FDKreadBit(hBs); /* reserved */ /* Read num preroll AU's */ *numPrerollAU = escapedValue(hBs, 2, 4, 0); diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index bd1f38f..002807f 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 - 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 @@ -172,6 +172,12 @@ enum { AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5 }; +#define AACDEC_CROSSFADE_BITMASK_OFF \ + ((UCHAR)0) /*!< No cross-fade between frames shall be applied at next \ + config change. */ +#define AACDEC_CROSSFADE_BITMASK_PREROLL \ + ((UCHAR)1 << 1) /*!< applyCrossfade is signaled in AudioPreRoll */ + typedef struct { /* Usac Extension Elements */ USAC_EXT_ELEMENT_TYPE usacExtElementType[(3)]; @@ -325,7 +331,7 @@ This structure is allocated once for each CPE. */ UINT loudnessInfoSetPosition[3]; SCHAR defaultTargetLoudness; - INT_PCM + PCM_DEC *pTimeDataFlush[((8) * 2)]; /*!< Pointer to the flushed time data which will be used for the crossfade in case of an USAC DASH IPF config change */ @@ -341,8 +347,8 @@ This structure is allocated once for each CPE. */ start position in the bitstream */ INT accessUnit; /*!< Number of the actual processed preroll accessUnit */ - UCHAR applyCrossfade; /*!< if set crossfade for seamless stream switching is - applied */ + UCHAR applyCrossfade; /*!< If any bit is set, cross-fade for seamless stream + switching is applied */ FDK_SignalDelay usacResidualDelay; /*!< Delay residual signal to compensate for eSBR delay of DMX signal in case of @@ -439,12 +445,12 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self, /* Prepare crossfade for USAC DASH IPF config change */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade( - const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, + const PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels, const INT frameSize, const INT interleaved); /* Apply crossfade for USAC DASH IPF config change */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade( - INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels, + PCM_DEC *pTimeData, PCM_DEC **pTimeDataFlush, const INT numChannels, const INT frameSize, const INT interleaved); /* Set flush and build up mode */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 6fb7bf1..5efa369 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1155,6 +1155,8 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, int applyCrossfade = 1; /* flag indicates if flushing was possible */ PCM_DEC *pTimeData2; PCM_AAC *pTimeData3; + INT pcmLimiterScale = 0; + INT interleaved = 0; if (self == NULL) { return AAC_DEC_INVALID_HANDLE; @@ -1800,8 +1802,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, } if (self->streamInfo.extAot != AOT_AAC_SLS) { - INT pcmLimiterScale = 0; - INT interleaved = 0; + interleaved = 0; interleaved |= (self->sbrEnabled) ? 1 : 0; interleaved |= (self->mpsEnableCurr) ? 1 : 0; PCMDMX_ERROR dmxErr = PCMDMX_OK; @@ -1832,145 +1833,38 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, * predictable behavior and thus maybe produce strange output. */ 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; - int blockLength = self->streamInfo.frameSize; - - /* Set actual signal parameters */ - pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels); - pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); - - if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || - (self->mpsEnableCurr)) { - pInterleaveBuffer = (PCM_LIM *)pTimeData2; - } else { - pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2; - - /* applyLimiter requests for interleaved data */ - /* Interleave ouput buffer */ - 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, - 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, pTimeData2, - self->streamInfo.frameSize * self->streamInfo.numChannels, - pcmLimiterScale); - - } else { - scaleValuesSaturate( - (INT_PCM *)self->workBufferCore2, pTimeData2, - self->streamInfo.frameSize * self->streamInfo.numChannels, - pcmLimiterScale); - /* Interleave ouput buffer */ - FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, - self->streamInfo.numChannels, - self->streamInfo.frameSize, - self->streamInfo.frameSize); - } - } - } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/ + } if (self->flags[0] & AC_USAC) { if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON && !(flags & AACDEC_CONCEAL)) { - CAacDecoder_PrepareCrossFade(pTimeData, self->pTimeDataFlush, + CAacDecoder_PrepareCrossFade(pTimeData2, self->pTimeDataFlush, self->streamInfo.numChannels, - self->streamInfo.frameSize, 1); + self->streamInfo.frameSize, interleaved); } /* prepare crossfade buffer for fade in */ - if (!applyCrossfade && self->applyCrossfade && + if (!applyCrossfade && + (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) && !(flags & AACDEC_CONCEAL)) { for (int ch = 0; ch < self->streamInfo.numChannels; ch++) { for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) { - self->pTimeDataFlush[ch][i] = 0; + self->pTimeDataFlush[ch][i] = (PCM_DEC)0; } } applyCrossfade = 1; } - if (applyCrossfade && self->applyCrossfade && + if (applyCrossfade && + (self->applyCrossfade != AACDEC_CROSSFADE_BITMASK_OFF) && !(accessUnit < numPrerollAU) && (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) { - CAacDecoder_ApplyCrossFade(pTimeData, self->pTimeDataFlush, + CAacDecoder_ApplyCrossFade(pTimeData2, self->pTimeDataFlush, self->streamInfo.numChannels, - self->streamInfo.frameSize, 1); - self->applyCrossfade = 0; + self->streamInfo.frameSize, interleaved); + self->applyCrossfade = + AACDEC_CROSSFADE_BITMASK_OFF; /* disable cross-fade between frames + at nect config change */ } } @@ -2012,6 +1906,116 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) && !(flags & AACDEC_CONCEAL))); + if (self->streamInfo.extAot != AOT_AAC_SLS) { + 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; + int blockLength = self->streamInfo.frameSize; + + /* Set actual signal parameters */ + pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels); + pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); + + if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || + (self->mpsEnableCurr)) { + pInterleaveBuffer = (PCM_LIM *)pTimeData2; + } else { + pInterleaveBuffer = (PCM_LIM *)self->workBufferCore2; + + /* applyLimiter requests for interleaved data */ + /* Interleave ouput buffer */ + 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, + 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, pTimeData2, + self->streamInfo.frameSize * self->streamInfo.numChannels, + pcmLimiterScale); + + } else { + scaleValuesSaturate( + (INT_PCM *)self->workBufferCore2, pTimeData2, + self->streamInfo.frameSize * self->streamInfo.numChannels, + pcmLimiterScale); + /* Interleave ouput buffer */ + FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData, + self->streamInfo.numChannels, self->streamInfo.frameSize, + self->streamInfo.frameSize); + } + } + } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/ + bail: /* error in renderer part occurred, ErrorStatus was set to invalid output */ -- cgit v1.2.3 From 0527875be6340013e933a26e296211999f5377cb Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 16 Mar 2021 14:42:02 +0100 Subject: Follow-up on: Improve decoder robustness by storing flags and elFlags temporarily. Bug: 186777497 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: I2aef40ef1868832cd00e4d761b060aa41b1b7efa --- libAACdec/src/aacdecoder.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index c18e5e9..7c16d2a 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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1417,11 +1417,7 @@ static void CAacDecoder_AcceptFlags(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, UINT flags, UINT *elFlags, int streamIndex, int elementOffset) { - { - FDKmemcpy( - self->elFlags, elFlags, - sizeof(*elFlags) * (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)); - } + FDKmemcpy(self->elFlags, elFlags, sizeof(self->elFlags)); self->flags[streamIndex] = flags; } @@ -1524,6 +1520,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, INT flushChannels = 0; UINT flags; + /* elFlags[(3*MAX_CHANNELS + (MAX_CHANNELS)/2 + 4 * (MAX_TRACKS) + 1] + where MAX_CHANNELS is (8*2) and MAX_TRACKS is 1 */ UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)]; if (!self) return AAC_DEC_INVALID_HANDLE; -- cgit v1.2.3 From e15d049ded8996e1b789b26d3d3c2a8fcc0128e5 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 16 Mar 2021 14:42:35 +0100 Subject: Use local variables for sbr and mps state in CAacDecoder_Init() to avoid inconsistencies in case of failing initialization. Bug: 186777497 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: Ic767aeb63cdc7d4556bc68cee0c4f7aeba05d12f --- libAACdec/src/aacdecoder.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 7c16d2a..fcf51b5 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1524,6 +1524,10 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, where MAX_CHANNELS is (8*2) and MAX_TRACKS is 1 */ UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)]; + UCHAR sbrEnabled = self->sbrEnabled; + UCHAR sbrEnabledPrev = self->sbrEnabledPrev; + UCHAR mpsEnableCurr = self->mpsEnableCurr; + if (!self) return AAC_DEC_INVALID_HANDLE; UCHAR downscaleFactor = self->downscaleFactor; @@ -1707,7 +1711,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, asc->m_sc.m_usacConfig.m_usacNumElements; } - self->mpsEnableCurr = 0; + mpsEnableCurr = 0; for (int _el = 0; _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements; _el++) { @@ -1727,7 +1731,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, self->usacStereoConfigIndex[el] = asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex; if (self->elements[el] == ID_USAC_CPE) { - self->mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0; + mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0; } } @@ -1863,7 +1867,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, self->useLdQmfTimeAlign = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; } - if (self->sbrEnabled != asc->m_sbrPresentFlag) { + if (sbrEnabled != asc->m_sbrPresentFlag) { ascChanged = 1; } } @@ -1879,13 +1883,13 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; if (asc->m_sbrPresentFlag) { - self->sbrEnabled = 1; - self->sbrEnabledPrev = 1; + sbrEnabled = 1; + sbrEnabledPrev = 1; } else { - self->sbrEnabled = 0; - self->sbrEnabledPrev = 0; + sbrEnabled = 0; + sbrEnabledPrev = 0; } - if (self->sbrEnabled && asc->m_extensionSamplingFrequency) { + if (sbrEnabled && asc->m_extensionSamplingFrequency) { if (downscaleFactor != 1 && (downscaleFactor)&1) { return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale factor */ @@ -1912,7 +1916,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; if (asc->m_aot == AOT_ER_AAC_ELD) { - self->mpsEnableCurr = 0; + mpsEnableCurr = 0; flags |= AC_ELD; flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT @@ -1923,7 +1927,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, ? AC_MPS_PRESENT : 0; if (self->mpsApplicable) { - self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; + mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign; } } flags |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; @@ -2004,7 +2008,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, /* set AC_USAC_SCFGI3 globally if any usac element uses */ switch (asc->m_aot) { case AOT_USAC: - if (self->sbrEnabled) { + if (sbrEnabled) { for (int _el = 0; _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements; _el++) { @@ -2041,7 +2045,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, */ switch (asc->m_aot) { case AOT_USAC: - if (self->sbrEnabled) { + if (sbrEnabled) { const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32}; FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0); @@ -2069,11 +2073,11 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } break; case AOT_ER_AAC_ELD: - if (self->mpsEnableCurr && + if (mpsEnableCurr && asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) { - SAC_INPUT_CONFIG sac_interface = - (self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF - : SAC_INTERFACE_TIME; + SAC_INPUT_CONFIG sac_interface = (sbrEnabled && self->hSbrDecoder) + ? SAC_INTERFACE_QMF + : SAC_INTERFACE_TIME; mpegSurroundDecoder_ConfigureQmfDomain( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface, (UINT)self->streamInfo.aacSampleRate, asc->m_aot); @@ -2428,6 +2432,9 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex, elementOffset); + self->sbrEnabled = sbrEnabled; + self->sbrEnabledPrev = sbrEnabledPrev; + self->mpsEnableCurr = mpsEnableCurr; /* Update externally visible copy of flags */ self->streamInfo.flags = self->flags[0]; -- cgit v1.2.3 From 9a9d260375879ec8b9bb36c6967bcdac626e7054 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 16 Mar 2021 14:48:20 +0100 Subject: Validate whether all PCE listed element instance tags are present in raw_data_block. Bug: 186777497 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: I299d3c11ffa65a7c09c437cd114d62b8d3013e2f --- libAACdec/src/aacdecoder.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index fcf51b5..d5f0cea 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -494,6 +494,75 @@ static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self, return error; } +static INT findElementInstanceTag( + INT elementTag, MP4_ELEMENT_ID elementId, + CAacDecoderChannelInfo **pAacDecoderChannelInfo, INT nChannels, + MP4_ELEMENT_ID *pElementIdTab, INT nElements) { + int el, chCnt = 0; + + for (el = 0; el < nElements; el++) { + switch (pElementIdTab[el]) { + case ID_CPE: + case ID_SCE: + case ID_LFE: + if ((elementTag == pAacDecoderChannelInfo[chCnt]->ElementInstanceTag) && + (elementId == pElementIdTab[el])) { + return 1; /* element instance tag found */ + } + chCnt += (pElementIdTab[el] == ID_CPE) ? 2 : 1; + break; + default: + break; + } + if (chCnt >= nChannels) break; + if (pElementIdTab[el] == ID_END) break; + } + + return 0; /* element instance tag not found */ +} + +static INT validateElementInstanceTags( + CProgramConfig *pce, CAacDecoderChannelInfo **pAacDecoderChannelInfo, + INT nChannels, MP4_ELEMENT_ID *pElementIdTab, INT nElements) { + if (nChannels >= pce->NumChannels) { + for (int el = 0; el < pce->NumFrontChannelElements; el++) { + if (!findElementInstanceTag(pce->FrontElementTagSelect[el], + pce->FrontElementIsCpe[el] ? ID_CPE : ID_SCE, + pAacDecoderChannelInfo, nChannels, + pElementIdTab, nElements)) { + return 0; /* element instance tag not in raw_data_block() */ + } + } + for (int el = 0; el < pce->NumSideChannelElements; el++) { + if (!findElementInstanceTag(pce->SideElementTagSelect[el], + pce->SideElementIsCpe[el] ? ID_CPE : ID_SCE, + pAacDecoderChannelInfo, nChannels, + pElementIdTab, nElements)) { + return 0; /* element instance tag not in raw_data_block() */ + } + } + for (int el = 0; el < pce->NumBackChannelElements; el++) { + if (!findElementInstanceTag(pce->BackElementTagSelect[el], + pce->BackElementIsCpe[el] ? ID_CPE : ID_SCE, + pAacDecoderChannelInfo, nChannels, + pElementIdTab, nElements)) { + return 0; /* element instance tag not in raw_data_block() */ + } + } + for (int el = 0; el < pce->NumLfeChannelElements; el++) { + if (!findElementInstanceTag(pce->LfeElementTagSelect[el], ID_LFE, + pAacDecoderChannelInfo, nChannels, + pElementIdTab, nElements)) { + return 0; /* element instance tag not in raw_data_block() */ + } + } + } else { + return 0; /* too less decoded audio channels */ + } + + return 1; /* all element instance tags found in raw_data_block() */ +} + /*! \brief Read Program Config Element @@ -2973,6 +3042,24 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( } /* while ( (type != ID_END) ... ) */ + if (!(self->flags[streamIndex] & + (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_BSAC | AC_LD | AC_ELD | AC_ER | + AC_SCALABLE)) && + (self->streamInfo.channelConfig == 0) && pce->isValid && + (ErrorStatus == AAC_DEC_OK) && self->frameOK && + !(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) { + /* Check whether all PCE listed element instance tags are present in + * raw_data_block() */ + if (!validateElementInstanceTags( + &self->pce, self->pAacDecoderChannelInfo, aacChannels, + channel_elements, + fMin(channel_element_count, (int)(sizeof(channel_elements) / + sizeof(*channel_elements))))) { + ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; + self->frameOK = 0; + } + } + if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) { /* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are * byteAligned with respect to the first bit */ -- cgit v1.2.3 From 167dcc380a53c0eb69cdfae97d0ba0fdc5af398d Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 25 Apr 2023 17:04:25 +0000 Subject: Remove obsolete uni drc precedence handling Bug: 241391733 Test: see bug (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4c41b05b6c60275c2a6b28918f40c218a8b818f6) Merged-In: I0ddc479626fb6a89d04bc989256ad1d8ec4275a3 Change-Id: I0ddc479626fb6a89d04bc989256ad1d8ec4275a3 --- libAACdec/src/aacdec_drc.cpp | 10 +--------- libAACdec/src/aacdec_drc.h | 5 ++--- libAACdec/src/aacdec_drc_types.h | 7 +------ libAACdec/src/aacdecoder.cpp | 6 ------ libAACdec/src/aacdecoder_lib.cpp | 31 +++++++------------------------ 5 files changed, 11 insertions(+), 48 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 760a9ba..abb9af7 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -217,7 +217,6 @@ void aacDecoder_drcInit(HANDLE_AAC_DRC self) { self->progRefLevel = pParams->targetRefLevel; self->progRefLevelPresent = 0; self->presMode = -1; - self->uniDrcPrecedence = 0; aacDecoder_drcReset(self); } @@ -353,12 +352,6 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self, self->numOutChannels = (INT)value; self->update = 1; break; - case UNIDRC_PRECEDENCE: - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->uniDrcPrecedence = (UCHAR)value; - break; default: return AAC_DEC_SET_PARAM_FAIL; } /* switch(param) */ @@ -1258,7 +1251,6 @@ static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self, /* switch on/off processing */ self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) || (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0)); - self->enable = (self->enable && !self->uniDrcPrecedence); self->prevAacNumChannels = aacNumChannels; self->update = 0; diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 2bb945d..f2c1390 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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -133,8 +133,7 @@ typedef enum { APPLY_HEAVY_COMPRESSION, DEFAULT_PRESENTATION_MODE, ENCODER_TARGET_LEVEL, - MAX_OUTPUT_CHANNELS, - UNIDRC_PRECEDENCE + MAX_OUTPUT_CHANNELS } AACDEC_DRC_PARAM; /** diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index d4393f7..c4c0794 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 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -207,11 +207,6 @@ typedef struct { position in the bitstream (only one per frame) */ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */ - - UCHAR - 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 diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index d5f0cea..ab8dc79 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -3310,12 +3310,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR)); } - /* 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( - self->hDrcInfo, UNIDRC_PRECEDENCE, - FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)); - /* Extract DRC control data and map it to channels (without bitstream delay) */ mapped = aacDecoder_drcProlog( diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 0c83191..af29366 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1689,8 +1689,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, FIXP_DBL channelGain[(8)]; int reverseInChannelMap[(8)]; int reverseOutChannelMap[(8)]; - int numDrcOutChannels = FDK_drcDec_GetParam( - self->hUniDrcDecoder, DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED); FDKmemclear(channelGain, sizeof(channelGain)); for (ch = 0; ch < (8); ch++) { reverseInChannelMap[ch] = ch; @@ -1713,17 +1711,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, drcDelay += CConcealment_GetDelay(&self->concealCommonData) * self->streamInfo.frameSize; - for (ch = 0; ch < self->streamInfo.numChannels; ch++) { - UCHAR mapValue = FDK_chMapDescr_getMapValue( - &self->mapDescr, (UCHAR)ch, self->chMapIndex); - if (mapValue < (8)) reverseInChannelMap[mapValue] = ch; - } - for (ch = 0; ch < (int)numDrcOutChannels; ch++) { - UCHAR mapValue = FDK_chMapDescr_getMapValue( - &self->mapDescr, (UCHAR)ch, numDrcOutChannels); - if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch; - } - /* The output of SBR and MPS is interleaved. Deinterleaving may be * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved * audio only. */ @@ -1758,11 +1745,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, FDK_drcDec_Preprocess(self->hUniDrcDecoder); /* apply DRC1 gain sequence */ - for (ch = 0; ch < self->streamInfo.numChannels; ch++) { - FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1, - ch, reverseInChannelMap[ch] - ch, 1, - drcWorkBuffer, self->streamInfo.frameSize); - } + FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1, + 0, 0, self->streamInfo.numChannels, + drcWorkBuffer, self->streamInfo.frameSize); /* apply downmix */ FDK_drcDec_ApplyDownmix( self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap, @@ -1770,12 +1755,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, &self->streamInfo.numChannels); /* self->streamInfo.numChannels may change here */ /* apply DRC2/3 gain sequence */ - for (ch = 0; ch < self->streamInfo.numChannels; ch++) { - FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, - DRC_DEC_DRC2_DRC3, ch, - reverseOutChannelMap[ch] - ch, 1, - drcWorkBuffer, self->streamInfo.frameSize); - } + FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, + DRC_DEC_DRC2_DRC3, 0, 0, + self->streamInfo.numChannels, drcWorkBuffer, + self->streamInfo.frameSize); if (needsDeinterleaving) { FDK_interleave( -- cgit v1.2.3 From b5b590367af9043aaf5e13b0d573aa7261945880 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 25 Apr 2023 17:09:22 +0000 Subject: Disable MPEG-D DRC for legacy AOTs Disable MPEG-D DRC metadata for legacy AOTs 2 (AAC-LC), 5 (HE-AAC), and 29 (HE-AAC v2). Bug: 241391733 Test: see bug (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2f4c595c4abd721967ecb494f5aec3f6b6dafb9e) Merged-In: Ie84badaa24bb4169adfdb1d3243525c32b44d3e9 Change-Id: Ie84badaa24bb4169adfdb1d3243525c32b44d3e9 --- libAACdec/src/aacdecoder.cpp | 39 +-------------------------------------- libAACdec/src/aacdecoder_lib.cpp | 4 ++-- 2 files changed, 3 insertions(+), 40 deletions(-) (limited to 'libAACdec/src/aacdecoder.cpp') diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index d5f0cea..ee448c3 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 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -912,43 +912,6 @@ static AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse( } *count -= readBits; } break; - case EXT_UNI_DRC: { - DRC_DEC_ERROR drcErr = DRC_DEC_OK; - DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED; - INT nBitsRemaining = FDKgetValidBits(hBs); - INT readBits; - - switch (self->streamInfo.aot) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - drcDecCodecMode = DRC_DEC_MPEG_4_AAC; - break; - default: - error = AAC_DEC_PARSE_ERROR; - goto bail; - } - - drcErr = FDK_drcDec_SetCodecMode(self->hUniDrcDecoder, drcDecCodecMode); - if (drcErr) { - error = AAC_DEC_PARSE_ERROR; - goto bail; - } - - drcErr = FDK_drcDec_ReadUniDrc(self->hUniDrcDecoder, hBs); - if (drcErr) { - error = AAC_DEC_PARSE_ERROR; - goto bail; - } - readBits = (INT)nBitsRemaining - (INT)FDKgetValidBits(hBs); - if (readBits > *count) { /* Read too much. Something went wrong! */ - error = AAC_DEC_PARSE_ERROR; - } - *count -= readBits; - /* Skip any trailing bits */ - FDKpushFor(hBs, *count); - *count = 0; - } break; case EXT_LDSAC_DATA: case EXT_SAC_DATA: /* Read MPEG Surround Extension payload */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 0c83191..c74ec1a 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1681,7 +1681,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, { if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) && - !(self->flags[0] & AC_RSV603DA)) { + (self->flags[0] & AC_USAC)) { /* Apply DRC gains*/ int ch, drcDelay = 0; int needsDeinterleaving = 0; -- cgit v1.2.3