diff options
Diffstat (limited to 'libAACdec/src/aacdec_drc.cpp')
-rw-r--r-- | libAACdec/src/aacdec_drc.cpp | 104 |
1 files changed, 89 insertions, 15 deletions
diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index 2666454..0c33a2b 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -130,7 +130,6 @@ void aacDecoder_drcInit ( /* init control fields */ self->enable = 0; self->numThreads = 0; - self->digitalNorm = 0; /* init params */ pParams = &self->params; @@ -139,12 +138,15 @@ void aacDecoder_drcInit ( 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 = -1; pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES; + pParams->applyDigitalNorm = 0; pParams->applyHeavyCompression = 0; /* initial program ref level = target ref level */ self->progRefLevel = pParams->targetRefLevel; + self->progRefLevelPresent = 0; + self->presMode = -1; } @@ -222,11 +224,12 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( return AAC_DEC_INVALID_HANDLE; } if (value < 0) { - self->digitalNorm = 0; + self->params.applyDigitalNorm = 0; + self->params.targetRefLevel = -1; } else { /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ - self->digitalNorm = 1; + self->params.applyDigitalNorm = 1; if (self->params.targetRefLevel != (SCHAR)value) { self->params.targetRefLevel = (SCHAR)value; self->progRefLevel = (SCHAR)value; /* Always set the program reference level equal to the @@ -234,6 +237,16 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( } } break; + case APPLY_NORMALIZATION: + if (value < 0 || value > 1) { + return AAC_DEC_SET_PARAM_FAIL; + } + if (self == NULL) { + return AAC_DEC_INVALID_HANDLE; + } + /* Store new parameter value */ + self->params.applyDigitalNorm = (UCHAR)value; + break; case APPLY_HEAVY_COMPRESSION: if (value < 0 || value > 1) { return AAC_DEC_SET_PARAM_FAIL; @@ -278,7 +291,7 @@ AAC_DECODER_ERROR aacDecoder_drcSetParam ( self->enable = ( (self->params.boost > (FIXP_DBL)0) || (self->params.cut > (FIXP_DBL)0) || (self->params.applyHeavyCompression != 0) - || (self->digitalNorm == 1) ); + || (self->params.targetRefLevel >= 0) ); return ErrorStatus; @@ -539,7 +552,7 @@ static int aacDecoder_drcReadCompression ( UINT payloadPosition ) { int bitCnt = 0; - int dmxLevelsPresent, compressionPresent; + int dmxLevelsPresent, extensionPresent, compressionPresent; int coarseGrainTcPresent, fineGrainTcPresent; /* Move to the beginning of the DRC payload field */ @@ -561,8 +574,9 @@ static int aacDecoder_drcReadCompression ( return 0; } FDKreadBits(bs, 2); /* dolby_surround_mode */ - FDKreadBits(bs, 2); /* presentation_mode */ - if (FDKreadBits(bs, 2) != 0) { /* reserved, set to 0 */ + pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */ + FDKreadBits(bs, 1); /* stereo_downmix_mode */ + if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ return 0; } @@ -571,9 +585,7 @@ static int aacDecoder_drcReadCompression ( return 0; } dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */ - if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ - return 0; - } + extensionPresent = FDKreadBits(bs, 1); /* ancillary_data_extension_status; */ compressionPresent = FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */ coarseGrainTcPresent = FDKreadBits(bs, 1); /* coarse_grain_timecode_status */ fineGrainTcPresent = FDKreadBits(bs, 1); /* fine_grain_timecode_status */ @@ -631,6 +643,19 @@ static int aacDecoder_drcReadCompression ( bitCnt += 16; } + /* Read extension just to get the right amount of bits. */ + if (extensionPresent) { + int extBits = 8; + + FDKreadBits(bs, 1); /* reserved, set to 0 */ + if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_levels_status */ + if (FDKreadBits(bs, 1)) extBits += 16; /* ext_downmixing_global_gains_status */ + if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_lfe_level_status */ + + FDKpushFor(bs, extBits - 4); /* skip the extension payload remainder. */ + bitCnt += extBits; + } + return (bitCnt); } @@ -780,9 +805,15 @@ static int aacDecoder_drcExtractAndMap ( */ if (pThreadBs->progRefLevel >= 0) { self->progRefLevel = pThreadBs->progRefLevel; + self->progRefLevelPresent = 1; self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ } + if (drcPayloadType == DVB_DRC_ANC_DATA) { + /* Announce the presentation mode of this valid thread. */ + self->presMode = pThreadBs->presMode; + } + /* SCE, CPE and LFE */ for (ch = 0; ch < validChannels; ch++) { int mapedChannel = channelMapping[ch]; @@ -802,6 +833,7 @@ static int aacDecoder_drcExtractAndMap ( if ( (pParams->expiryFrame > 0) && (self->prlExpiryCount++ > pParams->expiryFrame) ) { /* The program reference level is too old, so set it back to the target level. */ + self->progRefLevelPresent = 0; self->progRefLevel = pParams->targetRefLevel; self->prlExpiryCount = 0; } @@ -815,6 +847,7 @@ void aacDecoder_drcApply ( void *pSbrDec, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CDrcChannelData *pDrcChData, + FIXP_DBL *extGain, int ch, /* needed only for SBR */ int aacFrameSize, int bSbrPresent ) @@ -826,8 +859,8 @@ void aacDecoder_drcApply ( FIXP_DBL max_mantissa; INT max_exponent; - FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.0f); - INT norm_exponent = 0; + FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f); + INT norm_exponent = 1; FIXP_DBL fact_mantissa[MAX_DRC_BANDS]; INT fact_exponent[MAX_DRC_BANDS]; @@ -849,6 +882,15 @@ void aacDecoder_drcApply ( if (!self->enable) { sbrDecoder_drcDisable( (HANDLE_SBRDECODER)pSbrDec, ch ); + if (extGain != NULL) { + INT gainScale = (INT)*extGain; + /* The gain scaling must be passed to the function in the buffer pointed on by extGain. */ + if (gainScale >= 0 && gainScale <= DFRACT_BITS) { + *extGain = scaleValue(norm_mantissa, norm_exponent-gainScale); + } else { + FDK_ASSERT(0); + } + } return; } @@ -864,7 +906,7 @@ void aacDecoder_drcApply ( reduced DAC SNR (if signal is attenuated) or clipping (if signal is boosted) */ - if (self->digitalNorm == 1) + if (pParams->targetRefLevel >= 0) { /* 0.5^((targetRefLevel - progRefLevel)/24) */ norm_mantissa = fLdPow( @@ -874,7 +916,18 @@ void aacDecoder_drcApply ( 3, &norm_exponent ); } - else { + /* Always export the normalization gain (if possible). */ + if (extGain != NULL) { + INT gainScale = (INT)*extGain; + /* The gain scaling must be passed to the function in the buffer pointed on by extGain. */ + if (gainScale >= 0 && gainScale <= DFRACT_BITS) { + *extGain = scaleValue(norm_mantissa, norm_exponent-gainScale); + } else { + FDK_ASSERT(0); + } + } + if (self->params.applyDigitalNorm == 0) { + /* Reset normalization gain since this module must not apply it */ norm_mantissa = FL2FXCONST_DBL(0.5f); norm_exponent = 1; } @@ -1112,3 +1165,24 @@ int aacDecoder_drcEpilog ( return err; } +/* + * Export relevant metadata info from bitstream payload. + */ +void aacDecoder_drcGetInfo ( + HANDLE_AAC_DRC self, + SCHAR *pPresMode, + SCHAR *pProgRefLevel ) +{ + if (self != NULL) { + if (pPresMode != NULL) { + *pPresMode = self->presMode; + } + if (pProgRefLevel != NULL) { + if (self->progRefLevelPresent) { + *pProgRefLevel = self->progRefLevel; + } else { + *pProgRefLevel = -1; + } + } + } +} |