diff options
author | Dave Burke <daveburke@google.com> | 2012-05-12 13:17:25 -0700 |
---|---|---|
committer | Dave Burke <daveburke@google.com> | 2012-05-12 13:47:46 -0700 |
commit | 698b536f3b34a7cfc41a80e1034cc359456bdd66 (patch) | |
tree | fa3dfa75d535b188725f1b84316cb4b06db79771 /libAACdec | |
parent | 9bf37cc9712506b2483650c82d3c41152337ef7e (diff) | |
download | fdk-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.cpp | 64 | ||||
-rw-r--r-- | libAACdec/src/aacdec_drc_types.h | 8 | ||||
-rw-r--r-- | libAACdec/src/aacdec_hcrs.cpp | 3 | ||||
-rw-r--r-- | libAACdec/src/aacdec_tns.h | 2 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder.cpp | 73 | ||||
-rw-r--r-- | libAACdec/src/aacdecoder_lib.cpp | 4 |
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); |