Extend decoder API with audio output loudness info (FDKdec v3.1.3).

Bug: 148385721
Test: atest DecoderTestXheAac DecoderTestAacDrc
Change-Id: I68b09883def21baef259c9ab914922567ab8cee3
This commit is contained in:
Fraunhofer IIS FDK 2019-12-19 17:21:07 +01:00 committed by Jean-Michel Trivi
parent 3255d513ce
commit 31f66f6d3f
8 changed files with 71 additions and 19 deletions

Binary file not shown.

View File

@ -892,15 +892,25 @@ typedef struct {
1770. If no level has been found in the bitstream the 1770. If no level has been found in the bitstream the
value is -1. */ value is -1. */
SCHAR SCHAR
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
this field indicates whether light (MPEG-4 Dynamic Range this field indicates whether light (MPEG-4 Dynamic Range
Control tool) or heavy compression (DVB heavy Control tool) or heavy compression (DVB heavy
compression) dynamic range control shall take priority compression) dynamic range control shall take priority
on the outputs. For details, see ETSI TS 101 154, table on the outputs. For details, see ETSI TS 101 154, table
C.33. Possible values are: \n -1: No corresponding C.33. Possible values are: \n -1: No corresponding
metadata found in the bitstream \n 0: DRC presentation metadata found in the bitstream \n 0: DRC presentation
mode not indicated \n 1: DRC presentation mode 1 \n 2: mode not indicated \n 1: DRC presentation mode 1 \n 2:
DRC presentation mode 2 \n 3: Reserved */ 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; } CStreamInfo;

View File

@ -1225,6 +1225,8 @@ static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
pStreamInfo->drcProgRefLev = pStreamInfo->drcProgRefLev =
-1; /* set program reference level to not indicated */ -1; /* set program reference level to not indicated */
pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
pStreamInfo->outputLoudness = -1; /* default: no loudness metadata present */
} }
/*! /*!

View File

@ -120,7 +120,7 @@ amm-info@iis.fraunhofer.de
/* Decoder library info */ /* Decoder library info */
#define AACDECODER_LIB_VL0 3 #define AACDECODER_LIB_VL0 3
#define AACDECODER_LIB_VL1 1 #define AACDECODER_LIB_VL1 1
#define AACDECODER_LIB_VL2 2 #define AACDECODER_LIB_VL2 3
#define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_TITLE "AAC Decoder Lib"
#ifdef __ANDROID__ #ifdef __ANDROID__
#define AACDECODER_LIB_BUILD_DATE "" #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) { if (self->streamInfo.extAot != AOT_AAC_SLS) {
INT pcmLimiterScale = 0; INT pcmLimiterScale = 0;

View File

@ -114,6 +114,8 @@ amm-info@iis.fraunhofer.de
extern "C" { extern "C" {
#endif #endif
#define DRC_DEC_LOUDNESS_NOT_PRESENT (LONG)0x7FFFFFFE
typedef struct s_drc_decoder* HANDLE_DRC_DECODER; typedef struct s_drc_decoder* HANDLE_DRC_DECODER;
typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE; typedef struct s_uni_drc_interface* HANDLE_UNI_DRC_INTERFACE;
typedef struct s_selection_process_output* HANDLE_SEL_PROC_OUTPUT; 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 DRC_DEC_IS_ACTIVE, /**< MPEG-D DRC payload is present and at least one of
Dynamic Range Control (DRC) or Loudness Normalization Dynamic Range Control (DRC) or Loudness Normalization
(LN) is activated */ (LN) is activated */
DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED /**< number of output channels if DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED, /**< number of output channels if
appropriate downmixInstruction exists 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; } DRC_DEC_USERPARAM;
typedef enum { typedef enum {

View File

@ -519,6 +519,8 @@ LONG FDK_drcDec_GetParam(HANDLE_DRC_DECODER hDrcDec,
} }
case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED: case DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED:
return (LONG)hDrcDec->selProcOutput.targetChannelCount; return (LONG)hDrcDec->selProcOutput.targetChannelCount;
case DRC_DEC_OUTPUT_LOUDNESS:
return (LONG)hDrcDec->selProcOutput.outputLoudness;
default: default:
return 0; return 0;
} }

View File

@ -103,8 +103,6 @@ amm-info@iis.fraunhofer.de
#include "drcDec_selectionProcess.h" #include "drcDec_selectionProcess.h"
#include "drcDec_tools.h" #include "drcDec_tools.h"
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL) MAXVAL_DBL
typedef enum { typedef enum {
DETR_NONE = 0, DETR_NONE = 0,
DETR_NIGHT = 1, DETR_NIGHT = 1,
@ -1136,9 +1134,8 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
FIXP_DBL loudnessDeviationMax = FIXP_DBL loudnessDeviationMax =
((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7); ((FIXP_DBL)hSelProcInput->loudnessDeviationMax) << (DFRACT_BITS - 1 - 7);
;
if (hSelProcInput->loudnessNormalizationOn) { {
retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode, retVal = _getLoudness(hLoudnessInfoSet, hSelProcInput->albumMode,
hSelProcInput->loudnessMeasurementMethod, hSelProcInput->loudnessMeasurementMethod,
hSelProcInput->loudnessMeasurementSystem, hSelProcInput->loudnessMeasurementSystem,
@ -1147,9 +1144,10 @@ static DRCDEC_SELECTION_PROCESS_RETURN _preSelectionRequirement8(
hSelProcInput->downmixIdRequested[downmixIdIndex], hSelProcInput->downmixIdRequested[downmixIdIndex],
&loudnessNormalizationGainDb, &loudness); &loudnessNormalizationGainDb, &loudness);
if (retVal) return (retVal); if (retVal) return (retVal);
} else { }
if (!hSelProcInput->loudnessNormalizationOn) {
loudnessNormalizationGainDb = (FIXP_DBL)0; loudnessNormalizationGainDb = (FIXP_DBL)0;
loudness = UNDEFINED_LOUDNESS_VALUE;
} }
retVal = _getSignalPeakLevel( retVal = _getSignalPeakLevel(
@ -2070,6 +2068,7 @@ static DRCDEC_SELECTION_PROCESS_RETURN _generateOutputInfo(
pSelectionData->loudnessNormalizationGainDbAdjusted + pSelectionData->loudnessNormalizationGainDbAdjusted +
hSelProcInput->loudnessNormalizationGainModificationDb; hSelProcInput->loudnessNormalizationGainModificationDb;
hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel; hSelProcOutput->outputPeakLevelDb = pSelectionData->outputPeakLevel;
hSelProcOutput->outputLoudness = pSelectionData->outputLoudness;
hSelProcOutput->boost = boost; hSelProcOutput->boost = boost;
hSelProcOutput->compress = compress; hSelProcOutput->compress = compress;

View File

@ -111,6 +111,8 @@ amm-info@iis.fraunhofer.de
typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS; typedef struct s_drcdec_selection_process* HANDLE_DRC_SELECTION_PROCESS;
#define UNDEFINED_LOUDNESS_VALUE (FIXP_DBL)(MAXVAL_DBL - 1)
typedef enum { typedef enum {
DRCDEC_SELECTION_PROCESS_NO_ERROR = 0, DRCDEC_SELECTION_PROCESS_NO_ERROR = 0,