aboutsummaryrefslogtreecommitdiffstats
path: root/libAACdec/src/aacdecoder.cpp
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2013-08-27 16:28:09 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2013-08-27 16:28:09 -0700
commit5016eb7f6582fbb2d72d79be782325a12df08864 (patch)
treebc2325ebc6840a20d25f35a0c5a6a13454d2e402 /libAACdec/src/aacdecoder.cpp
parentb9774f90651be61065ae40171fc321f6ced60e49 (diff)
downloadfdk-aac-5016eb7f6582fbb2d72d79be782325a12df08864.tar.gz
fdk-aac-5016eb7f6582fbb2d72d79be782325a12df08864.tar.bz2
fdk-aac-5016eb7f6582fbb2d72d79be782325a12df08864.zip
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
Diffstat (limited to 'libAACdec/src/aacdecoder.cpp')
-rw-r--r--libAACdec/src/aacdecoder.cpp144
1 files changed, 93 insertions, 51 deletions
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index 3d00d34..3a2a561 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -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 */