aboutsummaryrefslogtreecommitdiffstats
path: root/libAACdec/src
diff options
context:
space:
mode:
Diffstat (limited to 'libAACdec/src')
-rw-r--r--libAACdec/src/aac_ram.cpp4
-rw-r--r--libAACdec/src/aac_ram.h4
-rw-r--r--libAACdec/src/aacdec_drc.cpp23
-rw-r--r--libAACdec/src/aacdec_drc.h7
-rw-r--r--libAACdec/src/aacdec_drc_types.h7
-rw-r--r--libAACdec/src/aacdec_hcrs.cpp4
-rw-r--r--libAACdec/src/aacdecoder.cpp352
-rw-r--r--libAACdec/src/aacdecoder.h18
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp333
-rw-r--r--libAACdec/src/channel.cpp6
-rw-r--r--libAACdec/src/rvlc.cpp15
-rw-r--r--libAACdec/src/usacdec_acelp.cpp4
12 files changed, 445 insertions, 332 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..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 - 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
@@ -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
@@ -204,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);
}
@@ -340,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) */
@@ -1245,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 76a44d6..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 - 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
@@ -133,13 +133,14 @@ typedef enum {
APPLY_HEAVY_COMPRESSION,
DEFAULT_PRESENTATION_MODE,
ENCODER_TARGET_LEVEL,
- MAX_OUTPUT_CHANNELS,
- UNIDRC_PRECEDENCE
+ MAX_OUTPUT_CHANNELS
} AACDEC_DRC_PARAM;
/**
* \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_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/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..ad8ce0d 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 - 2023 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);
@@ -838,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 */
@@ -1397,6 +1434,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 +1551,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 +1716,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 +1743,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 +1763,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 +1857,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 +1899,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 +1912,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 +1939,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 +2030,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 +2062,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 +2077,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 +2105,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 +2143,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 +2250,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 +2268,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 +2280,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 +2296,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 +2433,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 +2453,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 +2462,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 +3005,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 */
@@ -3177,12 +3273,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(
@@ -3194,11 +3284,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 +3532,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 bcbd46c..5319b7c 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 - 2023 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.
1. INTRODUCTION
@@ -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)));
@@ -1153,6 +1168,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;
@@ -1175,8 +1192,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);
+ }
}
}
@@ -1609,6 +1628,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);
@@ -1659,7 +1683,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;
@@ -1667,8 +1691,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;
@@ -1691,17 +1713,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. */
@@ -1736,11 +1747,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,
@@ -1748,12 +1757,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(
@@ -1796,8 +1803,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;
@@ -1828,145 +1834,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 */
}
}
@@ -2008,6 +1907,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 fbe3188..9769a07 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;