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; 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 /* 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 domain signal before the QMF synthesis. Therefore the DRC gains
need to be delayed by the QMF synthesis delay. */ need to be delayed by the QMF synthesis delay. */

View File

@ -142,6 +142,8 @@ typedef enum {
choosing an appropriate choosing an appropriate
downmixInstruction */ downmixInstruction */
DRC_DEC_BASE_CHANNEL_COUNT, DRC_DEC_BASE_CHANNEL_COUNT,
DRC_DEC_FRAME_SIZE,
DRC_DEC_SAMPLE_RATE,
/* get only system parameters */ /* get only system parameters */
DRC_DEC_IS_MULTIBAND_DRC_1, DRC_DEC_IS_MULTIBAND_DRC_1,
DRC_DEC_IS_MULTIBAND_DRC_2, 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) { 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; if (dErr) return DRC_DEC_NOT_OK;
} }
@ -377,79 +383,99 @@ DRC_DEC_ERROR
FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec, FDK_drcDec_SetParam(HANDLE_DRC_DECODER hDrcDec,
const DRC_DEC_USERPARAM requestType, const DRC_DEC_USERPARAM requestType,
const FIXP_DBL requestValue) { const FIXP_DBL requestValue) {
DRC_ERROR dErr = DE_OK;
DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR; DRCDEC_SELECTION_PROCESS_RETURN sErr = DRCDEC_SELECTION_PROCESS_NO_ERROR;
int invalidParameter = 0;
if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED; if (hDrcDec == NULL) return DRC_DEC_NOT_OPENED;
if (hDrcDec->functionalRange == DRC_DEC_GAIN) if (hDrcDec->functionalRange & DRC_DEC_GAIN) {
return DRC_DEC_NOT_OK; /* not supported for DRC_DEC_GAIN. All parameters are switch (requestType) {
handed over to selection process lib. */ case DRC_DEC_SAMPLE_RATE:
dErr = drcDec_GainDecoder_SetParam(
switch (requestType) { hDrcDec->hGainDec, GAIN_DEC_SAMPLE_RATE, (int)requestValue);
case DRC_DEC_BOOST: if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc, break;
SEL_PROC_BOOST, requestValue, case DRC_DEC_FRAME_SIZE:
&(hDrcDec->selProcInputDiff)); dErr = drcDec_GainDecoder_SetParam(
if (sErr) return DRC_DEC_PARAM_OUT_OF_RANGE; hDrcDec->hGainDec, GAIN_DEC_FRAME_SIZE, (int)requestValue);
break; if (dErr) return DRC_DEC_PARAM_OUT_OF_RANGE;
case DRC_DEC_COMPRESS: break;
sErr = drcDec_SelectionProcess_SetParam(hDrcDec->hSelectionProc, default:
SEL_PROC_COMPRESS, requestValue, invalidParameter |= DRC_DEC_GAIN;
&(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_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 */ /* All parameters need a new start of the selection process */
startSelectionProcess(hDrcDec); startSelectionProcess(hDrcDec);

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android 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. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -170,11 +170,10 @@ drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
} }
DRC_ERROR DRC_ERROR
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec) {
const int sampleRate) {
DRC_ERROR err = DE_OK; DRC_ERROR err = DE_OK;
err = initGainDec(hGainDec, frameSize, sampleRate); err = initGainDec(hGainDec);
if (err) return err; if (err) return err;
initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers); initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
@ -182,6 +181,25 @@ drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
return err; 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 DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters( drcDec_GainDecoder_SetCodecDependentParameters(
HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode, 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 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. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -134,6 +134,8 @@ typedef enum {
GAIN_DEC_DRC2_DRC3 GAIN_DEC_DRC2_DRC3
} GAIN_DEC_LOCATION; } GAIN_DEC_LOCATION;
typedef enum { GAIN_DEC_FRAME_SIZE, GAIN_DEC_SAMPLE_RATE } GAIN_DEC_PARAM;
typedef struct { typedef struct {
FIXP_DBL gainLin; /* e = 7 */ FIXP_DBL gainLin; /* e = 7 */
SHORT time; SHORT time;
@ -195,8 +197,12 @@ DRC_ERROR
drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec); drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec);
DRC_ERROR DRC_ERROR
drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec);
const int sampleRate);
DRC_ERROR
drcDec_GainDecoder_SetParam(HANDLE_DRC_GAIN_DECODER hGainDec,
const GAIN_DEC_PARAM paramType,
const int paramValue);
DRC_ERROR DRC_ERROR
drcDec_GainDecoder_SetCodecDependentParameters( drcDec_GainDecoder_SetCodecDependentParameters(

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android 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. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -184,24 +184,11 @@ static DRC_ERROR _generateDrcInstructionsDerivedData(
} }
DRC_ERROR DRC_ERROR
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec) {
const int sampleRate) {
int i, j, k; int i, j, k;
if (frameSize < 1) { /* sanity check */
return DE_NOT_OK; if (hGainDec->deltaTminDefault > hGainDec->frameSize) 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;
}
for (i = 0; i < MAX_ACTIVE_DRCS; i++) { for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android 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. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -104,8 +104,7 @@ amm-info@iis.fraunhofer.de
#define DRCGAINDEC_INIT_H #define DRCGAINDEC_INIT_H
DRC_ERROR DRC_ERROR
initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize, initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec);
const int sampleRate);
void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers); void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers);