From fcc3c65ec545ebaf4cbb78d529b47e6d6b5d4ce9 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:55:59 +0200 Subject: Evaluate and return StoreConfigAsBitstream() error state. Bug: 176246647 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I025e943e91f9be1a5259a761a8ff88defd8babea --- libMpegTPDec/src/tpdec_asc.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'libMpegTPDec/src') diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index 82f840e..ffe85c1 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.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 @@ -1996,9 +1996,11 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */ INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits; - StoreConfigAsBitstream(hBs, configSize_bits, - asc->m_sc.m_usacConfig.UsacConfig, - TP_USAC_MAX_CONFIG_LEN); + if (StoreConfigAsBitstream(hBs, configSize_bits, + asc->m_sc.m_usacConfig.UsacConfig, + TP_USAC_MAX_CONFIG_LEN)) { + return TRANSPORTDEC_PARSE_ERROR; + } asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits); return err; @@ -2300,8 +2302,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( /* Copy config() to asc->config[] buffer. */ if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) { INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor; - StoreConfigAsBitstream(bs, configSize_bits, self->config, - TP_USAC_MAX_CONFIG_LEN); + if (StoreConfigAsBitstream(bs, configSize_bits, self->config, + TP_USAC_MAX_CONFIG_LEN)) { + return TRANSPORTDEC_PARSE_ERROR; + } self->configBits = fAbs(configSize_bits); } -- cgit v1.2.3 From 5eb9ed1b1fe94e8bf94bba4aa305b61db19b48c5 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:58:17 +0200 Subject: Check number of core channels and SAC decoder input channels to avoid a channel mismatch. Bug: 176246647 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: Ib8b6973e9c29e13b8ef33d7736be2b977928face --- libAACdec/src/aacdecoder_lib.cpp | 16 +++++++--------- libAACenc/src/aacenc_lib.cpp | 4 ++-- libMpegTPDec/include/tp_data.h | 4 ++-- libMpegTPDec/src/tpdec_asc.cpp | 8 ++++++-- libMpegTPEnc/include/tp_data.h | 4 ++-- libMpegTPEnc/src/tpenc_asc.cpp | 6 +++--- libSACdec/include/sac_dec_lib.h | 6 +++--- libSACdec/src/sac_dec.cpp | 14 ++++++++------ libSACdec/src/sac_dec_lib.cpp | 21 ++++++++++++++++++--- 9 files changed, 51 insertions(+), 32 deletions(-) (limited to 'libMpegTPDec/src') diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 0c13304..6fb7bf1 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: diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index c3977f3..e39e62e 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -1235,7 +1235,7 @@ static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs, INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec, const INT samplingRate, const INT frameSize, - const INT stereoConfigIndex, + const INT numChannels, const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex, const INT configBytes, const UCHAR configMode, UCHAR *configChanged) { HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; diff --git a/libMpegTPDec/include/tp_data.h b/libMpegTPDec/include/tp_data.h index b015332..b63087a 100644 --- a/libMpegTPDec/include/tp_data.h +++ b/libMpegTPDec/include/tp_data.h @@ -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 @@ -368,7 +368,7 @@ typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *); typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, const AUDIO_OBJECT_TYPE coreCodec, const INT samplingRate, const INT frameSize, - const INT stereoConfigIndex, + const INT numChannels, const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex, const INT configBytes, const UCHAR configMode, UCHAR *configChanged); diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index ffe85c1..5a89a4d 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1415,7 +1415,7 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, cb->cbSscData, hBs, asc->m_aot, asc->m_samplingFrequency << esc->m_sbrSamplingRate, asc->m_samplesPerFrame << esc->m_sbrSamplingRate, - 1, /* stereoConfigIndex */ + asc->m_channelConfiguration, 1, /* stereoConfigIndex */ -1, /* nTimeSlots: read from bitstream */ eldExtLen, asc->configMode, &asc->SacConfigChanged); if (ErrorStatus != TRANSPORTDEC_OK) { @@ -1827,6 +1827,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( /* Mps212Config() ISO/IEC FDIS 23003-3 */ if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency, samplesPerFrame, + 1, /* only downmix channels (residual channels are + not counted) */ usc->element[i].m_stereoConfigIndex, usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ @@ -2221,7 +2223,7 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( case AOT_MPEGS: if (cb->cbSsc != NULL) { if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, - self->m_samplesPerFrame, 1, + self->m_samplesPerFrame, self->m_channelConfiguration, 1, -1, /* nTimeSlots: read from bitstream */ 0, /* don't know the length */ self->configMode, &self->SacConfigChanged)) { @@ -2419,6 +2421,8 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig( cb->cbSscData, hBs, AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */ asc->m_extensionSamplingFrequency, samplesPerFrame, + 1, /* only downmix channels (residual channels are not + counted) */ usc->element[elemIdx].m_stereoConfigIndex, usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ asc->configMode, &asc->SacConfigChanged); diff --git a/libMpegTPEnc/include/tp_data.h b/libMpegTPEnc/include/tp_data.h index 00de356..464c485 100644 --- a/libMpegTPEnc/include/tp_data.h +++ b/libMpegTPEnc/include/tp_data.h @@ -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 @@ -368,7 +368,7 @@ typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *); typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, const AUDIO_OBJECT_TYPE coreCodec, const INT samplingRate, const INT frameSize, - const INT stereoConfigIndex, + const INT numChannels, const INT stereoConfigIndex, const INT coreSbrFrameLengthIndex, const INT configBytes, const UCHAR configMode, UCHAR *configChanged); diff --git a/libMpegTPEnc/src/tpenc_asc.cpp b/libMpegTPEnc/src/tpenc_asc.cpp index 0b484a0..9591ba8 100644 --- a/libMpegTPEnc/src/tpenc_asc.cpp +++ b/libMpegTPEnc/src/tpenc_asc.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 @@ -795,7 +795,7 @@ static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs, const INT eldExtLen = (cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0, - 0, 0, 0, 0, NULL) + + 0, 0, 0, 0, 0, NULL) + 7) >> 3; INT cnt = eldExtLen; @@ -818,7 +818,7 @@ static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs, } cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0, - 0, 0, NULL); + 0, 0, 0, NULL); } if (config->downscaleSamplingRate != 0 && diff --git a/libSACdec/include/sac_dec_lib.h b/libSACdec/include/sac_dec_lib.h index 1827504..5aad4e0 100644 --- a/libSACdec/include/sac_dec_lib.h +++ b/libSACdec/include/sac_dec_lib.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 @@ -316,8 +316,8 @@ SACDEC_ERROR mpegSurroundDecoder_Init( SACDEC_ERROR mpegSurroundDecoder_Config( CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize, - INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes, - const UCHAR configMode, UCHAR *configChanged); + INT numChannels, INT stereoConfigIndex, INT coreSbrFrameLengthIndex, + INT configBytes, const UCHAR configMode, UCHAR *configChanged); SACDEC_ERROR mpegSurroundDecoder_ConfigureQmfDomain( diff --git a/libSACdec/src/sac_dec.cpp b/libSACdec/src/sac_dec.cpp index f0d24fb..a26e251 100644 --- a/libSACdec/src/sac_dec.cpp +++ b/libSACdec/src/sac_dec.cpp @@ -1209,15 +1209,17 @@ static SACDEC_ERROR SpatialDecApplyParameterSets( self->bShareDelayWithSBR = 0; /* We got no hybrid delay */ else self->bShareDelayWithSBR = 1; - SpatialDecFeedQMF(self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode, - self->qmfInputReal__FDK, self->qmfInputImag__FDK, - self->numInputChannels); + SpatialDecFeedQMF( + self, qmfInDataReal, qmfInDataImag, ts_io, bypassMode, + self->qmfInputReal__FDK, self->qmfInputImag__FDK, + (bypassMode) ? numInputChannels : self->numInputChannels); break; case INPUTMODE_TIME: self->bShareDelayWithSBR = 0; - SpatialDecQMFAnalysis(self, inData, ts_io, bypassMode, - self->qmfInputReal__FDK, self->qmfInputImag__FDK, - self->numInputChannels); + SpatialDecQMFAnalysis( + self, inData, ts_io, bypassMode, self->qmfInputReal__FDK, + self->qmfInputImag__FDK, + (bypassMode) ? numInputChannels : self->numInputChannels); break; default: break; diff --git a/libSACdec/src/sac_dec_lib.cpp b/libSACdec/src/sac_dec_lib.cpp index 57446f8..d30131f 100644 --- a/libSACdec/src/sac_dec_lib.cpp +++ b/libSACdec/src/sac_dec_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 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -700,9 +700,10 @@ bail: SACDEC_ERROR mpegSurroundDecoder_Config( CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize, - INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes, - const UCHAR configMode, UCHAR *configChanged) { + INT numChannels, INT stereoConfigIndex, INT coreSbrFrameLengthIndex, + INT configBytes, const UCHAR configMode, UCHAR *configChanged) { SACDEC_ERROR err = MPS_OK; + INT nInputChannels; SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; SPATIAL_SPECIFIC_CONFIG *pSsc = &pMpegSurroundDecoder->spatialSpecificConfigBackup; @@ -716,12 +717,18 @@ SACDEC_ERROR mpegSurroundDecoder_Config( err = SpatialDecParseMps212Config( hBs, &spatialSpecificConfig, samplingRate, coreCodec, stereoConfigIndex, coreSbrFrameLengthIndex); + nInputChannels = spatialSpecificConfig.nInputChannels; pSsc = &spatialSpecificConfig; } else { err = SpatialDecParseMps212Config( hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, samplingRate, coreCodec, stereoConfigIndex, coreSbrFrameLengthIndex); + nInputChannels = + pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels; + } + if ((err == MPS_OK) && (numChannels != nInputChannels)) { + err = MPS_PARSE_ERROR; } break; case AOT_ER_AAC_ELD: @@ -731,11 +738,19 @@ SACDEC_ERROR mpegSurroundDecoder_Config( * into temporarily allocated structure */ err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig, configBytes, coreCodec); + nInputChannels = spatialSpecificConfig.nInputChannels; pSsc = &spatialSpecificConfig; } else { err = SpatialDecParseSpecificConfig( hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, configBytes, coreCodec); + nInputChannels = + pMpegSurroundDecoder->spatialSpecificConfigBackup.nInputChannels; + } + /* check number of channels for channel_configuration > 0 */ + if ((err == MPS_OK) && (numChannels > 0) && + (numChannels != nInputChannels)) { + err = MPS_PARSE_ERROR; } break; default: -- cgit v1.2.3 From 36dd057c406534e077c37d5121633dd9ef6ded68 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 9 Apr 2020 17:58:42 +0200 Subject: Introduce additional sanity checks to validate program config element. Bug: 176246647 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: I3e04480ab5a74da1a9d09af5da95afb2000b3117 --- libMpegTPDec/src/tpdec_asc.cpp | 167 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 156 insertions(+), 11 deletions(-) (limited to 'libMpegTPDec/src') diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index 5a89a4d..a2baaaf 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -266,11 +266,118 @@ static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce, return (err); } +/** + * \brief Sanity checks for program config element. + * Check order of elements according to ISO/IEC 13818-7:2003(E), + * chapter 8.5.1 + * + * \param pPce pointer to program config element. + * + * \return 0 if successful, otherwise 1. + */ +static int CProgramConfig_Check(CProgramConfig *pPce) { + INT i; + INT err = 0; + INT numBackChannels[3] = {0}; + INT numSideChannels[3] = {0}; + INT numFrontChannels[3] = {0}; + UCHAR *pCpeFront = pPce->FrontElementIsCpe; + UCHAR *pCpeSide = pPce->SideElementIsCpe; + UCHAR *pCpeBack = pPce->BackElementIsCpe; + UCHAR *pHeight; + + pHeight = pPce->BackElementHeightInfo; + for (i = 0; i < pPce->NumBackChannelElements; i++) { + numBackChannels[*pHeight] += pPce->BackElementIsCpe[i] ? 2 : 1; + pHeight++; + } + pHeight = pPce->SideElementHeightInfo; + for (i = 0; i < pPce->NumSideChannelElements; i++) { + numSideChannels[*pHeight] += pPce->SideElementIsCpe[i] ? 2 : 1; + pHeight++; + } + pHeight = pPce->FrontElementHeightInfo; + for (i = 0; i < pPce->NumFrontChannelElements; i++) { + numFrontChannels[*pHeight] += pPce->FrontElementIsCpe[i] ? 2 : 1; + pHeight++; + } + + /* 0 = normal height channels, 1 = top height channels, 2 = bottom height + * channels */ + for (i = 0; i < 3; i++) { + /* if number of channels is odd => first element must be a SCE (front center + * channel) */ + if (numFrontChannels[i] & 1) { + if (*pCpeFront++ == ID_CPE) { + err = 1; + goto bail; + } + numFrontChannels[i]--; + } + while (numFrontChannels[i] > 0) { + /* must be CPE or paired SCE */ + if (*pCpeFront++ == ID_SCE) { + if (*pCpeFront++ == ID_CPE) { + err = 1; + goto bail; + } + } + numFrontChannels[i] -= 2; + }; + + /* in case that a top center surround channel (Ts) is transmitted the number + * of channels can be odd */ + if (i != 1) { + /* number of channels must be even */ + if (numSideChannels[i] & 1) { + err = 1; + goto bail; + } + while (numSideChannels[i] > 0) { + /* must be CPE or paired SCE */ + if (*pCpeSide++ == ID_SCE) { + if (*pCpeSide++ == ID_CPE) { + err = 1; + goto bail; + } + } + numSideChannels[i] -= 2; + }; + } + + while (numBackChannels[i] > 1) { + /* must be CPE or paired SCE */ + if (*pCpeBack++ == ID_SCE) { + if (*pCpeBack++ == ID_CPE) { + err = 1; + goto bail; + } + } + numBackChannels[i] -= 2; + }; + /* if number of channels is odd => last element must be a SCE (back center + * channel) */ + if (numBackChannels[i]) { + if (*pCpeBack++ == ID_CPE) { + err = 1; + goto bail; + } + } + } + +bail: + + return err; +} + void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, UINT alignmentAnchor) { - int i, err = 0; + int i; int commentBytes; + UCHAR tag, isCpe; + UCHAR checkElementTagSelect[3][PC_FSB_CHANNELS_MAX] = {{0}}; + pPce->isValid = 1; pPce->NumEffectiveChannels = 0; pPce->NumChannels = 0; pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4); @@ -297,28 +404,60 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, } for (i = 0; i < pPce->NumFrontChannelElements; i++) { - pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->FrontElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->FrontElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumSideChannelElements; i++) { - pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->SideElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->SideElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumBackChannelElements; i++) { - pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->BackElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->BackElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } pPce->NumEffectiveChannels = pPce->NumChannels; for (i = 0; i < pPce->NumLfeChannelElements; i++) { - pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->LfeElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[2][tag] == 0) { + checkElementTagSelect[2][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumAssocDataElements; i++) { @@ -336,7 +475,15 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, commentBytes = pPce->CommentFieldBytes; /* Search for height info extension and read it if available */ - err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor); + if (CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor)) { + pPce->isValid = 0; + } + + /* Check order of elements according to ISO / IEC 13818 - 7:2003(E), + * chapter 8.5.1 */ + if (CProgramConfig_Check(pPce)) { + pPce->isValid = 0; + } for (i = 0; i < commentBytes; i++) { UCHAR text; @@ -347,8 +494,6 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, pPce->Comment[i] = text; } } - - pPce->isValid = (err) ? 0 : 1; } /* -- cgit v1.2.3 From af0c91e7b88ebe1a2b9a2dc272a7ba4faa92f478 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 17 Apr 2020 15:08:34 +0200 Subject: 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(-) (limited to 'libMpegTPDec/src') diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 6fb7bf1..47d204b 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() -- cgit v1.2.3 From 14db264786fdd4fa837662c07f6a63458ce3de48 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 16 Mar 2021 14:47:58 +0100 Subject: Avoid integer overflows in CLatmDemux_ReadAuChunkLengthInfo() and FDK_get32() to prevent endless loop. Bug: 186777497 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: Icaedd341f4602882f72ff5e7be71d99ce08f3bec --- libMpegTPDec/src/tpdec_latm.cpp | 41 +++++++++++++++++++++-------------------- libMpegTPDec/src/tpdec_latm.h | 4 +--- 2 files changed, 22 insertions(+), 23 deletions(-) (limited to 'libMpegTPDec/src') diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index 3b71db8..c32be54 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -591,6 +591,18 @@ bail: return (ErrorStatus); } +static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { + int len = 0, tmp = 255; + int validBytes = (int)FDKgetValidBits(bs) >> 3; + + while (tmp == 255 && validBytes-- > 0) { + tmp = (int)FDKreadBits(bs, 8); + len += tmp; + } + + return ((tmp == 255) ? -1 : (len << 3)); +} + TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; @@ -602,11 +614,17 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; + int auChunkLengthInfo = 0; switch (p_linfo->m_frameLengthType) { case 0: - p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); - totalPayloadBits += p_linfo->m_frameLengthInBits; + auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs); + if (auChunkLengthInfo >= 0) { + p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo; + totalPayloadBits += p_linfo->m_frameLengthInBits; + } else { + return TRANSPORTDEC_PARSE_ERROR; + } break; case 3: case 5: @@ -627,23 +645,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, return (ErrorStatus); } -int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { - UCHAR endFlag; - int len = 0; - - do { - UCHAR tmp = (UCHAR)FDKreadBits(bs, 8); - endFlag = (tmp < 255); - - len += tmp; - - } while (endFlag == 0); - - len <<= 3; /* convert from bytes to bits */ - - return len; -} - UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, const UINT layer) { UINT nFrameLenBits = 0; diff --git a/libMpegTPDec/src/tpdec_latm.h b/libMpegTPDec/src/tpdec_latm.h index 6af553d..8b8c971 100644 --- a/libMpegTPDec/src/tpdec_latm.h +++ b/libMpegTPDec/src/tpdec_latm.h @@ -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 @@ -151,8 +151,6 @@ typedef struct { AudioPreRoll */ } CLatmDemux; -int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs); - TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, CSTpCallBacks *pTpDecCallbacks, -- cgit v1.2.3 From 1f5fac767af24805fbd9e25bd5d6a719e8a1e3cc Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 17 Apr 2020 15:13:35 +0200 Subject: Adjust data types to prevent load of invalid value Adjust usacExtElementType data type to prevent load of invalid value in extElementConfig(). Adjust usacConfigExtType data type to prevent load of invalid value in configExtension(). Bug: 186706541 Test: atest android.media.cts.DecoderTestAacFormat android.media.cts.DecoderTestXheAac android.media.cts.DecoderTestAacDrc Change-Id: Ide15daa73c084c4a2cfc9d0f36bd7666fa6bac7a --- libMpegTPDec/src/tpdec_asc.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'libMpegTPDec/src') diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index e46cb32..8f77017 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1694,8 +1694,7 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, const AUDIO_OBJECT_TYPE aot) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; - USAC_EXT_ELEMENT_TYPE usacExtElementType = - (USAC_EXT_ELEMENT_TYPE)escapedValue(hBs, 4, 8, 16); + UINT usacExtElementType = escapedValue(hBs, 4, 8, 16); /* recurve extension elements which are invalid for USAC */ if (aot == AOT_USAC) { @@ -1712,7 +1711,6 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, } } - extElement->usacExtElementType = usacExtElementType; int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16); extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength; INT bsAnchor; @@ -1746,8 +1744,10 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, } } break; default: + usacExtElementType = ID_EXT_ELE_UNKNOWN; break; } + extElement->usacExtElementType = (USAC_EXT_ELEMENT_TYPE)usacExtElementType; /* Adjust bit stream position. This is required because of byte alignment and * unhandled extensions. */ @@ -1776,7 +1776,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; int numConfigExtensions; - CONFIG_EXT_ID usacConfigExtType; + UINT usacConfigExtType; int usacConfigExtLength; int loudnessInfoSetIndex = -1; /* index of loudnessInfoSet config extension. -1 if not contained. */ @@ -1787,7 +1787,7 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) { INT nbits; int loudnessInfoSetConfigExtensionPosition = FDKgetValidBits(hBs); - usacConfigExtType = (CONFIG_EXT_ID)escapedValue(hBs, 4, 8, 16); + usacConfigExtType = escapedValue(hBs, 4, 8, 16); usacConfigExtLength = (int)escapedValue(hBs, 4, 8, 16); /* Start bit position of config extension */ -- cgit v1.2.3