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 | 183 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder.h | 18 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder_lib.cpp | 293 | ||||
-rw-r--r-- | libAACdec/src/channel.cpp | 6 |
9 files changed, 310 insertions, 221 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..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); @@ -1397,6 +1402,31 @@ 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(*elFlags) * (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)); + } + + self->flags[streamIndex] = flags; +} + +/*! * \brief CAacDecoder_CtrlCFGChange Set config change parameters. * * \param self [i] handle to AACDECODER structure @@ -1493,6 +1523,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 +1682,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 +1733,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; } } @@ -1791,9 +1823,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 { @@ -1838,8 +1878,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; @@ -1865,51 +1905,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)) { @@ -1960,6 +1996,10 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, if (ascChanged != 0) { *configChanged = 1; } + + CAacDecoder_AcceptFlags(self, asc, flags, elFlags, streamIndex, + elementOffset); + return err; } @@ -1988,7 +2028,7 @@ CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc, } if (usacStereoConfigIndex == 3) { - self->flags[streamIndex] |= AC_USAC_SCFGI3; + flags |= AC_USAC_SCFGI3; } } break; @@ -2069,14 +2109,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 +2216,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 +2234,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 +2246,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 +2262,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 +2399,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 +2419,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 +2428,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: @@ -3194,11 +3235,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 +3483,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 0f281eb..9d36d10 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -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); + } } } @@ -1794,8 +1813,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 +1844,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 +1917,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))) { |