summaryrefslogtreecommitdiffstats
path: root/libAACdec
diff options
context:
space:
mode:
authorDave Burke <daveburke@google.com>2012-05-12 13:17:25 -0700
committerDave Burke <daveburke@google.com>2012-05-12 13:47:46 -0700
commit698b536f3b34a7cfc41a80e1034cc359456bdd66 (patch)
treefa3dfa75d535b188725f1b84316cb4b06db79771 /libAACdec
parent9bf37cc9712506b2483650c82d3c41152337ef7e (diff)
downloadfdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.tar.gz
fdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.tar.bz2
fdk-aac-698b536f3b34a7cfc41a80e1034cc359456bdd66.zip
Update to 2012_05_11 version.
Fixes: - Don't throw error for invalid bitrate but limit to functional value - More robust ASC parsing - More robust handling of corrupt bitstreams - Handle multiple raw access units Change-Id: Ib49fe2545ff4185fe924126da702fe84ac5c2d87
Diffstat (limited to 'libAACdec')
-rw-r--r--libAACdec/src/aacdec_drc.cpp64
-rw-r--r--libAACdec/src/aacdec_drc_types.h8
-rw-r--r--libAACdec/src/aacdec_hcrs.cpp3
-rw-r--r--libAACdec/src/aacdec_tns.h2
-rw-r--r--libAACdec/src/aacdecoder.cpp73
-rw-r--r--libAACdec/src/aacdecoder_lib.cpp4
6 files changed, 88 insertions, 66 deletions
diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp
index 58abea2..9049353 100644
--- a/libAACdec/src/aacdec_drc.cpp
+++ b/libAACdec/src/aacdec_drc.cpp
@@ -42,7 +42,7 @@
#define DRC_PARAMETER_BITS ( 7 )
#define DRC_MAX_QUANT_STEPS ( 1<<DRC_PARAMETER_BITS )
#define DRC_MAX_QUANT_FACTOR ( DRC_MAX_QUANT_STEPS-1 )
-#define DRC_PARAM_QUANT_STEP ( FL2FXCONST_DBL(1.0f/(float)DRC_MAX_QUANT_STEPS) )
+#define DRC_PARAM_QUANT_STEP ( FL2FXCONST_DBL(1.0f/(float)DRC_MAX_QUANT_FACTOR) )
#define DRC_PARAM_SCALE ( 1 )
#define MAX_REFERENCE_LEVEL ( 127 )
@@ -99,6 +99,7 @@ void aacDecoder_drcInitChannelData (
pDrcChData->bandTop[0] = (1024 >> 2) - 1;
pDrcChData->drcValue[0] = 0;
pDrcChData->drcInterpolationScheme = 0;
+ pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
}
}
@@ -130,7 +131,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
- self->params.cut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)(value+1));
+ self->params.cut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value);
break;
case DRC_BOOST_SCALE:
/* set boost factor */
@@ -141,7 +142,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) {
return AAC_DEC_INVALID_HANDLE;
}
- self->params.boost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)(value+1));
+ self->params.boost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value);
break;
case TARGET_REF_LEVEL:
if ( value > MAX_REFERENCE_LEVEL
@@ -300,14 +301,13 @@ int aacDecoder_drcMarkPayload (
break;
case DVB_DRC_ANC_DATA:
+ bitCnt += 8;
/* check sync word */
if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE)
{
int dmxLevelsPresent, compressionPresent;
int coarseGrainTcPresent, fineGrainTcPresent;
- bitCnt+=8;
-
/* bs_info field */
FDKreadBits(bs, 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
bitCnt+=8;
@@ -432,7 +432,7 @@ static int aacDecoder_drcParse (
}
/* Set DRC payload type */
- pDrcBs->type = MPEG_DRC_EXT_DATA;
+ pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
return (bitCnt);
}
@@ -515,23 +515,26 @@ static int aacDecoder_drcReadCompression (
if ( compressionOn ) {
/* A compression value is available so store the data just like MPEG DRC data */
- pDrcBs->channelData.drcValue[0] = compressionValue;
- pDrcBs->channelData.numBands = 1; /* one value for all bands */
- pDrcBs->pceInstanceTag = -1; /* not present */
- pDrcBs->progRefLevel = -1; /* not present */
+ pDrcBs->channelData.numBands = 1; /* One band ... */
+ pDrcBs->channelData.drcValue[0] = compressionValue; /* ... with one value ... */
+ pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */
+ pDrcBs->pceInstanceTag = -1; /* Not present */
+ pDrcBs->progRefLevel = -1; /* Not present */
+ pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
} else {
/* No compression value available */
/* CAUTION: It is not clearly defined by standard how to react in this situation. */
- pDrcBs->channelData.drcValue[0] = 0x7F; /* 0dB */
- pDrcBs->channelData.bandTop[0] = 0;
+ /* Turn down the compression value to aprox. 0dB */
+ pDrcBs->channelData.numBands = 1; /* One band ... */
+ pDrcBs->channelData.drcValue[0] = 0x80; /* ... with aprox. 0dB ... */
+ pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */
+ pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
/* If compression_on field is set to "0" the compression_value field shall be "0000 0000". */
if (compressionValue != 0) {
return 0;
}
}
- /* Set DRC payload type now because the payload seems to be correct. */
- pDrcBs->type = DVB_DRC_ANC_DATA;
}
/* Read timecodes if available just to get the right amount of bits. */
@@ -617,7 +620,7 @@ static int aacDecoder_drcExtractAndMap (
CDrcPayload *pThreadBs = &threadBs[thread];
int numExclChns = 0;
- switch (pThreadBs->type) {
+ switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
default:
continue;
case MPEG_DRC_EXT_DATA:
@@ -659,7 +662,7 @@ static int aacDecoder_drcExtractAndMap (
/* thread applies to this channel */
- if ( (pThreadBs->type == MPEG_DRC_EXT_DATA)
+ if ( (pThreadBs->channelData.drcDataType == MPEG_DRC_EXT_DATA)
&& ( (numExcludedChns[thread] == 0)
|| (!(pThreadBs->excludedChnsMask & (1<<ch))) ) ) {
present++;
@@ -678,6 +681,7 @@ static int aacDecoder_drcExtractAndMap (
{
CDrcPayload *pThreadBs = validThreadBs[thread];
INT exclMask = pThreadBs->excludedChnsMask;
+ AACDEC_DRC_PAYLOAD_TYPE drcPayloadType = (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
int ch;
/* last progRefLevel transmitted is the one that is used
@@ -692,9 +696,9 @@ static int aacDecoder_drcExtractAndMap (
int mapedChannel = channelMapping[ch];
if ( ((exclMask & (1<<mapedChannel)) == 0)
- && ( ( self->params.applyHeavyCompression && (pThreadBs->type == DVB_DRC_ANC_DATA))
- || (!self->params.applyHeavyCompression && (pThreadBs->type == MPEG_DRC_EXT_DATA)) )
- ) {
+ && ( (drcPayloadType == MPEG_DRC_EXT_DATA)
+ || ((drcPayloadType == DVB_DRC_ANC_DATA) && self->params.applyHeavyCompression)
+ ) ) {
/* copy thread to channel */
pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
}
@@ -781,10 +785,17 @@ void aacDecoder_drcApply (
UCHAR drcVal = pDrcChData->drcValue[band];
top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize);
- if ( pParams->applyHeavyCompression ) {
+ fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
+ fact_exponent[band] = 1;
+
+ if ( pParams->applyHeavyCompression
+ && ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == DVB_DRC_ANC_DATA) )
+ {
INT compressionFactorVal_e;
- int valX = drcVal >> 4;
- int valY = drcVal & 0x0F;
+ int valX, valY;
+
+ valX = drcVal >> 4;
+ valY = drcVal & 0x0F;
/* calculate the unscaled heavy compression factor.
compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
@@ -801,11 +812,8 @@ void aacDecoder_drcApply (
fact_exponent[band] = DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
}
- else {
- fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
- fact_exponent[band] = 1;
- }
} else
+ if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == MPEG_DRC_EXT_DATA)
{
/* apply the scaled dynamic range control words to factor.
* if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
@@ -824,10 +832,6 @@ void aacDecoder_drcApply (
3+DRC_PARAM_SCALE,
&fact_exponent[band] );
}
- else {
- fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
- fact_exponent[band] = 1;
- }
}
fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h
index 20a593b..2306bb9 100644
--- a/libAACdec/src/aacdec_drc_types.h
+++ b/libAACdec/src/aacdec_drc_types.h
@@ -41,9 +41,9 @@
*/
typedef enum
{
- UNKNOWN_PAYLOAD = 0,
- MPEG_DRC_EXT_DATA,
- DVB_DRC_ANC_DATA
+ UNKNOWN_PAYLOAD = 0,
+ MPEG_DRC_EXT_DATA = 1,
+ DVB_DRC_ANC_DATA = 2
} AACDEC_DRC_PAYLOAD_TYPE;
@@ -54,12 +54,12 @@ typedef struct
USHORT bandTop[MAX_DRC_BANDS];
SHORT drcInterpolationScheme;
UCHAR drcValue[MAX_DRC_BANDS];
+ SCHAR drcDataType;
} CDrcChannelData;
typedef struct
{
- AACDEC_DRC_PAYLOAD_TYPE type;
UINT excludedChnsMask;
SCHAR progRefLevel;
SCHAR pceInstanceTag;
diff --git a/libAACdec/src/aacdec_hcrs.cpp b/libAACdec/src/aacdec_hcrs.cpp
index da8928e..1c2bb46 100644
--- a/libAACdec/src/aacdec_hcrs.cpp
+++ b/libAACdec/src/aacdec_hcrs.cpp
@@ -736,6 +736,9 @@ UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr)
/* search for a line (which was decoded in previous state) which is not zero. [This value will get a sign] */
while ( pResultBase[iQSC] == (FIXP_DBL)0 ) {
iQSC++; /* points to current value different from zero */
+ if (iQSC >= 1024) {
+ return BODY_SIGN__SIGN;
+ }
}
/* put sign together with line; if carryBit is zero, the sign is ok already; no write operation necessary in this case */
diff --git a/libAACdec/src/aacdec_tns.h b/libAACdec/src/aacdec_tns.h
index cf3f597..55b31ce 100644
--- a/libAACdec/src/aacdec_tns.h
+++ b/libAACdec/src/aacdec_tns.h
@@ -34,7 +34,7 @@
enum
{
TNS_MAX_WINDOWS = 8, /* 8 */
- TNS_MAXIMUM_ORDER = 12, /* 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken encoders also do order 20 for AAC-LC :( */
+ TNS_MAXIMUM_ORDER = 20, /* 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken encoders also do order 20 for AAC-LC :( */
TNS_MAXIMUM_FILTERS = 3
};
diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp
index 534d48f..77c415b 100644
--- a/libAACdec/src/aacdecoder.cpp
+++ b/libAACdec/src/aacdecoder.cpp
@@ -345,6 +345,7 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read (
HANDLE_FDK_BITSTREAM bs,
HANDLE_TRANSPORTDEC pTp,
CProgramConfig *pce,
+ UINT channelConfig,
UINT alignAnchor )
{
AAC_DECODER_ERROR error = AAC_DEC_OK;
@@ -362,8 +363,15 @@ static AAC_DECODER_ERROR CProgramConfigElement_Read (
transportDec_CrcEndReg(pTp, crcReg);
- if (!pce->isValid && tmpPce->NumChannels <= (6) && tmpPce->Profile == 1) {
- /* store PCE data */
+ 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));
}
@@ -411,29 +419,18 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
INT readBits = aacDecoder_drcMarkPayload( self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA );
if (readBits > *count)
- {
- FDKpushBack(hBs, readBits - *count);
+ { /* Read too much. Something went wrong! */
error = AAC_DEC_PARSE_ERROR;
- return error;
- }
- else
- {
- *count -= (readBits+7) & ~0x7;
}
+ *count -= readBits;
}
break;
- case EXT_LDSAC_DATA:
- case EXT_SAC_DATA:
- /* Skip MPEG Surround Extension payload */
- FDKpushFor(hBs, *count);
- *count = 0;
- break;
+
case EXT_SBR_DATA_CRC:
crcFlag = 1;
-
case EXT_SBR_DATA:
- {
+ if (IS_CHANNEL_ELEMENT(previous_element)) {
SBR_ERROR sbrError;
CAacDecoder_SyncQmfMode(self);
@@ -479,6 +476,8 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
self->frameOK = 0;
}
}
+ } else {
+ error = AAC_DEC_PARSE_ERROR;
}
break;
@@ -523,14 +522,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
*count -= (dataElementLength<<3);
} else {
/* align = 0 */
- FDKpushFor(hBs, (*count)<<3);
- *count = 0;
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
}
}
break;
case EXT_DATA_LENGTH:
- {
+ if ( !fIsFillElement /* Makes no sens to have an additional length in a fill ... */
+ && (self->flags & AC_ER) ) /* ... element because this extension payload type was ... */
+ { /* ... created to circumvent the missing length in ER-Syntax. */
int bitCnt, len = FDKreadBits(hBs, 4);
*count -= 4;
@@ -551,7 +552,9 @@ 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;
- } else {
+ goto bail;
+ }
+ else {
/* rewind and call myself again. */
FDKpushBack(hBs, 4);
@@ -562,12 +565,13 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
&bitCnt,
previous_element,
elIndex,
- 0 );
+ 1 ); /* Treat same as fill element */
*count -= len - bitCnt;
}
+ /* Note: the fall through in case the if statement above is not taken is intentional. */
+ break;
}
- break;
case EXT_FIL:
@@ -578,6 +582,16 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self,
break;
}
+bail:
+ if ( (error != AAC_DEC_OK)
+ && fIsFillElement )
+ { /* Skip the remaining extension bytes */
+ FDKpushBiDirectional(hBs, *count);
+ *count = 0;
+ /* Patch error code because decoding can go on. */
+ error = AAC_DEC_OK;
+ /* Be sure that parsing errors have been stored. */
+ }
return error;
}
@@ -750,7 +764,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CS
/* valid number of channels -> copy program config element (PCE) from ASC */
FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig));
/* Built element table */
- el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements);
+ el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, 7);
for (; el<7; el++) {
self->elements[el] = ID_NONE;
}
@@ -1286,7 +1300,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
}
}
-#if defined(PCM_POSTPROCESS_ENABLE) && defined(DVB_MIXDOWN_ENABLE) && defined(AACDEC_DVB_SUPPORT_ENABLE)
{
UCHAR *pDvbAncData = NULL;
AAC_DECODER_ERROR ancErr;
@@ -1309,7 +1322,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
0 /* not mpeg2 */ );
}
}
-#endif /* PCM_POSTPROCESS_ENABLE && DVB_MIXDOWN_ENABLE && AACDEC_DVB_SUPPORT_ENABLE */
break;
#ifdef TP_PCE_ENABLE
@@ -1318,9 +1330,10 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if ( CProgramConfigElement_Read( bs,
self->hInput,
pce,
+ self->streamInfo.channelConfig,
auStartAnchor ) )
{ /* Built element table */
- int elIdx = CProgramConfig_GetElementTable(pce, self->elements);
+ int elIdx = CProgramConfig_GetElementTable(pce, self->elements, 7);
/* Reset the remaining tabs */
for ( ; elIdx<7; elIdx++) {
self->elements[elIdx] = ID_NONE;
@@ -1368,7 +1381,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD)) )
{
- SBR_ERROR err;
+ SBR_ERROR err = SBRDEC_OK;
int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE];
for (elIdx = 0; elIdx < numChElements; elIdx += 1)
@@ -1494,7 +1507,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
/* Update number of output channels */
self->streamInfo.numChannels = aacChannels;
-#if defined(TP_PCE_ENABLE) && defined(PCM_POSTPROCESS_ENABLE) && defined(MPEG_PCE_MIXDOWN_ENABLE)
+ #ifdef TP_PCE_ENABLE
if (pceRead == 1 || CProgramConfig_IsValid(pce)) {
/* Set matrix mixdown infos if available from PCE. */
pcmDmx_SetMatrixMixdownFromPce ( self->hPcmUtils,
@@ -1502,7 +1515,7 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
pce->MatrixMixdownIndex,
pce->PseudoSurroundEnable );
}
-#endif
+ #endif
/* If there is no valid data to transfrom into time domain, return. */
if ( ! IS_OUTPUT_VALID(ErrorStatus) ) {
diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp
index 379c84c..763981b 100644
--- a/libAACdec/src/aacdecoder_lib.cpp
+++ b/libAACdec/src/aacdecoder_lib.cpp
@@ -48,7 +48,7 @@
/* Decoder library info */
#define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 4
-#define AACDECODER_LIB_VL2 0
+#define AACDECODER_LIB_VL2 1
#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__
@@ -500,6 +500,8 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT
return NULL;
}
+ transportDec_SetParam(pIn, TPDEC_PARAM_IGNORE_BUFFERFULLNESS, 1);
+
/* Allocate AAC decoder core struct. */
aacDec = CAacDecoder_Open(transportFmt);