mirror of https://github.com/mstorsjo/fdk-aac.git
Add AOT specific number of qmf bands sanity check in SpatialSpecificConfig()
Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ic106c4371c5ac17cb832c7d9db042bcc9d1e7a09
This commit is contained in:
parent
7884aefc84
commit
5c54fa5387
|
@ -387,7 +387,7 @@ static INT aacDecoder_SbrCallback(
|
|||
|
||||
static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
|
||||
const AUDIO_OBJECT_TYPE coreCodec,
|
||||
const INT samplingRate,
|
||||
const INT samplingRate, const INT frameSize,
|
||||
const INT stereoConfigIndex,
|
||||
const INT coreSbrFrameLengthIndex,
|
||||
const INT configBytes, const UCHAR configMode,
|
||||
|
@ -398,8 +398,8 @@ static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
|
|||
|
||||
err = mpegSurroundDecoder_Config(
|
||||
(CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
|
||||
samplingRate, stereoConfigIndex, coreSbrFrameLengthIndex, configBytes,
|
||||
configMode, configChanged);
|
||||
samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex,
|
||||
configBytes, configMode, configChanged);
|
||||
|
||||
switch (err) {
|
||||
case MPS_UNSUPPORTED_CONFIG:
|
||||
|
|
|
@ -1216,7 +1216,8 @@ 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 stereoConfigIndex,
|
||||
const INT samplingRate, const INT frameSize,
|
||||
const INT stereoConfigIndex,
|
||||
const INT coreSbrFrameLengthIndex, const INT configBytes,
|
||||
const UCHAR configMode, UCHAR *configChanged) {
|
||||
HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self;
|
||||
|
|
|
@ -367,7 +367,8 @@ typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
|
|||
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 stereoConfigIndex,
|
||||
const INT samplingRate, const INT frameSize,
|
||||
const INT stereoConfigIndex,
|
||||
const INT coreSbrFrameLengthIndex, const INT configBytes,
|
||||
const UCHAR configMode, UCHAR *configChanged);
|
||||
|
||||
|
|
|
@ -1413,7 +1413,9 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc,
|
|||
esc->m_useLdQmfTimeAlign = 1;
|
||||
if (cb->cbSsc != NULL) {
|
||||
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, /* nTimeSlots: read from bitstream */
|
||||
eldExtLen, asc->configMode, &asc->SacConfigChanged);
|
||||
|
@ -1812,9 +1814,16 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse(
|
|||
|
||||
if (usc->element[i].m_stereoConfigIndex > 0) {
|
||||
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 */
|
||||
if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot,
|
||||
asc->m_extensionSamplingFrequency,
|
||||
asc->m_extensionSamplingFrequency, samplesPerFrame,
|
||||
usc->element[i].m_stereoConfigIndex,
|
||||
usc->m_coreSbrFrameLengthIndex,
|
||||
0, /* don't know the length */
|
||||
|
@ -2181,7 +2190,8 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
|
|||
case AOT_MPEGS:
|
||||
if (cb->cbSsc != NULL) {
|
||||
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 */
|
||||
self->configMode, &self->SacConfigChanged)) {
|
||||
return TRANSPORTDEC_UNSUPPORTED_FORMAT;
|
||||
|
@ -2365,10 +2375,17 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig(
|
|||
/*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2);
|
||||
if (usc->element[elemIdx].m_stereoConfigIndex > 0) {
|
||||
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(
|
||||
cb->cbSscData, hBs,
|
||||
AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */
|
||||
asc->m_extensionSamplingFrequency,
|
||||
asc->m_extensionSamplingFrequency, samplesPerFrame,
|
||||
usc->element[elemIdx].m_stereoConfigIndex,
|
||||
usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */
|
||||
asc->configMode, &asc->SacConfigChanged);
|
||||
|
|
|
@ -367,7 +367,8 @@ typedef INT (*cbFreeMem_t)(void *, const CSAudioSpecificConfig *);
|
|||
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 stereoConfigIndex,
|
||||
const INT samplingRate, const INT frameSize,
|
||||
const INT stereoConfigIndex,
|
||||
const INT coreSbrFrameLengthIndex, const INT configBytes,
|
||||
const UCHAR configMode, UCHAR *configChanged);
|
||||
|
||||
|
|
|
@ -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, NULL) +
|
||||
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, NULL);
|
||||
0, 0, NULL);
|
||||
}
|
||||
|
||||
if (config->downscaleSamplingRate != 0 &&
|
||||
|
|
|
@ -315,9 +315,9 @@ SACDEC_ERROR mpegSurroundDecoder_Init(
|
|||
*/
|
||||
SACDEC_ERROR mpegSurroundDecoder_Config(
|
||||
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
|
||||
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT stereoConfigIndex,
|
||||
INT coreSbrFrameLengthIndex, INT configBytes, const UCHAR configMode,
|
||||
UCHAR *configChanged);
|
||||
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
|
||||
INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
|
||||
const UCHAR configMode, UCHAR *configChanged);
|
||||
|
||||
SACDEC_ERROR
|
||||
mpegSurroundDecoder_ConfigureQmfDomain(
|
||||
|
|
|
@ -517,6 +517,10 @@ SACDEC_ERROR SpatialDecParseSpecificConfig(
|
|||
|
||||
pSpatialSpecificConfig->tempShapeConfig =
|
||||
(SPATIALDEC_TS_CONF)FDKreadBits(bitstream, 2);
|
||||
if (pSpatialSpecificConfig->tempShapeConfig > 2) {
|
||||
return MPS_PARSE_ERROR; /* reserved value */
|
||||
}
|
||||
|
||||
pSpatialSpecificConfig->decorrConfig =
|
||||
(SPATIALDEC_DECORR_CONF)FDKreadBits(bitstream, 2);
|
||||
if (pSpatialSpecificConfig->decorrConfig > 2) {
|
||||
|
|
|
@ -237,6 +237,11 @@ struct MpegSurroundDecoder {
|
|||
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);
|
||||
|
||||
/**
|
||||
|
@ -694,11 +699,13 @@ bail:
|
|||
**/
|
||||
SACDEC_ERROR mpegSurroundDecoder_Config(
|
||||
CMpegSurroundDecoder *pMpegSurroundDecoder, HANDLE_FDK_BITSTREAM hBs,
|
||||
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT stereoConfigIndex,
|
||||
INT coreSbrFrameLengthIndex, INT configBytes, const UCHAR configMode,
|
||||
UCHAR *configChanged) {
|
||||
AUDIO_OBJECT_TYPE coreCodec, INT samplingRate, INT frameSize,
|
||||
INT stereoConfigIndex, INT coreSbrFrameLengthIndex, INT configBytes,
|
||||
const UCHAR configMode, UCHAR *configChanged) {
|
||||
SACDEC_ERROR err = MPS_OK;
|
||||
SPATIAL_SPECIFIC_CONFIG spatialSpecificConfig;
|
||||
SPATIAL_SPECIFIC_CONFIG *pSsc =
|
||||
&pMpegSurroundDecoder->spatialSpecificConfigBackup;
|
||||
|
||||
switch (coreCodec) {
|
||||
case AOT_DRM_USAC:
|
||||
|
@ -709,6 +716,7 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
|
|||
err = SpatialDecParseMps212Config(
|
||||
hBs, &spatialSpecificConfig, samplingRate, coreCodec,
|
||||
stereoConfigIndex, coreSbrFrameLengthIndex);
|
||||
pSsc = &spatialSpecificConfig;
|
||||
} else {
|
||||
err = SpatialDecParseMps212Config(
|
||||
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
|
||||
|
@ -723,6 +731,7 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
|
|||
* into temporarily allocated structure */
|
||||
err = SpatialDecParseSpecificConfig(hBs, &spatialSpecificConfig,
|
||||
configBytes, coreCodec);
|
||||
pSsc = &spatialSpecificConfig;
|
||||
} else {
|
||||
err = SpatialDecParseSpecificConfig(
|
||||
hBs, &pMpegSurroundDecoder->spatialSpecificConfigBackup,
|
||||
|
@ -738,14 +747,21 @@ SACDEC_ERROR mpegSurroundDecoder_Config(
|
|||
goto bail;
|
||||
}
|
||||
|
||||
err = sscCheckOutOfBand(pSsc, coreCodec, samplingRate, frameSize);
|
||||
|
||||
if (err != MPS_OK) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (configMode & AC_CM_DET_CFG_CHANGE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (configMode & AC_CM_ALLOC_MEM) {
|
||||
if (*configChanged) {
|
||||
if ((err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder,
|
||||
stereoConfigIndex, NULL))) {
|
||||
err = mpegSurroundDecoder_Open(&pMpegSurroundDecoder, stereoConfigIndex,
|
||||
NULL);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
@ -815,29 +831,9 @@ static MPEGS_OPMODE mpegSurroundOperationMode(
|
|||
* \return MPS_OK on sucess, and else on parse error.
|
||||
*/
|
||||
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 < 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)) {
|
||||
return MPS_PARSE_ERROR;
|
||||
}
|
||||
|
@ -846,17 +842,9 @@ static SACDEC_ERROR sscParseCheck(const SPATIAL_SPECIFIC_CONFIG *pSsc) {
|
|||
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 */
|
||||
|
||||
return err;
|
||||
return MPS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1024,6 +1012,11 @@ static SACDEC_ERROR sscCheckInBand(SPATIAL_SPECIFIC_CONFIG *pSsc,
|
|||
|
||||
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 */
|
||||
if (pSsc->samplingFreq != sampleRate) {
|
||||
err = MPS_PARSE_ERROR /* MPEGSDEC_SSC_PARSE_ERROR */;
|
||||
|
@ -1093,6 +1086,83 @@ mpegSurroundDecoder_ConfigureQmfDomain(
|
|||
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.
|
||||
**/
|
||||
|
|
Loading…
Reference in New Issue