diff options
Diffstat (limited to 'libAACdec/src')
-rw-r--r-- | libAACdec/src/aac_ram.cpp | 4 | ||||
-rw-r--r-- | libAACdec/src/aac_ram.h | 4 | ||||
-rw-r--r-- | libAACdec/src/aacdec_drc.cpp | 15 | ||||
-rw-r--r-- | libAACdec/src/aacdec_drc.h | 4 | ||||
-rw-r--r-- | libAACdec/src/aacdec_hcrs.cpp | 4 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder.cpp | 309 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder.h | 18 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder_lib.cpp | 302 | ||||
-rw-r--r-- | libAACdec/src/channel.cpp | 6 | ||||
-rw-r--r-- | libAACdec/src/rvlc.cpp | 15 | ||||
-rw-r--r-- | libAACdec/src/usacdec_acelp.cpp | 4 |
11 files changed, 436 insertions, 249 deletions
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/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index b6f5b49..760a9ba 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 - 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 @@ -150,6 +150,19 @@ static INT convert_drcParam(FIXP_DBL param_dbl) { } /*! +\brief Disable DRC + +\self Handle of DRC info + +\return none +*/ +void aacDecoder_drcDisable(HANDLE_AAC_DRC self) { + self->enable = 0; + self->applyExtGain = 0; + self->progRefLevelPresent = 0; +} + +/*! \brief Reset DRC information \self Handle of DRC info diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 76a44d6..2bb945d 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 - 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 @@ -140,6 +140,8 @@ typedef enum { /** * \brief DRC module interface functions */ +void aacDecoder_drcDisable(HANDLE_AAC_DRC self); + void aacDecoder_drcReset(HANDLE_AAC_DRC self); void aacDecoder_drcInit(HANDLE_AAC_DRC self); diff --git a/libAACdec/src/aacdec_hcrs.cpp b/libAACdec/src/aacdec_hcrs.cpp index 44b32a5..5e3f9ac 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 - 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 @@ -173,7 +173,9 @@ void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) { pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT; /* Process sets subsequently */ + numSet = fMin(numSet, (UCHAR)MAX_HCR_SETS); for (currentSet = 1; currentSet < numSet; currentSet++) { + /* step 1 */ numCodeword -= *pNumSegment; /* number of remaining non PCWs [for all sets] */ diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 965631b..d5f0cea 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 @@ -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 @@ -568,7 +637,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 +653,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 +675,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 +691,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 +822,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); @@ -1397,6 +1471,27 @@ static void CAacDecoder_DeInit(HANDLE_AACDECODER self, } /*! + * \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(self->elFlags)); + + self->flags[streamIndex] = flags; +} + +/*! * \brief CAacDecoder_CtrlCFGChange Set config change parameters. * * \param self [i] handle to AACDECODER structure @@ -1493,6 +1588,15 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, const int streamIndex = 0; 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)]; + + UCHAR sbrEnabled = self->sbrEnabled; + UCHAR sbrEnabledPrev = self->sbrEnabledPrev; + UCHAR mpsEnableCurr = self->mpsEnableCurr; + if (!self) return AAC_DEC_INVALID_HANDLE; UCHAR downscaleFactor = self->downscaleFactor; @@ -1649,8 +1753,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)) { @@ -1676,7 +1780,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++) { @@ -1696,35 +1800,34 @@ 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; } } - 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; } } @@ -1791,9 +1894,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 { @@ -1825,7 +1936,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; } } @@ -1838,16 +1949,16 @@ 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; + 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 */ @@ -1865,51 +1976,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; + mpsEnableCurr = 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; + 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)) { @@ -1960,13 +2067,17 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (ascChanged != 0) { *configChanged = 1; } + + CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex, + elementOffset); + return err; } /* 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++) { @@ -1988,7 +2099,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } if (usacStereoConfigIndex == 3) { - self->flags[streamIndex] |= AC_USAC_SCFGI3; + flags |= AC_USAC_SCFGI3; } } break; @@ -2003,7 +2114,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); @@ -2031,11 +2142,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); @@ -2069,14 +2180,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; @@ -2176,15 +2287,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, @@ -2195,7 +2305,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) { @@ -2207,7 +2317,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; @@ -2223,7 +2333,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(); @@ -2360,9 +2470,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; @@ -2383,8 +2490,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); } } @@ -2393,6 +2499,15 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f)); } + 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]; + return err; bail: @@ -2927,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 */ @@ -3194,11 +3327,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 +3575,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 */ 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 f5ce7e0..0c83191 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 - 2019 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 @@ -122,7 +122,7 @@ amm-info@iis.fraunhofer.de #define AACDECODER_LIB_VL1 2 #define AACDECODER_LIB_VL2 0 #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 @@ -385,21 +385,19 @@ static INT aacDecoder_SbrCallback( return errTp; } -static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, - const AUDIO_OBJECT_TYPE coreCodec, - const INT samplingRate, const INT frameSize, - const INT stereoConfigIndex, - const INT coreSbrFrameLengthIndex, - const INT configBytes, const UCHAR configMode, - UCHAR *configChanged) { +static INT aacDecoder_SscCallback( + void *handle, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingRate, const INT frameSize, const INT numChannels, + const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex, + const INT configBytes, const UCHAR configMode, UCHAR *configChanged) { SACDEC_ERROR err; TRANSPORTDEC_ERROR errTp; HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; err = mpegSurroundDecoder_Config( (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec, - samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex, - configBytes, configMode, configChanged); + samplingRate, frameSize, numChannels, stereoConfigIndex, + coreSbrFrameLengthIndex, configBytes, configMode, configChanged); switch (err) { case MPS_UNSUPPORTED_CONFIG: @@ -443,12 +441,23 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, TRANSPORTDEC_ERROR errTp; HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED; + UCHAR dummyBuffer[4] = {0}; + FDK_BITSTREAM dummyBs; + HANDLE_FDK_BITSTREAM hReadBs; if (subStreamIndex != 0) { return TRANSPORTDEC_OK; } - else if (aot == AOT_USAC) { + if (hBs == NULL) { + /* use dummy zero payload to clear memory */ + hReadBs = &dummyBs; + FDKinitBitStream(hReadBs, dummyBuffer, 4, 24); + } else { + hReadBs = hBs; + } + + if (aot == AOT_USAC) { drcDecCodecMode = DRC_DEC_MPEG_D_USAC; } @@ -457,10 +466,10 @@ static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, if (payloadType == 0) /* uniDrcConfig */ { - err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs); + err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hReadBs); } else /* loudnessInfoSet */ { - err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs); + err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hReadBs); hAacDecoder->loudnessInfoSetPosition[1] = payloadStart; hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength; } @@ -822,6 +831,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam( case AAC_DRC_ATTENUATION_FACTOR: /* DRC compression factor (where 0 is no and 127 is max compression) */ + if ((value < 0) || (value > 127)) { + return AAC_DEC_SET_PARAM_FAIL; + } errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value); uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_COMPRESS, value * (FL2FXCONST_DBL(0.5f / 127.0f))); @@ -829,6 +841,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam( case AAC_DRC_BOOST_FACTOR: /* DRC boost factor (where 0 is no and 127 is max boost) */ + if ((value < 0) || (value > 127)) { + return AAC_DEC_SET_PARAM_FAIL; + } errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value); uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_BOOST, value * (FL2FXCONST_DBL(0.5f / 127.0f))); @@ -1151,6 +1166,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; @@ -1173,8 +1190,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, aacDecoder_FreeMemCallback(self, &asc); self->streamInfo.numChannels = 0; /* 3) restore AudioSpecificConfig */ - transportDec_OutOfBandConfig(self->hInput, asc.config, - (asc.configBits + 7) >> 3, 0); + if (asc.configBits <= (TP_USAC_MAX_CONFIG_LEN << 3)) { + transportDec_OutOfBandConfig(self->hInput, asc.config, + (asc.configBits + 7) >> 3, 0); + } } } @@ -1607,6 +1626,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, /* set params */ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, self->sbrParams.bsDelay); + sbrDecoder_SetParam( + self->hSbrDecoder, SBR_FLUSH_DATA, + (flags & AACDEC_FLUSH) | + ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH + : 0)); sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); @@ -1794,8 +1818,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; @@ -1826,145 +1849,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 */ } } @@ -2006,6 +1922,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 */ diff --git a/libAACdec/src/channel.cpp b/libAACdec/src/channel.cpp index a020034..7e62bfb 100644 --- a/libAACdec/src/channel.cpp +++ b/libAACdec/src/channel.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 @@ -265,7 +265,9 @@ void CChannelElement_Decode( stereo prediction since scaling has already been carried out. */ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste); - if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) || + if (!(CP_active && (max_sfb_ste == noSfbs)) || + !(CP_active && + !(pAacDecoderChannelInfo[ch]->pDynData->TnsData.Active)) || ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr == 0))) { diff --git a/libAACdec/src/rvlc.cpp b/libAACdec/src/rvlc.cpp index b7a9be1..0b80364 100644 --- a/libAACdec/src/rvlc.cpp +++ b/libAACdec/src/rvlc.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 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -628,7 +628,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd; SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc; - UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc); + UCHAR escEscCnt = pRvlc->numDecodedEscapeWordsEsc; UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd); pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd); @@ -636,7 +636,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, *pEscBwdCnt = 0; pRvlc->direction = BWD; - pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */ + pScfEsc += escEscCnt - 1; /* set pScfEsc to last entry */ pRvlc->firstScf = 0; pRvlc->firstNrg = 0; pRvlc->firstIs = 0; @@ -651,7 +651,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, } dpcm -= TABLE_OFFSET; if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { + if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) { pRvlc->conceal_min = bnds; return; } else { @@ -694,7 +694,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, } dpcm -= TABLE_OFFSET; if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { + if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) { pScfBwd[bnds] = position; pRvlc->conceal_min = fMax(0, bnds - offset); return; @@ -731,7 +731,8 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, } dpcm -= TABLE_OFFSET; if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { + if ((pRvlc->length_of_rvlc_escapes) || + (*pEscBwdCnt >= escEscCnt)) { pScfBwd[bnds] = noisenrg; pRvlc->conceal_min = fMax(0, bnds - offset); return; @@ -762,7 +763,7 @@ static void rvlcDecodeBackward(CErRvlcInfo *pRvlc, } dpcm -= TABLE_OFFSET; if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { + if ((pRvlc->length_of_rvlc_escapes) || (*pEscBwdCnt >= escEscCnt)) { pScfBwd[bnds] = factor; pRvlc->conceal_min = fMax(0, bnds - offset); return; diff --git a/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp index a8dadc0..ca1a6a2 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 - 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 @@ -719,7 +719,7 @@ static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX, UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac; if ((int)*pold_T0 >= PIT_MAX) { - *pold_T0 = (UCHAR)(PIT_MAX - 5); + *pold_T0 = (USHORT)(PIT_MAX - 5); } *pT0 = (int)*pold_T0; *pT0_frac = (int)*pold_T0_frac; |