Add AOT specific number of qmf bands sanity check in SpatialSpecificConfig()

Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc

Change-Id: Ic106c4371c5ac17cb832c7d9db042bcc9d1e7a09
This commit is contained in:
Fraunhofer IIS FDK 2018-12-20 15:52:46 +01:00 committed by Jean-Michel Trivi
parent 7884aefc84
commit 5c54fa5387
9 changed files with 144 additions and 50 deletions

View File

@ -387,7 +387,7 @@ static INT aacDecoder_SbrCallback(
static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex, const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT coreSbrFrameLengthIndex,
const INT configBytes, const UCHAR configMode, const INT configBytes, const UCHAR configMode,
@ -398,8 +398,8 @@ static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
err = mpegSurroundDecoder_Config( err = mpegSurroundDecoder_Config(
(CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec, (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
samplingRate, stereoConfigIndex, coreSbrFrameLengthIndex, configBytes, samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex,
configMode, configChanged); configBytes, configMode, configChanged);
switch (err) { switch (err) {
case MPS_UNSUPPORTED_CONFIG: case MPS_UNSUPPORTED_CONFIG:

View File

@ -1216,7 +1216,8 @@ static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT stereoConfigIndex, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged) { const UCHAR configMode, UCHAR *configChanged) {
HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;

View File

@ -367,7 +367,8 @@ typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *); typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT stereoConfigIndex, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged); const UCHAR configMode, UCHAR *configChanged);

View File

@ -1413,7 +1413,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
esc->m_useLdQmfTimeAlign = 1; esc->m_useLdQmfTimeAlign = 1;
if (cb->cbSsc != NULL) { if (cb->cbSsc != NULL) {
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc( ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency, cb->cbSscData, hBs, asc->m_aot,
asc->m_samplingFrequency << esc->m_sbrSamplingRate,
asc->m_samplesPerFrame << esc->m_sbrSamplingRate,
1, /* stereoConfigIndex */ 1, /* stereoConfigIndex */
-1, /* nTimeSlots: read from bitstream */ -1, /* nTimeSlots: read from bitstream */
eldExtLen, asc->configMode, &asc->SacConfigChanged); eldExtLen, asc->configMode, &asc->SacConfigChanged);
@ -1812,9 +1814,16 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
if (usc->element[i].m_stereoConfigIndex > 0) { if (usc->element[i].m_stereoConfigIndex > 0) {
if (cb->cbSsc != NULL) { if (cb->cbSsc != NULL) {
int samplesPerFrame = asc->m_samplesPerFrame;
if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
if (usc->m_sbrRatioIndex == 2)
samplesPerFrame = (samplesPerFrame * 8) / 3;
if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
/* Mps212Config() ISO/IEC FDIS 23003-3 */ /* Mps212Config() ISO/IEC FDIS 23003-3 */
if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot, if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
asc->m_extensionSamplingFrequency, asc->m_extensionSamplingFrequency, samplesPerFrame,
usc->element[i].m_stereoConfigIndex, usc->element[i].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex, usc->m_coreSbrFrameLengthIndex,
0, /* don't know the length */ 0, /* don't know the length */
@ -2181,7 +2190,8 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
case AOT_MPEGS: case AOT_MPEGS:
if (cb->cbSsc != NULL) { if (cb->cbSsc != NULL) {
if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency,
1, -1, /* nTimeSlots: read from bitstream */ self->m_samplesPerFrame, 1,
-1, /* nTimeSlots: read from bitstream */
0, /* don't know the length */ 0, /* don't know the length */
self->configMode, &self->SacConfigChanged)) { self->configMode, &self->SacConfigChanged)) {
return TRANSPORTDEC_UNSUPPORTED_FORMAT; return TRANSPORTDEC_UNSUPPORTED_FORMAT;
@ -2365,10 +2375,17 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
/*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2); /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
if (usc->element[elemIdx].m_stereoConfigIndex > 0) { if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
if (cb->cbSsc != NULL) { if (cb->cbSsc != NULL) {
int samplesPerFrame = asc->m_samplesPerFrame;
if (usc->m_sbrRatioIndex == 1) samplesPerFrame <<= 2;
if (usc->m_sbrRatioIndex == 2)
samplesPerFrame = (samplesPerFrame * 8) / 3;
if (usc->m_sbrRatioIndex == 3) samplesPerFrame <<= 1;
ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc( ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbSsc(
cb->cbSscData, hBs, cb->cbSscData, hBs,
AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */ AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
asc->m_extensionSamplingFrequency, asc->m_extensionSamplingFrequency, samplesPerFrame,
usc->element[elemIdx].m_stereoConfigIndex, usc->element[elemIdx].m_stereoConfigIndex,
usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
asc->configMode, &asc->SacConfigChanged); asc->configMode, &asc->SacConfigChanged);

View File

@ -367,7 +367,8 @@ typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *); typedef INT (*cbCtrlCFGChange_t)(void *, const CCtrlCFGChange *);
typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM, typedef INT (*cbSsc_t)(void *, HANDLE_FDK_BITSTREAM,
const AUDIO_OBJECT_TYPE coreCodec, const AUDIO_OBJECT_TYPE coreCodec,
const INT samplingRate, const INT stereoConfigIndex, const INT samplingRate, const INT frameSize,
const INT stereoConfigIndex,
const INT coreSbrFrameLengthIndex, const INT configBytes, const INT coreSbrFrameLengthIndex, const INT configBytes,
const UCHAR configMode, UCHAR *configChanged); const UCHAR configMode, UCHAR *configChanged);

View File

@ -795,7 +795,7 @@ static int transportEnc_writeELDSpecificConfig(HANDLE_FDK_BITSTREAM hBs,
const INT eldExtLen = const INT eldExtLen =
(cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0, (cb->cbSsc(cb->cbSscData, NULL, config->aot, config->extSamplingRate, 0,
0, 0, 0, NULL) + 0, 0, 0, 0, NULL) +
7) >> 7) >>
3; 3;
INT cnt = eldExtLen; 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, cb->cbSsc(cb->cbSscData, hBs, config->aot, config->extSamplingRate, 0, 0, 0,
0, NULL); 0, 0, NULL);
} }
if (config->downscaleSamplingRate != 0 && if (config->downscaleSamplingRate != 0 &&

View File

@ -315,9 +315,9 @@ SACDEC_ERROR mpegSurroundDecoder_Init(
*/ */
SACDEC_ERROR mpegSurroundDecoder_Config( SACDEC_ERROR mpegSurroundDecoder_Config(
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT stereoConfigIndex, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
INT coreSbrFrameLengthIndex, INT configBytes, const UCHAR configMode, INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
UCHAR *configChanged); const UCHAR configMode, UCHAR *configChanged);
SACDEC_ERROR SACDEC_ERROR
mpegSurroundDecoder_ConfigureQmfDomain( mpegSurroundDecoder_ConfigureQmfDomain(

View File

@ -517,6 +517,10 @@ SACDEC_ERROR SpatialDecParseSpecificConfig(
pSpatialSpecificConfig->tempShapeConfig = pSpatialSpecificConfig->tempShapeConfig =
(SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2); (SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
if (pSpatialSpecificConfig->tempShapeConfig > 2) {
return MPS_PARSE_ERROR; /* reserved value */
}
pSpatialSpecificConfig->decorrConfig = pSpatialSpecificConfig->decorrConfig =
(SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2); (SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
if (pSpatialSpecificConfig->decorrConfig > 2) { if (pSpatialSpecificConfig->decorrConfig > 2) {

View File

@ -237,6 +237,11 @@ struct MpegSurroundDecoder {
SPATIAL_DEC_CONFIG decConfig; SPATIAL_DEC_CONFIG decConfig;
}; };
SACDEC_ERROR
static sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc,
const INT coreCodec, const INT sampleRate,
const INT frameSize);
static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc); static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc);
/** /**
@ -694,11 +699,13 @@ bail:
**/ **/
SACDEC_ERROR mpegSurroundDecoder_Config( SACDEC_ERROR mpegSurroundDecoder_Config(
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs, CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT stereoConfigIndex, AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
INT coreSbrFrameLengthIndex, INT configBytes, const UCHAR configMode, INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
UCHAR *configChanged) { const UCHAR configMode, UCHAR *configChanged) {
SACDEC_ERROR err = MPS_OK; SACDEC_ERROR err = MPS_OK;
SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig; SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig;
SPATIAL_SPECIFIC_CONFIG *pSsc =
&pMpegSurroundDecoder->spatialSpecificConfigBackup;
switch (coreCodec) { switch (coreCodec) {
case AOT_DRM_USAC: case AOT_DRM_USAC:
@ -709,6 +716,7 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
err = SpatialDecParseMps212Config( err = SpatialDecParseMps212Config(
hBs, &spatialSpecificConfig, samplingRate, coreCodec, hBs, &spatialSpecificConfig, samplingRate, coreCodec,
stereoConfigIndex, coreSbrFrameLengthIndex); stereoConfigIndex, coreSbrFrameLengthIndex);
pSsc = &spatialSpecificConfig;
} else { } else {
err = SpatialDecParseMps212Config( err = SpatialDecParseMps212Config(
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
@ -723,6 +731,7 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
* into temporarily allocated structure */ * into temporarily allocated structure */
err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig, err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig,
configBytes, coreCodec); configBytes, coreCodec);
pSsc = &spatialSpecificConfig;
} else { } else {
err = SpatialDecParseSpecificConfig( err = SpatialDecParseSpecificConfig(
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup, hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
@ -738,14 +747,21 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
goto bail; goto bail;
} }
err = sscCheckOutOfBand(pSsc, coreCodec, samplingRate, frameSize);
if (err != MPS_OK) {
goto bail;
}
if (configMode & AC_CM_DET_CFG_CHANGE) { if (configMode & AC_CM_DET_CFG_CHANGE) {
return err; return err;
} }
if (configMode & AC_CM_ALLOC_MEM) { if (configMode & AC_CM_ALLOC_MEM) {
if (*configChanged) { if (*configChanged) {
if ((err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder, err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder, stereoConfigIndex,
stereoConfigIndex, NULL))) { NULL);
if (err) {
return err; return err;
} }
} }
@ -815,29 +831,9 @@ static MPEGS_OPMODE mpegSurroundOperationMode(
* \return MPS_OK on sucess, and else on parse error. * \return MPS_OK on sucess, and else on parse error.
*/ */
static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) { static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) {
SACDEC_ERROR err = MPS_OK;
if (pSsc->samplingFreq > 96000) return MPS_PARSE_ERROR; if (pSsc->samplingFreq > 96000) return MPS_PARSE_ERROR;
if (pSsc->samplingFreq < 8000) return MPS_PARSE_ERROR; if (pSsc->samplingFreq < 8000) return MPS_PARSE_ERROR;
switch (pSsc->freqRes) {
case SPATIALDEC_FREQ_RES_28:
case SPATIALDEC_FREQ_RES_20:
case SPATIALDEC_FREQ_RES_14:
case SPATIALDEC_FREQ_RES_10:
case SPATIALDEC_FREQ_RES_23:
case SPATIALDEC_FREQ_RES_15:
case SPATIALDEC_FREQ_RES_12:
case SPATIALDEC_FREQ_RES_9:
case SPATIALDEC_FREQ_RES_7:
case SPATIALDEC_FREQ_RES_5:
case SPATIALDEC_FREQ_RES_4:
break;
case SPATIALDEC_FREQ_RES_40: /* 40 doesn't exist in ISO/IEC 23003-1 */
default:
return MPS_PARSE_ERROR;
}
if ((pSsc->treeConfig < 0) || (pSsc->treeConfig > 7)) { if ((pSsc->treeConfig < 0) || (pSsc->treeConfig > 7)) {
return MPS_PARSE_ERROR; return MPS_PARSE_ERROR;
} }
@ -846,17 +842,9 @@ static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) {
return MPS_PARSE_ERROR; return MPS_PARSE_ERROR;
} }
if (pSsc->tempShapeConfig == 3) {
return MPS_PARSE_ERROR;
}
if (pSsc->decorrConfig == 3) {
return MPS_PARSE_ERROR;
}
/* now we are sure there were no parsing errors */ /* now we are sure there were no parsing errors */
return err; return MPS_OK;
} }
/** /**
@ -1024,6 +1012,11 @@ static SACDEC_ERROR sscCheckInBand(SPATIAL_SPECIFIC_CONFIG *pSsc,
FDK_ASSERT(pSsc != NULL); FDK_ASSERT(pSsc != NULL);
/* check ssc for parse errors */
if (sscParseCheck(pSsc) != MPS_OK) {
err = MPS_PARSE_ERROR;
}
/* core fs and mps fs must match */ /* core fs and mps fs must match */
if (pSsc->samplingFreq != sampleRate) { if (pSsc->samplingFreq != sampleRate) {
err = MPS_PARSE_ERROR /* MPEGSDEC_SSC_PARSE_ERROR */; err = MPS_PARSE_ERROR /* MPEGSDEC_SSC_PARSE_ERROR */;
@ -1093,6 +1086,83 @@ mpegSurroundDecoder_ConfigureQmfDomain(
return err; return err;
} }
/**
* \brief Check out-of-band config
*
* \param pSsc spatial specific config handle.
* \param coreCodec core codec.
* \param sampleRate sampling frequency.
*
* \return errorStatus
*/
SACDEC_ERROR
sscCheckOutOfBand(const SPATIAL_SPECIFIC_CONFIG *pSsc, const INT coreCodec,
const INT sampleRate, const INT frameSize) {
FDK_ASSERT(pSsc != NULL);
int qmfBands = 0;
/* check ssc for parse errors */
if (sscParseCheck(pSsc) != MPS_OK) {
return MPS_PARSE_ERROR;
}
switch (coreCodec) {
case AOT_USAC:
case AOT_DRM_USAC:
/* ISO/IEC 23003-1:2007(E), Chapter 6.3.3, Support for lower and higher
* sampling frequencies */
if (pSsc->samplingFreq >= 55426) {
return MPS_PARSE_ERROR;
}
break;
case AOT_ER_AAC_LD:
case AOT_ER_AAC_ELD:
/* core fs and mps fs must match */
if (pSsc->samplingFreq != sampleRate) {
return MPS_PARSE_ERROR;
}
/* ISO/IEC 14496-3:2009 FDAM 3: Chapter 1.5.2.3, Levels for the Low Delay
* AAC v2 profile */
if (pSsc->samplingFreq > 48000) {
return MPS_PARSE_ERROR;
}
qmfBands = mpegSurroundDecoder_GetNrOfQmfBands(pSsc, pSsc->samplingFreq);
switch (frameSize) {
case 480:
if (!((qmfBands == 32) && (pSsc->nTimeSlots == 15))) {
return MPS_PARSE_ERROR;
}
break;
case 960:
if (!((qmfBands == 64) && (pSsc->nTimeSlots == 15))) {
return MPS_PARSE_ERROR;
}
break;
case 512:
if (!(((qmfBands == 32) && (pSsc->nTimeSlots == 16)) ||
((qmfBands == 64) && (pSsc->nTimeSlots == 8)))) {
return MPS_PARSE_ERROR;
}
break;
case 1024:
if (!((qmfBands == 64) && (pSsc->nTimeSlots == 16))) {
return MPS_PARSE_ERROR;
}
break;
default:
return MPS_PARSE_ERROR;
}
break;
default:
return MPS_PARSE_ERROR;
break;
}
return MPS_OK;
}
/** /**
* \brief Decode MPEG Surround frame. * \brief Decode MPEG Surround frame.
**/ **/