From b9774f90651be61065ae40171fc321f6ced60e49 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 27 Aug 2013 16:20:46 -0700 Subject: Decode dynamic range control improvements * AAC-Decoder - Only set the program reference level if it has changed compared to the previous value. This allows setting it on a frame-by-frame basis without limitations. Modified file(s): libAACdec/src/aacdec_drc.cpp libAACdec/src/aacdec_drc.h - Add expiry counter for the program reference level. Modified file(s): libAACdec/src/aacdec_drc.cpp libAACdec/src/aacdec_drc_types.h - Disable scaling of light compression gain values when heavy compression mode is enabled to have the full light compression as fallback if no heavy values are available. Modified file(s): libAACdec/src/aacdec_drc.cpp libAACdec/src/aacdecoder_lib.cpp libAACdec/src/aacdec_drc_types.h - Change initialization and channel disabling to improve start-up behavior in SBR decoder. Modified file(s): libSBRdec/src/sbrdecoder.cpp libSBRdec/src/sbrdec_drc.cpp Bug 9428126 Change-Id: Ie1d3949c53910506da2547d32fe3bf6ee7606eb4 --- libAACdec/src/aacdec_drc.cpp | 55 +++++++++++++++++++++++++++++++++------- libAACdec/src/aacdec_drc.h | 10 ++++++++ libAACdec/src/aacdec_drc_types.h | 8 ++++-- libAACdec/src/aacdecoder_lib.cpp | 2 +- 4 files changed, 63 insertions(+), 12 deletions(-) (limited to 'libAACdec/src') diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 942a651..2666454 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -135,10 +135,13 @@ void aacDecoder_drcInit ( /* init params */ pParams = &self->params; pParams->bsDelayEnable = 0; - pParams->cut = FL2FXCONST_DBL(0.0f); - pParams->boost = FL2FXCONST_DBL(0.0f); + pParams->cut = FL2FXCONST_DBL(0.0f); + pParams->usrCut = FL2FXCONST_DBL(0.0f); + pParams->boost = FL2FXCONST_DBL(0.0f); + pParams->usrBoost = FL2FXCONST_DBL(0.0f); pParams->targetRefLevel = AACDEC_DRC_DEFAULT_REF_LEVEL; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; + pParams->applyHeavyCompression = 0; /* initial program ref level = target ref level */ self->progRefLevel = pParams->targetRefLevel; @@ -193,7 +196,9 @@ 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); + self->params.usrCut = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value); + if (self->params.applyHeavyCompression == 0) + self->params.cut = self->params.usrCut; break; case DRC_BOOST_SCALE: /* set boost factor */ @@ -204,7 +209,9 @@ 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); + self->params.usrBoost = (FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP>>DRC_PARAM_SCALE) * (INT)value); + if (self->params.applyHeavyCompression == 0) + self->params.boost = self->params.usrBoost; break; case TARGET_REF_LEVEL: if ( value > MAX_REFERENCE_LEVEL @@ -220,9 +227,11 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( else { /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ self->digitalNorm = 1; - self->params.targetRefLevel = value; - self->progRefLevel = (SCHAR)value; /* Set the program reference level equal to the target - level according to 4.5.2.7.3 of ISO/IEC 14496-3. */ + if (self->params.targetRefLevel != (SCHAR)value) { + self->params.targetRefLevel = (SCHAR)value; + self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the + target level according to 4.5.2.7.3 of ISO/IEC 14496-3. */ + } } break; case APPLY_HEAVY_COMPRESSION: @@ -232,7 +241,19 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( if (self == NULL) { return AAC_DEC_INVALID_HANDLE; } - self->params.applyHeavyCompression = (UCHAR)value; + if (self->params.applyHeavyCompression != (UCHAR)value) { + if (value == 1) { + /* Disable scaling of DRC values by setting the max values */ + self->params.boost = FL2FXCONST_DBL(1.0f/(float)(1<params.cut = FL2FXCONST_DBL(1.0f/(float)(1<params.boost = self->params.usrBoost; + self->params.cut = self->params.usrCut; + } + /* Store new parameter value */ + self->params.applyHeavyCompression = (UCHAR)value; + } break; case DRC_BS_DELAY: if (value < 0 || value > 1) { @@ -473,7 +494,7 @@ static int aacDecoder_drcParse ( } } else { - pDrcBs->channelData.bandTop[0] = 255; + pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */; } pDrcBs->channelData.numBands = numBands; @@ -627,10 +648,17 @@ static int aacDecoder_drcExtractAndMap ( { CDrcPayload threadBs[MAX_DRC_THREADS]; CDrcPayload *validThreadBs[MAX_DRC_THREADS]; + CDrcParams *pParams; UINT backupBsPosition; int i, thread, validThreads = 0; int numExcludedChns[MAX_DRC_THREADS]; + FDK_ASSERT(self != NULL); + FDK_ASSERT(hBs != NULL); + FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL); + + pParams = &self->params; + self->numThreads = 0; backupBsPosition = FDKgetValidBits(hBs); @@ -752,6 +780,7 @@ static int aacDecoder_drcExtractAndMap ( */ if (pThreadBs->progRefLevel >= 0) { self->progRefLevel = pThreadBs->progRefLevel; + self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ } /* SCE, CPE and LFE */ @@ -769,6 +798,14 @@ static int aacDecoder_drcExtractAndMap ( /* CCEs not supported by now */ } + /* Increment and check expiry counter for the program reference level: */ + if ( (pParams->expiryFrame > 0) + && (self->prlExpiryCount++ > pParams->expiryFrame) ) + { /* The program reference level is too old, so set it back to the target level. */ + self->progRefLevel = pParams->targetRefLevel; + self->prlExpiryCount = 0; + } + return 0; } diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 124b6f5..2ebae2c 100644 --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -143,6 +143,16 @@ int aacDecoder_drcProlog ( UCHAR channelMapping[], int numChannels ); +/** + * \brief Apply DRC. If SBR is present, DRC data is handed over to the SBR decoder. + * \param self AAC decoder instance + * \param pSbrDec pointer to SBR decoder instance + * \param pAacDecoderChannelInfo AAC decoder channel instance to be processed + * \param pDrcDat DRC channel data + * \param ch channel index + * \param aacFrameSize AAC frame size + * \param bSbrPresent flag indicating that SBR is present, in which case DRC is handed over to the SBR instance pSbrDec + */ void aacDecoder_drcApply ( HANDLE_AAC_DRC self, void *pSbrDec, diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index e7c6f1a..1b5cd76 100644 --- a/libAACdec/src/aacdec_drc_types.h +++ b/libAACdec/src/aacdec_drc_types.h @@ -132,8 +132,10 @@ typedef struct typedef struct { - FIXP_DBL cut; - FIXP_DBL boost; + FIXP_DBL cut; /* The attenuation scale factor currently used. */ + FIXP_DBL usrCut; /* The latest attenuation scale factor set by user. */ + FIXP_DBL boost; /* The boost scale factor currently used. */ + FIXP_DBL usrBoost; /* The latest boost scale factor set by user. */ UINT expiryFrame; SCHAR targetRefLevel; @@ -154,6 +156,8 @@ typedef struct USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */ SCHAR progRefLevel; /* Program reference level for all channels */ + UINT prlExpiryCount; /* Counter that can be used to monitor the life time of the program reference level. */ + UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data is present or not */ UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload position in the bitstream (only one per frame) */ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 5f0be30..247fcef 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL1 5 -#define AACDECODER_LIB_VL2 2 +#define AACDECODER_LIB_VL2 3 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_TIME __TIME__ -- cgit v1.2.3