From e970ac4c95e2e1016c72caa5218fc8f1bafe58fe Mon Sep 17 00:00:00 2001 From: Fraunhofer IIS FDK Date: Fri, 8 Mar 2019 16:08:07 +0100 Subject: [PATCH] Fix HE-AAC using MPEG-D DRC with implicit SBR signaling. Bug: 132641988 Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc Change-Id: I97c5d3972528092f627153ad3127c7db977a0e5d --- libAACdec/src/aacdecoder_lib.cpp | 7 ++ libDRCdec/include/FDK_drcDecLib.h | 2 + libDRCdec/src/FDK_drcDecLib.cpp | 162 ++++++++++++++++----------- libDRCdec/src/drcDec_gainDecoder.cpp | 26 ++++- libDRCdec/src/drcDec_gainDecoder.h | 12 +- libDRCdec/src/drcGainDec_init.cpp | 21 +--- libDRCdec/src/drcGainDec_init.h | 5 +- 7 files changed, 140 insertions(+), 95 deletions(-) diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 4046d66..86ec899 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -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. */ diff --git a/libDRCdec/include/FDK_drcDecLib.h b/libDRCdec/include/FDK_drcDecLib.h index 9a99ed1..2d28d23 100644 --- a/libDRCdec/include/FDK_drcDecLib.h +++ b/libDRCdec/include/FDK_drcDecLib.h @@ -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, diff --git a/libDRCdec/src/FDK_drcDecLib.cpp b/libDRCdec/src/FDK_drcDecLib.cpp index 8f3faa0..4f8ebc7 100644 --- a/libDRCdec/src/FDK_drcDecLib.cpp +++ b/libDRCdec/src/FDK_drcDecLib.cpp @@ -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); diff --git a/libDRCdec/src/drcDec_gainDecoder.cpp b/libDRCdec/src/drcDec_gainDecoder.cpp index ca81fad..9d91267 100644 --- a/libDRCdec/src/drcDec_gainDecoder.cpp +++ b/libDRCdec/src/drcDec_gainDecoder.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 @@ -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, diff --git a/libDRCdec/src/drcDec_gainDecoder.h b/libDRCdec/src/drcDec_gainDecoder.h index 2f4df4c..394b455 100644 --- a/libDRCdec/src/drcDec_gainDecoder.h +++ b/libDRCdec/src/drcDec_gainDecoder.h @@ -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( diff --git a/libDRCdec/src/drcGainDec_init.cpp b/libDRCdec/src/drcGainDec_init.cpp index c9f87d7..89d0f55 100644 --- a/libDRCdec/src/drcGainDec_init.cpp +++ b/libDRCdec/src/drcGainDec_init.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 @@ -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++) { diff --git a/libDRCdec/src/drcGainDec_init.h b/libDRCdec/src/drcGainDec_init.h index 9215bc3..c0b9853 100644 --- a/libDRCdec/src/drcGainDec_init.h +++ b/libDRCdec/src/drcGainDec_init.h @@ -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);