aboutsummaryrefslogtreecommitdiffstats
path: root/libDRCdec
diff options
context:
space:
mode:
Diffstat (limited to 'libDRCdec')
-rw-r--r--libDRCdec/include/FDK_drcDecLib.h11
-rw-r--r--libDRCdec/src/FDK_drcDecLib.cpp16
-rw-r--r--libDRCdec/src/drcDec_gainDecoder.cpp8
-rw-r--r--libDRCdec/src/drcDec_reader.cpp25
-rw-r--r--libDRCdec/src/drcDec_selectionProcess.cpp79
-rw-r--r--libDRCdec/src/drcDec_selectionProcess.h2
-rw-r--r--libDRCdec/src/drcDec_types.h3
-rw-r--r--libDRCdec/src/drcGainDec_preprocess.cpp5
8 files changed, 113 insertions, 36 deletions
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 4f8ebc7..26e5b78 100644
--- a/libDRCdec/src/FDK_drcDecLib.cpp
+++ b/libDRCdec/src/FDK_drcDecLib.cpp
@@ -112,7 +112,7 @@ amm-info@iis.fraunhofer.de
#define DRCDEC_LIB_VL1 1
#define DRCDEC_LIB_VL2 0
#define DRCDEC_LIB_TITLE "MPEG-D DRC Decoder Lib"
-#ifdef __ANDROID__
+#ifdef SUPPRESS_BUILD_DATE_INFO
#define DRCDEC_LIB_BUILD_DATE ""
#define DRCDEC_LIB_BUILD_TIME ""
#else
@@ -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;
@@ -515,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;
}
@@ -729,7 +735,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 +759,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 9b5403a..ca35345 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;
}
@@ -1018,6 +1021,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 +1071,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);
diff --git a/libDRCdec/src/drcDec_selectionProcess.cpp b/libDRCdec/src/drcDec_selectionProcess.cpp
index c33bf74..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,
@@ -753,8 +751,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 =
@@ -956,17 +954,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 +986,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 +1002,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 +1102,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(
@@ -1097,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,
@@ -1108,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(
@@ -2031,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;
@@ -2051,8 +2089,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 +2112,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 +2140,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 +2167,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 +2275,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_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,
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;
/****************/
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;