From 7104c00b44a4c447bde18d03c8f2e9590706e339 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Tue, 29 Oct 2019 13:10:37 +0100 Subject: Move array definition out of for loop in MPEG-D DRC _skipEqInstructions(). Bug: 145669488 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Icb71fb1cb8e0b64ae969276d08746f687a753467 --- libDRCdec/src/drcDec_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libDRCdec/src') diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp index a784457..9e37246 100644 --- a/libDRCdec/src/drcDec_reader.cpp +++ b/libDRCdec/src/drcDec_reader.cpp @@ -1018,6 +1018,7 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs, int additionalDrcSetIdPresent, additionalDrcSetIdCount; int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent, subbandGainsPresent, eqTransitionDurationPresent; + UCHAR eqChannelGroupForChannel[8]; FDKpushFor(hBs, 6); /* eqSetId */ FDKpushFor(hBs, 4); /* eqSetComplexityLevel */ @@ -1067,7 +1068,6 @@ static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs, eqChannelGroupCount = 0; for (c = 0; c < channelCount; c++) { - UCHAR eqChannelGroupForChannel[8]; int newGroup = 1; if (c >= 8) return DE_MEMORY_ERROR; eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7); -- cgit v1.2.3 From 3ce7751a440cafe41ff2eefb105b03096fbe122c Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 20 Dec 2018 15:52:47 +0100 Subject: Perform sanity check on DRC sets and improve the selection process Bug: 137282770 Bug: 141883493 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Ie8e17c82653cb0d9adcdb10ec3f4875b6207ac6f --- libDRCdec/src/FDK_drcDecLib.cpp | 12 +++++- libDRCdec/src/drcDec_gainDecoder.cpp | 8 ++-- libDRCdec/src/drcDec_reader.cpp | 23 ++++++----- libDRCdec/src/drcDec_selectionProcess.cpp | 64 +++++++++++++++++++++++++++---- libDRCdec/src/drcDec_types.h | 3 ++ 5 files changed, 88 insertions(+), 22 deletions(-) (limited to 'libDRCdec/src') diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index 4f8ebc7..e43279f 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -145,6 +145,10 @@ struct s_drc_decoder { SEL_PROC_OUTPUT selProcOutput; } DRC_DECODER; +static int _getGainStatus(HANDLE_UNI_DRC_GAIN hUniDrcGain) { + return hUniDrcGain->status; +} + static int isResetNeeded(HANDLE_DRC_DECODER hDrcDec, const SEL_PROC_OUTPUT oldSelProcOutput) { int i, resetNeeded = 0; @@ -729,7 +733,9 @@ FDK_drcDec_ReadUniDrcGain(HANDLE_DRC_DECODER hDrcDec, &(hDrcDec->uniDrcGain)); if (dErr) return DRC_DEC_NOT_OK; - hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + if (_getGainStatus(&(hDrcDec->uniDrcGain))) { + hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + } return DRC_DEC_OK; } @@ -751,7 +757,9 @@ FDK_drcDec_ReadUniDrc(HANDLE_DRC_DECODER hDrcDec, startSelectionProcess(hDrcDec); if (dErr) return DRC_DEC_NOT_OK; - hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + if (_getGainStatus(&(hDrcDec->uniDrcGain))) { + hDrcDec->status = DRC_DEC_NEW_GAIN_PAYLOAD; + } return DRC_DEC_OK; } diff --git a/libDRCdec/src/drcDec_gainDecoder.cpp b/libDRCdec/src/drcDec_gainDecoder.cpp index 9d91267..de54dde 100644 --- a/libDRCdec/src/drcDec_gainDecoder.cpp +++ b/libDRCdec/src/drcDec_gainDecoder.cpp @@ -297,9 +297,11 @@ drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec, int seq, gainSequenceCount; DRC_COEFFICIENTS_UNI_DRC* pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); - if (pCoef == NULL) return DE_OK; - - gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + if (pCoef && pCoef->gainSequenceCount) { + gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + } else { + gainSequenceCount = 1; + } for (seq = 0; seq < gainSequenceCount; seq++) { int lastNodeIndex = 0; diff --git a/libDRCdec/src/drcDec_reader.cpp b/libDRCdec/src/drcDec_reader.cpp index 9e37246..367a352 100644 --- a/libDRCdec/src/drcDec_reader.cpp +++ b/libDRCdec/src/drcDec_reader.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -199,11 +199,8 @@ drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig, } } - if (hUniDrcGain != NULL) { - err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault, - hUniDrcGain); - if (err) return err; - } + err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault, + hUniDrcGain); return err; } @@ -487,10 +484,13 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs, int seq, gainSequenceCount; DRC_COEFFICIENTS_UNI_DRC* pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); - if (pCoef == NULL) return DE_OK; - if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */ - - gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + if (hUniDrcGain == NULL) return DE_NOT_OK; + hUniDrcGain->status = 0; + if (pCoef) { + gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12); + } else { + gainSequenceCount = 0; + } for (seq = 0; seq < gainSequenceCount; seq++) { UCHAR index = pCoef->gainSetIndexForGainSequence[seq]; @@ -518,6 +518,9 @@ drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs, if (err) return err; } + if (err == DE_OK && gainSequenceCount > 0) { + hUniDrcGain->status = 1; + } return err; } diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index c33bf74..d806ae9 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -956,17 +956,31 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement4( return DRCDEC_SELECTION_PROCESS_NO_ERROR; } -/* #5: The number of DRC bands is supported. */ +/* #5: The number of DRC bands is supported. Moreover, gainSetIndex and + * gainSequenceIndex are within the allowed range. */ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( DRC_INSTRUCTIONS_UNI_DRC* pDrcInstructionUniDrc, DRC_COEFFICIENTS_UNI_DRC* pCoef, int* pMatchFound) { - int i; + int b, i; *pMatchFound = 1; + if (pDrcInstructionUniDrc->drcSetId < 0) /* virtual DRC sets are okay */ + { + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + if (pCoef == NULL) /* check for parametricDRC */ { - *pMatchFound = 1; + *pMatchFound = 0; /* parametricDRC not supported */ + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + + if (pCoef->drcLocation != + pDrcInstructionUniDrc + ->drcLocation) /* drcLocation must be LOCATION_SELECTED */ + { + *pMatchFound = 0; return DRCDEC_SELECTION_PROCESS_NO_ERROR; } @@ -974,10 +988,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( int indexDrcCoeff = pDrcInstructionUniDrc->gainSetIndexForChannelGroup[i]; int bandCount = 0; + if (indexDrcCoeff >= 12) { + *pMatchFound = 0; + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + if (indexDrcCoeff > pCoef->gainSetCount - 1) /* check for parametricDRC */ { - *pMatchFound = 1; - return DRCDEC_SELECTION_PROCESS_NO_ERROR; + continue; } GAIN_SET* gainSet = &(pCoef->gainSet[indexDrcCoeff]); @@ -986,6 +1004,14 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement5( if (bandCount > 4) { *pMatchFound = 0; } + + for (b = 0; b < bandCount; b++) { + if ((gainSet->gainSequenceIndex[b] >= 12) || + (gainSet->gainSequenceIndex[b] >= pCoef->gainSequenceCount)) { + *pMatchFound = 0; + return DRCDEC_SELECTION_PROCESS_NO_ERROR; + } + } } return DRCDEC_SELECTION_PROCESS_NO_ERROR; @@ -1078,6 +1104,19 @@ static int _targetLoudnessInRange( return retVal; } +static int _drcSetIsUsable(HANDLE_UNI_DRC_CONFIG hUniDrcConfig, + DRC_INSTRUCTIONS_UNI_DRC* pInst) { + int usable = 0; + DRC_COEFFICIENTS_UNI_DRC* pCoef = + selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED); + + /* check if ID is unique */ + if (selectDrcInstructions(hUniDrcConfig, pInst->drcSetId) != pInst) return 0; + /* sanity check on drcInstructions */ + _preSelectionRequirement5(pInst, pCoef, &usable); + return usable; +} + /* #8: The range of the target loudness specified for a DRC set has to include * the requested decoder target loudness. */ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( @@ -2051,8 +2090,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( int dependsOnDrcSetID = pSelectionData->pInst->dependsOnDrcSet; for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) { - if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId == - dependsOnDrcSetID) { + DRC_INSTRUCTIONS_UNI_DRC* pInst = + &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; + + if (pInst->drcSetId == dependsOnDrcSetID) { hSelProcOutput->selectedDrcSetIds[hSelProcOutput->numSelectedDrcSets] = hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId; hSelProcOutput->selectedDownmixIds[hSelProcOutput->numSelectedDrcSets] = @@ -2071,6 +2113,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & EB_FADE) { if (pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) { @@ -2098,6 +2141,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { for (j = 0; j < pInst->downmixIdCount; j++) { @@ -2124,6 +2168,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) { DRC_INSTRUCTIONS_UNI_DRC* pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]); + if (!_drcSetIsUsable(hUniDrcConfig, pInst)) continue; if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) { for (j = 0; j < pInst->downmixIdCount; j++) { @@ -2231,6 +2276,11 @@ static DRCDEC_SELECTION_PROCESS_RETURN _drcSetPreSelection( for (j = 0; j < hUniDrcConfig->drcInstructionsCountInclVirtual; j++) { DRC_INSTRUCTIONS_UNI_DRC* pDrcInstruction = &(hUniDrcConfig->drcInstructionsUniDrc[j]); + /* check if ID is unique */ + if (selectDrcInstructions(hUniDrcConfig, pDrcInstruction->drcSetId) != + pDrcInstruction) + continue; + retVal = _drcSetPreSelectionSingleInstruction( hSelProcInput, i, hUniDrcConfig, hLoudnessInfoSet, pDrcInstruction, *ppCandidatesPotential, *ppCandidatesSelected, codecMode); diff --git a/libDRCdec/src/drcDec_types.h b/libDRCdec/src/drcDec_types.h index 6b99018..b0d89c1 100644 --- a/libDRCdec/src/drcDec_types.h +++ b/libDRCdec/src/drcDec_types.h @@ -130,6 +130,9 @@ typedef struct { UCHAR uniDrcGainExtPresent; UNI_DRC_GAIN_EXTENSION uniDrcGainExtension; + + /* derived data */ + UCHAR status; } UNI_DRC_GAIN, *HANDLE_UNI_DRC_GAIN; /****************/ -- cgit v1.2.3 From cedcc475f52dd704497524dda6ec2ef430d2b6c5 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Wed, 13 Nov 2019 16:10:07 +0100 Subject: Reject undefined fPow() input data in _compressorIO_sigmoid_common(). Bug: 146938418 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: Iae4730ab5f5cef7c0ac8830831d25cfcaa567a99 --- libDRCdec/src/drcGainDec_preprocess.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libDRCdec/src') diff --git a/libDRCdec/src/drcGainDec_preprocess.cpp b/libDRCdec/src/drcGainDec_preprocess.cpp index c543c53..8d94ace 100644 --- a/libDRCdec/src/drcGainDec_preprocess.cpp +++ b/libDRCdec/src/drcGainDec_preprocess.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -285,6 +285,9 @@ static DRC_ERROR _compressorIO_sigmoid_common( &e_tmp2); invExp = fDivNorm(FL2FXCONST_DBL(1.0f / (float)(1 << 1)), exp, &e_invExp); e_invExp += 1 - 5; + if (tmp2 < (FIXP_DBL)0) { + return DE_NOT_OK; + } denom = fPow(tmp2, e_tmp2, invExp, e_invExp, &e_denom); *out = fDivNormSigned(tmp, denom, &e_out); e_out += 7 - e_denom; -- cgit v1.2.3 From 7d437ef090bc03cf628e34f00b3519c15789b0da Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:20:48 +0100 Subject: Request for Expert and Anchor loudness by default. Bug: 148385721 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I06b116b7d144b6959705119908a9db27946a0adb --- libDRCdec/src/drcDec_selectionProcess.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libDRCdec/src') diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index d806ae9..fe6034c 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -753,8 +753,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _initDefaultParams( hSelProcInput->loudnessNormalizationOn = 1; hSelProcInput->targetLoudness = FL2FXCONST_DBL(-24.0f / (float)(1 << 7)); hSelProcInput->loudnessDeviationMax = DEFAULT_LOUDNESS_DEVIATION_MAX; - hSelProcInput->loudnessMeasurementMethod = MDR_DEFAULT; - hSelProcInput->loudnessMeasurementSystem = MSR_DEFAULT; + hSelProcInput->loudnessMeasurementMethod = MDR_ANCHOR_LOUDNESS; + hSelProcInput->loudnessMeasurementSystem = MSR_EXPERT_PANEL; hSelProcInput->loudnessMeasurementPreProc = LPR_DEFAULT; hSelProcInput->deviceCutOffFrequency = 500; hSelProcInput->loudnessNormalizationGainDbMax = -- cgit v1.2.3 From 31f66f6d3ffcfa429c170b2c35250982d11f5082 Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Thu, 19 Dec 2019 17:21:07 +0100 Subject: Extend decoder API with audio output loudness info (FDKdec v3.1.3). Bug: 148385721 Test: atest DecoderTestXheAac DecoderTestAacDrc Change-Id: I68b09883def21baef259c9ab914922567ab8cee3 --- documentation/aacDecoder.pdf | Bin 488412 -> 494126 bytes libAACdec/include/aacdecoder_lib.h | 28 ++++++++++++++++-------- libAACdec/src/aacdecoder.cpp | 2 ++ libAACdec/src/aacdecoder_lib.cpp | 34 +++++++++++++++++++++++++++++- libDRCdec/include/FDK_drcDecLib.h | 11 +++++++--- libDRCdec/src/FDK_drcDecLib.cpp | 2 ++ libDRCdec/src/drcDec_selectionProcess.cpp | 11 +++++----- libDRCdec/src/drcDec_selectionProcess.h | 2 ++ 8 files changed, 71 insertions(+), 19 deletions(-) (limited to 'libDRCdec/src') diff --git a/documentation/aacDecoder.pdf b/documentation/aacDecoder.pdf index eb2a75e..f2131ed 100644 Binary files a/documentation/aacDecoder.pdf and b/documentation/aacDecoder.pdf differ diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index 6c2fda4..6084bd3 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -892,15 +892,25 @@ typedef struct { 1770. If no level has been found in the bitstream the value is -1. */ SCHAR - drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, - this field indicates whether light (MPEG-4 Dynamic Range - Control tool) or heavy compression (DVB heavy - compression) dynamic range control shall take priority - on the outputs. For details, see ETSI TS 101 154, table - C.33. Possible values are: \n -1: No corresponding - metadata found in the bitstream \n 0: DRC presentation - mode not indicated \n 1: DRC presentation mode 1 \n 2: - DRC presentation mode 2 \n 3: Reserved */ + drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, + this field indicates whether light (MPEG-4 Dynamic Range + Control tool) or heavy compression (DVB heavy + compression) dynamic range control shall take priority + on the outputs. For details, see ETSI TS 101 154, table + C.33. Possible values are: \n -1: No corresponding + metadata found in the bitstream \n 0: DRC presentation + mode not indicated \n 1: DRC presentation mode 1 \n 2: + DRC presentation mode 2 \n 3: Reserved */ + INT outputLoudness; /*!< Audio output loudness in steps of -0.25 dB. Range: 0 + (0 dBFS) to 231 (-57.75 dBFS).\n A value of -1 + indicates that no loudness metadata is present.\n If + loudness normalization is active, the value corresponds + to the target loudness value set with + ::AAC_DRC_REFERENCE_LEVEL.\n If loudness normalization + is not active, the output loudness value corresponds to + the loudness metadata given in the bitstream.\n + Loudness metadata can originate from MPEG-4 DRC or + MPEG-D DRC. */ } CStreamInfo; diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index bd12d96..f747b2d 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) { pStreamInfo->drcProgRefLev = -1; /* set program reference level to not indicated */ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */ + + pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */ } /*! diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index e90dbef..2ba0e86 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -120,7 +120,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 3 #define AACDECODER_LIB_VL1 1 -#define AACDECODER_LIB_VL2 2 +#define AACDECODER_LIB_VL2 3 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #ifdef __ANDROID__ #define AACDECODER_LIB_BUILD_DATE "" @@ -1764,6 +1764,38 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern, } } } + if (FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) { + /* return output loudness information for MPEG-D DRC */ + LONG outputLoudness = + FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_OUTPUT_LOUDNESS); + if (outputLoudness == DRC_DEC_LOUDNESS_NOT_PRESENT) { + /* no valid MPEG-D DRC loudness value contained */ + self->streamInfo.outputLoudness = -1; + } else { + if (outputLoudness > 0) { + /* positive output loudness values (very unusual) are limited to 0 + * dB */ + self->streamInfo.outputLoudness = 0; + } else { + self->streamInfo.outputLoudness = + -(INT)outputLoudness >> + 22; /* negate and scale from e = 7 to e = (31-2) */ + } + } + } else { + /* return output loudness information for MPEG-4 DRC */ + if (self->streamInfo.drcProgRefLev < + 0) { /* no MPEG-4 DRC loudness metadata contained */ + self->streamInfo.outputLoudness = -1; + } else { + if (self->defaultTargetLoudness < + 0) { /* loudness normalization is off */ + self->streamInfo.outputLoudness = self->streamInfo.drcProgRefLev; + } else { + self->streamInfo.outputLoudness = self->defaultTargetLoudness; + } + } + } if (self->streamInfo.extAot != AOT_AAC_SLS) { INT pcmLimiterScale = 0; diff --git a/libDRCdec/include/FDK_drcDecLib.h b/libDRCdec/include/FDK_drcDecLib.h index 2d28d23..79f8566 100644 --- a/libDRCdec/include/FDK_drcDecLib.h +++ b/libDRCdec/include/FDK_drcDecLib.h @@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de extern "C" { #endif +#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE + typedef struct s_drc_decoder* HANDLE_DRC_DECODER; typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE; typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT; @@ -150,9 +152,12 @@ typedef enum { DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of Dynamic Range Control (DRC) or Loudness Normalization (LN) is activated */ - DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if - appropriate downmixInstruction exists - */ + DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if + appropriate downmixInstruction + exists */ + DRC_DEC_OUTPUT_LOUDNESS /**< output loudness in dB, with exponent e = 7, or + DRC_DEC_LOUDNESS_NOT_PRESENT if no loudness is + contained in the bitstream */ } DRC_DEC_USERPARAM; typedef enum { diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index e43279f..83b5773 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -519,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec, } case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED: return (LONG)hDrcDec->selProcOutput.targetChannelCount; + case DRC_DEC_OUTPUT_LOUDNESS: + return (LONG)hDrcDec->selProcOutput.outputLoudness; default: return 0; } diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp index fe6034c..46ed740 100644 --- a/libDRCdec/src/drcDec_selectionProcess.cpp +++ b/libDRCdec/src/drcDec_selectionProcess.cpp @@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de #include "drcDec_selectionProcess.h" #include "drcDec_tools.h" -#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL - typedef enum { DETR_NONE = 0, DETR_NIGHT = 1, @@ -1136,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( FIXP_DBL loudnessDeviationMax = ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7); - ; - if (hSelProcInput->loudnessNormalizationOn) { + { retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode, hSelProcInput->loudnessMeasurementMethod, hSelProcInput->loudnessMeasurementSystem, @@ -1147,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8( hSelProcInput->downmixIdRequested[downmixIdIndex], &loudnessNormalizationGainDb, &loudness); if (retVal) return (retVal); - } else { + } + + if (!hSelProcInput->loudnessNormalizationOn) { loudnessNormalizationGainDb = (FIXP_DBL)0; - loudness = UNDEFINED_LOUDNESS_VALUE; } retVal = _getSignalPeakLevel( @@ -2070,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo( pSelectionData->loudnessNormalizationGainDbAdjusted + hSelProcInput->loudnessNormalizationGainModificationDb; hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel; + hSelProcOutput->outputLoudness = pSelectionData->outputLoudness; hSelProcOutput->boost = boost; hSelProcOutput->compress = compress; diff --git a/libDRCdec/src/drcDec_selectionProcess.h b/libDRCdec/src/drcDec_selectionProcess.h index 420bae6..0f878cf 100644 --- a/libDRCdec/src/drcDec_selectionProcess.h +++ b/libDRCdec/src/drcDec_selectionProcess.h @@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS; +#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1) + typedef enum { DRCDEC_SELECTION_PROCESS_NO_ERROR = 0, -- cgit v1.2.3