1
0
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:
Jean-Michel Trivi
2013-08-27 16:28:09 -07:00
parent b9774f9065
commit 5016eb7f65
16 changed files with 683 additions and 294 deletions

View File

@@ -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 */