Fix HE-AAC using MPEG-D DRC with implicit SBR signaling.

Bug: 132641988
Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc
Change-Id: I97c5d3972528092f627153ad3127c7db977a0e5d
This commit is contained in:
Fraunhofer IIS FDK 2019-03-08 16:08:07 +01:00 committed by Jean-Michel Trivi
parent 14f7e13693
commit e970ac4c95
7 changed files with 140 additions and 95 deletions

View File

@ -1676,6 +1676,13 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
reverseOutChannelMap[ch] = ch;
}
/* Update sampleRate and frameSize. This may be necessary in case of
* implicit SBR signaling */
FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_SAMPLE_RATE,
self->streamInfo.sampleRate);
FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_FRAME_SIZE,
self->streamInfo.frameSize);
/* If SBR and/or MPS is active, the DRC gains are aligned to the QMF
domain signal before the QMF synthesis. Therefore the DRC gains
need to be delayed by the QMF synthesis delay. */

View File

@ -142,6 +142,8 @@ typedef enum {
choosing an appropriate
downmixInstruction */
DRC_DEC_BASE_CHANNEL_COUNT,
DRC_DEC_FRAME_SIZE,
DRC_DEC_SAMPLE_RATE,
/* get only system parameters */
DRC_DEC_IS_MULTIBAND_DRC_1,
DRC_DEC_IS_MULTIBAND_DRC_2,

View File

@ -336,7 +336,13 @@ FDK_drcDec_Init(HANDLE_DRC_DECODER hDrcDec, const int frameSize,
}
if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec, frameSize, sampleRate);
dErr = drcDec_GainDecoder_SetParam(hDrcDec->hGainDec, GAIN_DEC_FRAME_SIZE,
frameSize);
if (dErr) return DRC_DEC_NOT_OK;
dErr = drcDec_GainDecoder_SetParam(hDrcDec->hGainDec, GAIN_DEC_SAMPLE_RATE,
sampleRate);
if (dErr) return DRC_DEC_NOT_OK;
dErr = drcDec_GainDecoder_Init(hDrcDec->hGainDec);
if (dErr) return DRC_DEC_NOT_OK;
}
@ -377,79 +383,99 @@ DRC_DEC_ERROR
FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
const DRC_DEC_USERPARAM requestType,
const FIXP_DBL requestValue) {
DRC_ERROR dErr = DE_OK;
DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
int invalidParameter = 0;
if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
if (hDrcDec->functionalRange == DRC_DEC_GAIN)
return DRC_DEC_NOT_OK; /* not supported for DRC_DEC_GAIN. All parameters are
handed over to selection process lib. */
switch (requestType) {
case DRC_DEC_BOOST:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_BOOST, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_COMPRESS:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_COMPRESS, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_LOUDNESS_NORMALIZATION_ON:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON,
requestValue, &(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_TARGET_LOUDNESS:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_EFFECT_TYPE:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_DOWNMIX_ID:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_DOWNMIX_ID, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_BASE_CHANNEL_COUNT:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_NOT_OK;
break;
case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
requestValue, &(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_ALBUM_MODE:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_ALBUM_MODE, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
default:
return DRC_DEC_INVALID_PARAM;
if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
switch (requestType) {
case DRC_DEC_SAMPLE_RATE:
dErr = drcDec_GainDecoder_SetParam(
hDrcDec->hGainDec, GAIN_DEC_SAMPLE_RATE, (int)requestValue);
if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_FRAME_SIZE:
dErr = drcDec_GainDecoder_SetParam(
hDrcDec->hGainDec, GAIN_DEC_FRAME_SIZE, (int)requestValue);
if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
default:
invalidParameter |= DRC_DEC_GAIN;
}
}
if (hDrcDec->functionalRange & DRC_DEC_SELECTION) {
switch (requestType) {
case DRC_DEC_BOOST:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_BOOST, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_COMPRESS:
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc,
SEL_PROC_COMPRESS, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_LOUDNESS_NORMALIZATION_ON:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_NORMALIZATION_ON,
requestValue, &(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_TARGET_LOUDNESS:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_TARGET_LOUDNESS, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_EFFECT_TYPE:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_EFFECT_TYPE, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_DOWNMIX_ID:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_DOWNMIX_ID, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_TARGET_CHANNEL_COUNT,
requestValue, &(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_BASE_CHANNEL_COUNT:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_BASE_CHANNEL_COUNT, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_NOT_OK;
break;
case DRC_DEC_LOUDNESS_MEASUREMENT_METHOD:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_LOUDNESS_MEASUREMENT_METHOD,
requestValue, &(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
case DRC_DEC_ALBUM_MODE:
sErr = drcDec_SelectionProcess_SetParam(
hDrcDec->hSelectionProc, SEL_PROC_ALBUM_MODE, requestValue,
&(hDrcDec->selProcInputDiff));
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
break;
default:
invalidParameter |= DRC_DEC_SELECTION;
}
}
if (invalidParameter == hDrcDec->functionalRange)
return DRC_DEC_INVALID_PARAM;
/* All parameters need a new start of the selection process */
startSelectionProcess(hDrcDec);

View File

@ -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
@ -170,11 +170,10 @@ drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
}
DRC_ERROR
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
const int sampleRate) {
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec) {
DRC_ERROR err = DE_OK;
err = initGainDec(hGainDec, frameSize, sampleRate);
err = initGainDec(hGainDec);
if (err) return err;
initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
@ -182,6 +181,25 @@ drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
return err;
}
DRC_ERROR
drcDec_GainDecoder_SetParam(HANDLE_DRC_GAIN_DECODER hGainDec,
const GAIN_DEC_PARAM paramType,
const int paramValue) {
switch (paramType) {
case GAIN_DEC_FRAME_SIZE:
if (paramValue < 0) return DE_PARAM_OUT_OF_RANGE;
hGainDec->frameSize = paramValue;
break;
case GAIN_DEC_SAMPLE_RATE:
if (paramValue < 0) return DE_PARAM_OUT_OF_RANGE;
hGainDec->deltaTminDefault = getDeltaTmin(paramValue);
break;
default:
return DE_PARAM_INVALID;
}
return DE_OK;
}
DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters(
HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,

View File

@ -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
@ -134,6 +134,8 @@ typedef enum {
GAIN_DEC_DRC2_DRC3
} GAIN_DEC_LOCATION;
typedef enum { GAIN_DEC_FRAME_SIZE, GAIN_DEC_SAMPLE_RATE } GAIN_DEC_PARAM;
typedef struct {
FIXP_DBL gainLin; /* e = 7 */
SHORT time;
@ -195,8 +197,12 @@ DRC_ERROR
drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec);
DRC_ERROR
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
const int sampleRate);
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec);
DRC_ERROR
drcDec_GainDecoder_SetParam(HANDLE_DRC_GAIN_DECODER hGainDec,
const GAIN_DEC_PARAM paramType,
const int paramValue);
DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters(

View File

@ -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
@ -184,24 +184,11 @@ static DRC_ERROR _generateDrcInstructionsDerivedData(
}
DRC_ERROR
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
const int sampleRate) {
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec) {
int i, j, k;
if (frameSize < 1) {
return DE_NOT_OK;
}
hGainDec->frameSize = frameSize;
if (hGainDec->frameSize * 1000 < sampleRate) {
return DE_NOT_OK;
}
hGainDec->deltaTminDefault = getDeltaTmin(sampleRate);
if (hGainDec->deltaTminDefault > hGainDec->frameSize) {
return DE_NOT_OK;
}
/* sanity check */
if (hGainDec->deltaTminDefault > hGainDec->frameSize) return DE_NOT_OK;
for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
for (j = 0; j < 8; j++) {

View File

@ -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
@ -104,8 +104,7 @@ amm-info@iis.fraunhofer.de
#define DRCGAINDEC_INIT_H
DRC_ERROR
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
const int sampleRate);
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec);
void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers);