mirror of
https://github.com/mstorsjo/fdk-aac.git
synced 2025-06-05 22:39:13 +02:00
Decoder stability, sanity checks improvements
* AAC-Decoder - Improved PCE handling for saver (re-)configuration and metadata processing. Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp - Transport layer changes (config found) -> to be evaluated. Modified file(s): libMpegTPDec/include/tpdec_lib.h libMpegTPDec/src/tpdec_latm.h libMpegTPDec/src/version libMpegTPDec/src/tpdec_asc.cpp libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/tpdec_adts.cpp libMpegTPDec/src/tpdec_latm.cpp libSYS/include/FDK_audio.h libSYS/src/genericStds.cpp - Enable concealment state machine to skip states if the corresponding parameter is set to zero. Modified file(s): libAACdec/src/conceal.cpp - Add some more sanity checks to avoid segmentation faults especially when setting dynamic API params. Modified file(s): libAACdec/src/aacdecoder_lib.cpp - Fix to do a fail-safe initialization of IMDCT for all channels even with corrupt streams. Modified file(s): libAACdec/src/aacdecoder.cpp - HCR decoder fix (remove warnings). Modified file(s): libAACdec/src/block.cpp - Fix border calculation in SBR decoder's LPP transposer patch determination. Modified file(s): libSBRdec/src/env_dec.cpp libSBRdec/src/sbrdecoder.cpp libSBRdec/src/lpp_tran.cpp Bug 9428126 Change-Id: Ib415b702b88a7ec8e9a55789d79cafb39296d26b
This commit is contained in:
@@ -373,7 +373,7 @@ static AAC_DECODER_ERROR CDataStreamElement_Read (
|
||||
|
||||
{
|
||||
INT readBits, dataBits = count<<3;
|
||||
|
||||
|
||||
/* Move to the beginning of the data junk */
|
||||
FDKpushBack(bs, dataStart-FDKgetValidBits(bs));
|
||||
|
||||
@@ -394,23 +394,26 @@ static AAC_DECODER_ERROR CDataStreamElement_Read (
|
||||
\brief Read Program Config Element
|
||||
|
||||
\bs Bitstream Handle
|
||||
\count Pointer to program config element.
|
||||
\pTp Transport decoder handle for CRC handling
|
||||
\pce Pointer to PCE buffer
|
||||
\channelConfig Current channel configuration
|
||||
\alignAnchor Anchor for byte alignment
|
||||
|
||||
\return Error code
|
||||
\return PCE status (-1: fail, 0: no new PCE, 1: PCE updated, 2: PCE updated need re-config).
|
||||
*/
|
||||
static AAC_DECODER_ERROR CProgramConfigElement_Read (
|
||||
static int CProgramConfigElement_Read (
|
||||
HANDLE_FDK_BITSTREAM bs,
|
||||
HANDLE_TRANSPORTDEC pTp,
|
||||
CProgramConfig *pce,
|
||||
UINT channelConfig,
|
||||
UINT alignAnchor )
|
||||
const UINT channelConfig,
|
||||
const UINT alignAnchor )
|
||||
{
|
||||
AAC_DECODER_ERROR error = AAC_DEC_OK;
|
||||
int pceStatus = 0;
|
||||
int crcReg;
|
||||
|
||||
/* read PCE to temporal buffer first */
|
||||
C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
|
||||
|
||||
|
||||
CProgramConfig_Init(tmpPce);
|
||||
CProgramConfig_Reset(tmpPce);
|
||||
|
||||
@@ -421,22 +424,43 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read (
|
||||
transportDec_CrcEndReg(pTp, crcReg);
|
||||
|
||||
if ( CProgramConfig_IsValid(tmpPce)
|
||||
&& ( (channelConfig == 6 && (tmpPce->NumChannels == 6))
|
||||
|| (channelConfig == 5 && (tmpPce->NumChannels == 5))
|
||||
|| (channelConfig == 0 && (tmpPce->NumChannels == pce->NumChannels)) )
|
||||
&& (tmpPce->NumFrontChannelElements == 2)
|
||||
&& (tmpPce->NumSideChannelElements == 0)
|
||||
&& (tmpPce->NumBackChannelElements == 1)
|
||||
&& (tmpPce->Profile == 1) )
|
||||
{ /* Copy the complete PCE including metadata. */
|
||||
FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig));
|
||||
{
|
||||
if ( !pce->isValid && (channelConfig > 0) ) {
|
||||
/* Create a standard channel config PCE to compare with */
|
||||
CProgramConfig_GetDefault( pce, channelConfig );
|
||||
}
|
||||
|
||||
if (pce->isValid) {
|
||||
/* Compare the new and the old PCE (tags ignored) */
|
||||
switch ( CProgramConfig_Compare( pce, tmpPce ) )
|
||||
{
|
||||
case 1: /* Channel configuration not changed. Just new metadata. */
|
||||
FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); /* Store the complete PCE */
|
||||
pceStatus = 1; /* New PCE but no change of config */
|
||||
break;
|
||||
case 2: /* The number of channels are identical but not the config */
|
||||
if (channelConfig == 0) {
|
||||
FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); /* Store the complete PCE */
|
||||
pceStatus = 2; /* Decoder needs re-configuration */
|
||||
}
|
||||
break;
|
||||
case -1: /* The channel configuration is completely different */
|
||||
pceStatus = -1; /* Not supported! */
|
||||
break;
|
||||
case 0: /* Nothing to do because PCE matches the old one exactly. */
|
||||
default:
|
||||
/* pceStatus = 0; */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
|
||||
|
||||
return error;
|
||||
return pceStatus;
|
||||
}
|
||||
#endif
|
||||
#endif /* TP_PCE_ENABLE */
|
||||
|
||||
/*!
|
||||
\brief Parse Extension Payload
|
||||
@@ -591,7 +615,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
|
||||
{ /* ... created to circumvent the missing length in ER-Syntax. */
|
||||
int bitCnt, len = FDKreadBits(hBs, 4);
|
||||
*count -= 4;
|
||||
|
||||
|
||||
if (len == 15) {
|
||||
int add_len = FDKreadBits(hBs, 8);
|
||||
*count -= 8;
|
||||
@@ -609,9 +633,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
|
||||
/* Check NOTE 2: The extension_payload() included here must
|
||||
not have extension_type == EXT_DATA_LENGTH. */
|
||||
error = AAC_DEC_PARSE_ERROR;
|
||||
goto bail;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* rewind and call myself again. */
|
||||
FDKpushBack(hBs, 4);
|
||||
|
||||
@@ -622,7 +644,7 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
|
||||
&bitCnt,
|
||||
previous_element,
|
||||
elIndex,
|
||||
1 ); /* Treat same as fill element */
|
||||
0 );
|
||||
|
||||
*count -= len - bitCnt;
|
||||
}
|
||||
@@ -754,8 +776,12 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self)
|
||||
|
||||
for (ch=0; ch<(6); ch++) {
|
||||
if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
|
||||
FreeOverlapBuffer (&self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
|
||||
FreeAacDecoderStaticChannelInfo (&self->pAacDecoderStaticChannelInfo[ch]);
|
||||
if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
|
||||
FreeOverlapBuffer (&self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
|
||||
}
|
||||
if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
|
||||
FreeAacDecoderStaticChannelInfo (&self->pAacDecoderStaticChannelInfo[ch]);
|
||||
}
|
||||
}
|
||||
if (self->pAacDecoderChannelInfo[ch] != NULL) {
|
||||
FreeAacDecoderChannelInfo (&self->pAacDecoderChannelInfo[ch]);
|
||||
@@ -768,8 +794,12 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self)
|
||||
FreeDrcInfo(&self->hDrcInfo);
|
||||
}
|
||||
|
||||
FreeWorkBufferCore1 (&self->aacCommonData.workBufferCore1);
|
||||
FreeWorkBufferCore2 (&self->aacCommonData.workBufferCore2);
|
||||
if (self->aacCommonData.workBufferCore1 != NULL) {
|
||||
FreeWorkBufferCore1 (&self->aacCommonData.workBufferCore1);
|
||||
}
|
||||
if (self->aacCommonData.workBufferCore2 != NULL) {
|
||||
FreeWorkBufferCore2 (&self->aacCommonData.workBufferCore2);
|
||||
}
|
||||
|
||||
FreeAacDecoder ( &self);
|
||||
}
|
||||
@@ -994,12 +1024,14 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
|
||||
CPns_InitPns(&self->pAacDecoderChannelInfo[ch]->data.aac.PnsData, &self->aacCommonData.pnsInterChannelData, &self->aacCommonData.pnsCurrentSeed, self->aacCommonData.pnsRandomSeed);
|
||||
}
|
||||
|
||||
if (ascChannels > self->aacChannels)
|
||||
{
|
||||
/* Make allocated channel count persistent in decoder context. */
|
||||
self->aacChannels = ascChannels;
|
||||
}
|
||||
|
||||
HcrInitRom(&self->aacCommonData.overlay.aac.erHcrInfo);
|
||||
setHcrType(&self->aacCommonData.overlay.aac.erHcrInfo, ID_SCE);
|
||||
|
||||
/* Make allocated channel count persistent in decoder context. */
|
||||
self->aacChannels = ascChannels;
|
||||
}
|
||||
|
||||
/* Make amount of signalled channels persistent in decoder context. */
|
||||
@@ -1009,8 +1041,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
|
||||
/* Update structures */
|
||||
if (ascChanged) {
|
||||
|
||||
/* Things to be done for each channel, which do not involved allocating memory. */
|
||||
for (ch = 0; ch < ascChannels; ch++) {
|
||||
/* Things to be done for each channel, which do not involve allocating memory.
|
||||
Doing these things only on the channels needed for the current configuration
|
||||
(ascChannels) could lead to memory access violation later (error concealment). */
|
||||
for (ch = 0; ch < self->aacChannels; ch++) {
|
||||
switch (self->streamInfo.aot) {
|
||||
case AOT_ER_AAC_ELD:
|
||||
case AOT_ER_AAC_LD:
|
||||
@@ -1241,10 +1275,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
else {
|
||||
self->frameOK = 0;
|
||||
}
|
||||
/* Create SBR element for SBR for upsampling. */
|
||||
if ( (type == ID_LFE)
|
||||
&& ( (self->flags & AC_SBR_PRESENT)
|
||||
|| (self->sbrEnabled == 1) ) )
|
||||
/* Create SBR element for SBR for upsampling for LFE elements,
|
||||
and if SBR was explicitly signaled, because the first frame(s)
|
||||
may not contain SBR payload (broken encoder, bit errors). */
|
||||
if ( (self->flags & AC_SBR_PRESENT) || (self->sbrEnabled == 1) )
|
||||
{
|
||||
SBR_ERROR sbrError;
|
||||
|
||||
@@ -1254,7 +1288,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
self->streamInfo.extSamplingRate,
|
||||
self->streamInfo.aacSamplesPerFrame,
|
||||
self->streamInfo.aot,
|
||||
ID_LFE,
|
||||
type,
|
||||
previous_element_index
|
||||
);
|
||||
if (sbrError != SBRDEC_OK) {
|
||||
@@ -1394,26 +1428,34 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
|
||||
|
||||
#ifdef TP_PCE_ENABLE
|
||||
case ID_PCE:
|
||||
|
||||
if ( CProgramConfigElement_Read( bs,
|
||||
{
|
||||
int result = CProgramConfigElement_Read(
|
||||
bs,
|
||||
self->hInput,
|
||||
pce,
|
||||
self->streamInfo.channelConfig,
|
||||
auStartAnchor ) )
|
||||
{ /* Built element table */
|
||||
int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
|
||||
/* Reset the remaining tabs */
|
||||
for ( ; elIdx<7; elIdx++) {
|
||||
self->elements[elIdx] = ID_NONE;
|
||||
}
|
||||
/* Make new number of channel persistant */
|
||||
self->ascChannels = pce->NumChannels;
|
||||
/* If PCE is not first element conceal this frame to avoid inconsistencies */
|
||||
if ( element_count != 0 ) {
|
||||
auStartAnchor );
|
||||
if ( result < 0 ) {
|
||||
/* Something went wrong */
|
||||
ErrorStatus = AAC_DEC_PARSE_ERROR;
|
||||
self->frameOK = 0;
|
||||
}
|
||||
else if ( result > 1 ) {
|
||||
/* Built element table */
|
||||
int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
|
||||
/* Reset the remaining tabs */
|
||||
for ( ; elIdx<7; elIdx++) {
|
||||
self->elements[elIdx] = ID_NONE;
|
||||
}
|
||||
/* Make new number of channel persistant */
|
||||
self->ascChannels = pce->NumChannels;
|
||||
/* If PCE is not first element conceal this frame to avoid inconsistencies */
|
||||
if ( element_count != 0 ) {
|
||||
self->frameOK = 0;
|
||||
}
|
||||
}
|
||||
pceRead = (result>=0) ? 1 : 0;
|
||||
}
|
||||
pceRead = 1;
|
||||
break;
|
||||
#endif /* TP_PCE_ENABLE */
|
||||
|
||||
|
Reference in New Issue
Block a user