Commit b9774f90 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi

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
parent 2ddc922d
...@@ -135,10 +135,13 @@ void aacDecoder_drcInit ( ...@@ -135,10 +135,13 @@ void aacDecoder_drcInit (
/* init params */ /* init params */
pParams = &self->params; pParams = &self->params;
pParams->bsDelayEnable = 0; pParams->bsDelayEnable = 0;
pParams->cut = FL2FXCONST_DBL(0.0f); pParams->cut = FL2FXCONST_DBL(0.0f);
pParams->boost = 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->targetRefLevel = AACDEC_DRC_DEFAULT_REF_LEVEL;
pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
pParams->applyHeavyCompression = 0;
/* initial program ref level = target ref level */ /* initial program ref level = target ref level */
self->progRefLevel = pParams->targetRefLevel; self->progRefLevel = pParams->targetRefLevel;
...@@ -193,7 +196,9 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -193,7 +196,9 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; 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; break;
case DRC_BOOST_SCALE: case DRC_BOOST_SCALE:
/* set boost factor */ /* set boost factor */
...@@ -204,7 +209,9 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -204,7 +209,9 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; 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; break;
case TARGET_REF_LEVEL: case TARGET_REF_LEVEL:
if ( value > MAX_REFERENCE_LEVEL if ( value > MAX_REFERENCE_LEVEL
...@@ -220,9 +227,11 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -220,9 +227,11 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
else { else {
/* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
self->digitalNorm = 1; self->digitalNorm = 1;
self->params.targetRefLevel = value; if (self->params.targetRefLevel != (SCHAR)value) {
self->progRefLevel = (SCHAR)value; /* Set the program reference level equal to the target self->params.targetRefLevel = (SCHAR)value;
level according to 4.5.2.7.3 of ISO/IEC 14496-3. */ 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; break;
case APPLY_HEAVY_COMPRESSION: case APPLY_HEAVY_COMPRESSION:
...@@ -232,7 +241,19 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( ...@@ -232,7 +241,19 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam (
if (self == NULL) { if (self == NULL) {
return AAC_DEC_INVALID_HANDLE; 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<<DRC_PARAM_SCALE));
self->params.cut = FL2FXCONST_DBL(1.0f/(float)(1<<DRC_PARAM_SCALE));
} else {
/* Restore the user params */
self->params.boost = self->params.usrBoost;
self->params.cut = self->params.usrCut;
}
/* Store new parameter value */
self->params.applyHeavyCompression = (UCHAR)value;
}
break; break;
case DRC_BS_DELAY: case DRC_BS_DELAY:
if (value < 0 || value > 1) { if (value < 0 || value > 1) {
...@@ -473,7 +494,7 @@ static int aacDecoder_drcParse ( ...@@ -473,7 +494,7 @@ static int aacDecoder_drcParse (
} }
} }
else { else {
pDrcBs->channelData.bandTop[0] = 255; pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */;
} }
pDrcBs->channelData.numBands = numBands; pDrcBs->channelData.numBands = numBands;
...@@ -627,10 +648,17 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -627,10 +648,17 @@ static int aacDecoder_drcExtractAndMap (
{ {
CDrcPayload threadBs[MAX_DRC_THREADS]; CDrcPayload threadBs[MAX_DRC_THREADS];
CDrcPayload *validThreadBs[MAX_DRC_THREADS]; CDrcPayload *validThreadBs[MAX_DRC_THREADS];
CDrcParams *pParams;
UINT backupBsPosition; UINT backupBsPosition;
int i, thread, validThreads = 0; int i, thread, validThreads = 0;
int numExcludedChns[MAX_DRC_THREADS]; int numExcludedChns[MAX_DRC_THREADS];
FDK_ASSERT(self != NULL);
FDK_ASSERT(hBs != NULL);
FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
pParams = &self->params;
self->numThreads = 0; self->numThreads = 0;
backupBsPosition = FDKgetValidBits(hBs); backupBsPosition = FDKgetValidBits(hBs);
...@@ -752,6 +780,7 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -752,6 +780,7 @@ static int aacDecoder_drcExtractAndMap (
*/ */
if (pThreadBs->progRefLevel >= 0) { if (pThreadBs->progRefLevel >= 0) {
self->progRefLevel = pThreadBs->progRefLevel; self->progRefLevel = pThreadBs->progRefLevel;
self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
} }
/* SCE, CPE and LFE */ /* SCE, CPE and LFE */
...@@ -769,6 +798,14 @@ static int aacDecoder_drcExtractAndMap ( ...@@ -769,6 +798,14 @@ static int aacDecoder_drcExtractAndMap (
/* CCEs not supported by now */ /* 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; return 0;
} }
......
...@@ -143,6 +143,16 @@ int aacDecoder_drcProlog ( ...@@ -143,6 +143,16 @@ int aacDecoder_drcProlog (
UCHAR channelMapping[], UCHAR channelMapping[],
int numChannels ); 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 ( void aacDecoder_drcApply (
HANDLE_AAC_DRC self, HANDLE_AAC_DRC self,
void *pSbrDec, void *pSbrDec,
......
...@@ -132,8 +132,10 @@ typedef struct ...@@ -132,8 +132,10 @@ typedef struct
typedef struct typedef struct
{ {
FIXP_DBL cut; FIXP_DBL cut; /* The attenuation scale factor currently used. */
FIXP_DBL boost; 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; UINT expiryFrame;
SCHAR targetRefLevel; SCHAR targetRefLevel;
...@@ -154,6 +156,8 @@ typedef struct ...@@ -154,6 +156,8 @@ typedef struct
USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */ USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */
SCHAR progRefLevel; /* Program reference level for all channels */ 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 */ 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 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 */ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */
......
...@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de ...@@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL0 2
#define AACDECODER_LIB_VL1 5 #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_TITLE "AAC Decoder Lib"
#define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_DATE __DATE__
#define AACDECODER_LIB_BUILD_TIME __TIME__ #define AACDECODER_LIB_BUILD_TIME __TIME__
......
...@@ -127,8 +127,8 @@ void sbrDecoder_drcInitChannel ( ...@@ -127,8 +127,8 @@ void sbrDecoder_drcInitChannel (
hDrcData->currFact_exp = 1; hDrcData->currFact_exp = 1;
hDrcData->nextFact_exp = 1; hDrcData->nextFact_exp = 1;
hDrcData->numBandsCurr = 0; hDrcData->numBandsCurr = 1;
hDrcData->numBandsNext = 0; hDrcData->numBandsNext = 1;
hDrcData->winSequenceCurr = 0; hDrcData->winSequenceCurr = 0;
hDrcData->winSequenceNext = 0; hDrcData->winSequenceNext = 0;
...@@ -490,9 +490,7 @@ void sbrDecoder_drcApply ( ...@@ -490,9 +490,7 @@ void sbrDecoder_drcApply (
if (hDrcData == NULL) { if (hDrcData == NULL) {
return; return;
} }
if ( (hDrcData->enable == 0) if (hDrcData->enable == 0) {
|| ((hDrcData->numBandsCurr == 0) && (hDrcData->numBandsNext == 0))
) {
return; /* Avoid changing the scaleFactor even though the processing is disabled. */ return; /* Avoid changing the scaleFactor even though the processing is disabled. */
} }
......
...@@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de ...@@ -137,7 +137,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define SBRDECODER_LIB_VL0 2 #define SBRDECODER_LIB_VL0 2
#define SBRDECODER_LIB_VL1 2 #define SBRDECODER_LIB_VL1 2
#define SBRDECODER_LIB_VL2 1 #define SBRDECODER_LIB_VL2 2
#define SBRDECODER_LIB_TITLE "SBR Decoder" #define SBRDECODER_LIB_TITLE "SBR Decoder"
#define SBRDECODER_LIB_BUILD_DATE __DATE__ #define SBRDECODER_LIB_BUILD_DATE __DATE__
#define SBRDECODER_LIB_BUILD_TIME __TIME__ #define SBRDECODER_LIB_BUILD_TIME __TIME__
...@@ -878,7 +878,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self, ...@@ -878,7 +878,7 @@ void sbrDecoder_drcDisable ( HANDLE_SBRDECODER self,
pSbrDrcChannelData = sbrDecoder_drcGetChannel( self, ch ); pSbrDrcChannelData = sbrDecoder_drcGetChannel( self, ch );
if ( pSbrDrcChannelData != NULL ) { if ( pSbrDrcChannelData != NULL ) {
pSbrDrcChannelData->enable = 0; sbrDecoder_drcInitChannel( pSbrDrcChannelData );
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment