From a4695298d6142f1dfe9cabb74432c40b635d36a6 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 17 Apr 2020 15:08:34 +0200 Subject: [PATCH] Solve issue regarding config changes between Loudness-only vs. Loudness+DRC. Fix config changes from Loudness+DRC to Loudness-only configurations by clearing the DRC configuration Bug: 176246647 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: I7afef848308478c29a82b13f24ba8c2a9760fd45 --- libAACdec/src/aacdecoder_lib.cpp | 17 +++++++++--- libMpegTPDec/src/tpdec_asc.cpp | 45 +++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 90563ea..239896d 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -441,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; } @@ -455,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; } diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index a2baaaf..e46cb32 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1778,6 +1778,10 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, int numConfigExtensions; CONFIG_EXT_ID usacConfigExtType; int usacConfigExtLength; + int loudnessInfoSetIndex = + -1; /* index of loudnessInfoSet config extension. -1 if not contained. */ + int tmp_subStreamIndex = 0; + AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC; numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1; for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) { @@ -1807,10 +1811,12 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( cb->cbUniDrcData, hBs, usacConfigExtLength, 1, /* loudnessInfoSet */ - 0, loudnessInfoSetConfigExtensionPosition, AOT_USAC); + tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition, + tmp_aot); if (ErrorStatus != TRANSPORTDEC_OK) { return ErrorStatus; } + loudnessInfoSetIndex = confExtIdx; } } break; default: @@ -1826,6 +1832,17 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, FDKpushFor(hBs, usacConfigExtLength); } + if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) { + /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding + * an empty config extension */ + ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex, + 0, tmp_aot); + if (ErrorStatus != TRANSPORTDEC_OK) { + return ErrorStatus; + } + } + return ErrorStatus; } @@ -1842,6 +1859,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( int channelElementIdx = 0; /* index for elements which contain audio channels (sce, cpe, lfe) */ SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0}; + int uniDrcElement = + -1; /* index of uniDrc extension element. -1 if not contained. */ numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1; usc->m_usacNumElements = numberOfElements; @@ -2017,6 +2036,10 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( case ID_USAC_EXT: ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0, asc->m_samplesPerFrame, 0, asc->m_aot); + if (usc->element[i].extElement.usacExtElementType == + ID_EXT_ELE_UNI_DRC) { + uniDrcElement = i; + } if (ErrorStatus) { return ErrorStatus; @@ -2045,6 +2068,18 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( } } + if (uniDrcElement == -1 && cb->cbUniDrc != NULL) { + /* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an + * empty extension element */ + int subStreamIndex = 0; + ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0, + asc->m_aot); + if (ErrorStatus != TRANSPORTDEC_OK) { + return ErrorStatus; + } + } + return ErrorStatus; } @@ -2131,6 +2166,14 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, if (err != TRANSPORTDEC_OK) { return err; } + } else if (cb->cbUniDrc != NULL) { + /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding + * an empty config extension */ + err = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot); + if (err != TRANSPORTDEC_OK) { + return err; + } } /* sanity check whether number of channels signaled in UsacDecoderConfig()