You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
14 KiB
372 lines
14 KiB
4 months ago
|
/*
|
||
|
* Copyright (C) 2014 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
#include "DrcPresModeWrap.h"
|
||
|
|
||
|
#include <assert.h>
|
||
|
|
||
|
#define LOG_TAG "C2SoftAacDrcWrapper"
|
||
|
//#define LOG_NDEBUG 0
|
||
|
#include <utils/Log.h>
|
||
|
|
||
|
//#define DRC_PRES_MODE_WRAP_DEBUG
|
||
|
|
||
|
#define GPM_ENCODER_TARGET_LEVEL 64
|
||
|
#define MAX_TARGET_LEVEL 40
|
||
|
|
||
|
CDrcPresModeWrapper::CDrcPresModeWrapper()
|
||
|
{
|
||
|
mDataUpdate = true;
|
||
|
|
||
|
/* Data from streamInfo. */
|
||
|
/* Initialized to the same values as in the aac decoder */
|
||
|
mStreamPRL = -1;
|
||
|
mStreamDRCPresMode = -1;
|
||
|
mStreamNrAACChan = 0;
|
||
|
mStreamNrOutChan = 0;
|
||
|
|
||
|
/* Desired values (set by user). */
|
||
|
/* Initialized to the same values as in the aac decoder */
|
||
|
mDesTarget = -1;
|
||
|
mDesAttFactor = 0;
|
||
|
mDesBoostFactor = 0;
|
||
|
mDesHeavy = 0;
|
||
|
|
||
|
mEncoderTarget = -1;
|
||
|
|
||
|
/* Values from last time. */
|
||
|
mLastTarget = -2;
|
||
|
mLastAttFactor = -1;
|
||
|
mLastBoostFactor = -1;
|
||
|
mLastHeavy = 0;
|
||
|
}
|
||
|
|
||
|
CDrcPresModeWrapper::~CDrcPresModeWrapper()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CDrcPresModeWrapper::setDecoderHandle(const HANDLE_AACDECODER handle)
|
||
|
{
|
||
|
mHandleDecoder = handle;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CDrcPresModeWrapper::submitStreamData(CStreamInfo* pStreamInfo)
|
||
|
{
|
||
|
assert(pStreamInfo);
|
||
|
|
||
|
if (mStreamPRL != pStreamInfo->drcProgRefLev) {
|
||
|
mStreamPRL = pStreamInfo->drcProgRefLev;
|
||
|
mDataUpdate = true;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
ALOGV("DRC presentation mode wrapper: drcProgRefLev is %d\n", mStreamPRL);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (mStreamDRCPresMode != pStreamInfo->drcPresMode) {
|
||
|
mStreamDRCPresMode = pStreamInfo->drcPresMode;
|
||
|
mDataUpdate = true;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
ALOGV("DRC presentation mode wrapper: drcPresMode is %d\n", mStreamDRCPresMode);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (mStreamNrAACChan != pStreamInfo->aacNumChannels) {
|
||
|
mStreamNrAACChan = pStreamInfo->aacNumChannels;
|
||
|
mDataUpdate = true;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
ALOGV("DRC presentation mode wrapper: aacNumChannels is %d\n", mStreamNrAACChan);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (mStreamNrOutChan != pStreamInfo->numChannels) {
|
||
|
mStreamNrOutChan = pStreamInfo->numChannels;
|
||
|
mDataUpdate = true;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
ALOGV("DRC presentation mode wrapper: numChannels is %d\n", mStreamNrOutChan);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if (mStreamNrOutChan<mStreamNrAACChan) {
|
||
|
mIsDownmix = true;
|
||
|
} else {
|
||
|
mIsDownmix = false;
|
||
|
}
|
||
|
|
||
|
if (mIsDownmix && (mStreamNrOutChan == 1)) {
|
||
|
mIsMonoDownmix = true;
|
||
|
} else {
|
||
|
mIsMonoDownmix = false;
|
||
|
}
|
||
|
|
||
|
if (mIsDownmix && mStreamNrOutChan == 2){
|
||
|
mIsStereoDownmix = true;
|
||
|
} else {
|
||
|
mIsStereoDownmix = false;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CDrcPresModeWrapper::setParam(const DRC_PRES_MODE_WRAP_PARAM param, const int value)
|
||
|
{
|
||
|
switch (param) {
|
||
|
case DRC_PRES_MODE_WRAP_DESIRED_TARGET:
|
||
|
mDesTarget = value;
|
||
|
break;
|
||
|
case DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR:
|
||
|
mDesAttFactor = value;
|
||
|
break;
|
||
|
case DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR:
|
||
|
mDesBoostFactor = value;
|
||
|
break;
|
||
|
case DRC_PRES_MODE_WRAP_DESIRED_HEAVY:
|
||
|
mDesHeavy = value;
|
||
|
break;
|
||
|
case DRC_PRES_MODE_WRAP_ENCODER_TARGET:
|
||
|
mEncoderTarget = value;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
mDataUpdate = true;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CDrcPresModeWrapper::update()
|
||
|
{
|
||
|
// Get Data from Decoder
|
||
|
int progRefLevel = mStreamPRL;
|
||
|
int drcPresMode = mStreamDRCPresMode;
|
||
|
|
||
|
// by default, do as desired
|
||
|
int newTarget = mDesTarget;
|
||
|
int newAttFactor = mDesAttFactor;
|
||
|
int newBoostFactor = mDesBoostFactor;
|
||
|
int newHeavy = mDesHeavy;
|
||
|
|
||
|
if (mDataUpdate) {
|
||
|
// Validation check
|
||
|
if ((mDesTarget < MAX_TARGET_LEVEL) && (mDesTarget != -1)){
|
||
|
mDesTarget = MAX_TARGET_LEVEL; // limit target level to -10 dB or below
|
||
|
newTarget = MAX_TARGET_LEVEL;
|
||
|
}
|
||
|
|
||
|
if (mEncoderTarget != -1) {
|
||
|
if (mDesTarget<124) { // if target level > -31 dB
|
||
|
if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
|
||
|
// no stereo or mono downmixing, calculated scaling of light DRC
|
||
|
/* use as little compression as possible */
|
||
|
newAttFactor = 0;
|
||
|
newBoostFactor = 0;
|
||
|
if (mDesTarget<progRefLevel) { // if target level > PRL
|
||
|
if (mEncoderTarget < mDesTarget) { // if mEncoderTarget > target level
|
||
|
// mEncoderTarget > target level > PRL
|
||
|
int calcFactor;
|
||
|
float calcFactor_norm;
|
||
|
// 0.0f < calcFactor_norm < 1.0f
|
||
|
calcFactor_norm = (float)(mDesTarget - progRefLevel) /
|
||
|
(float)(mEncoderTarget - progRefLevel);
|
||
|
calcFactor = (int)(calcFactor_norm*127.0f); // 0 <= calcFactor < 127
|
||
|
// calcFactor is the lower limit
|
||
|
newAttFactor = (calcFactor>newAttFactor) ? calcFactor : newAttFactor;
|
||
|
// new AttFactor will be always = calcFactor, as it is set to 0 before.
|
||
|
newBoostFactor = newAttFactor;
|
||
|
} else {
|
||
|
/* target level > mEncoderTarget > PRL */
|
||
|
// newTDLimiterEnable = 1;
|
||
|
// the time domain limiter must always be active in this case.
|
||
|
// It is assumed that the framework activates it by default
|
||
|
newAttFactor = 127;
|
||
|
newBoostFactor = 127;
|
||
|
}
|
||
|
} else { // target level <= PRL
|
||
|
// no restrictions required
|
||
|
// newAttFactor = newAttFactor;
|
||
|
}
|
||
|
} else { // downmixing
|
||
|
// if target level > -23 dB or mono downmix
|
||
|
if ( (mDesTarget<92) || mIsMonoDownmix ) {
|
||
|
newHeavy = 1;
|
||
|
} else {
|
||
|
// we perform a downmix, so, we need at least full light DRC
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
} else { // target level <= -31 dB
|
||
|
// playback -31 dB: light DRC only needed if we perform downmixing
|
||
|
if (mIsDownmix) { // we do downmixing
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else { // handle other used encoder target levels
|
||
|
|
||
|
// Validation check: DRC presentation mode is only specified for max. 5.1 channels
|
||
|
if (mStreamNrAACChan > 6) {
|
||
|
drcPresMode = 0;
|
||
|
}
|
||
|
|
||
|
switch (drcPresMode) {
|
||
|
case 0:
|
||
|
default: // presentation mode not indicated
|
||
|
{
|
||
|
|
||
|
if (mDesTarget<124) { // if target level > -31 dB
|
||
|
// no stereo or mono downmixing
|
||
|
if ((mIsStereoDownmix == false) && (mIsMonoDownmix == false)) {
|
||
|
if (mDesTarget<progRefLevel) { // if target level > PRL
|
||
|
// newTDLimiterEnable = 1;
|
||
|
// the time domain limiter must always be active in this case.
|
||
|
// It is assumed that the framework activates it by default
|
||
|
newAttFactor = 127; // at least, use light compression
|
||
|
} else { // target level <= PRL
|
||
|
// no restrictions required
|
||
|
// newAttFactor = newAttFactor;
|
||
|
}
|
||
|
} else { // downmixing
|
||
|
// newTDLimiterEnable = 1;
|
||
|
// the time domain limiter must always be active in this case.
|
||
|
// It is assumed that the framework activates it by default
|
||
|
|
||
|
// if target level > -23 dB or mono downmix
|
||
|
if ( (mDesTarget < 92) || mIsMonoDownmix ) {
|
||
|
newHeavy = 1;
|
||
|
} else{
|
||
|
// we perform a downmix, so, we need at least full light DRC
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
} else { // target level <= -31 dB
|
||
|
if (mIsDownmix) { // we do downmixing.
|
||
|
// newTDLimiterEnable = 1;
|
||
|
// the time domain limiter must always be active in this case.
|
||
|
// It is assumed that the framework activates it by default
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
// Presentation mode 1 and 2 according to ETSI TS 101 154:
|
||
|
// Digital Video Broadcasting (DVB); Specification for the use of Video and Audio Coding
|
||
|
// in Broadcasting Applications based on the MPEG-2 Transport Stream,
|
||
|
// section C.5.4., "Decoding", and Table C.33
|
||
|
// ISO DRC -> newHeavy = 0 (Use light compression, MPEG-style)
|
||
|
// Compression_value -> newHeavy = 1 (Use heavy compression, DVB-style)
|
||
|
// scaling restricted -> newAttFactor = 127
|
||
|
|
||
|
case 1: // presentation mode 1, Light:-31/Heavy:-23
|
||
|
{
|
||
|
if (mDesTarget < 124) { // if target level > -31 dB
|
||
|
// playback up to -23 dB
|
||
|
newHeavy = 1;
|
||
|
} else { // target level <= -31 dB
|
||
|
// playback -31 dB
|
||
|
if (mIsDownmix) { // we do downmixing.
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 2: // presentation mode 2, Light:-23/Heavy:-23
|
||
|
{
|
||
|
if (mDesTarget < 124) { // if target level > -31 dB
|
||
|
// playback up to -23 dB
|
||
|
if (mIsMonoDownmix) { // if mono downmix
|
||
|
newHeavy = 1;
|
||
|
} else {
|
||
|
newHeavy = 0;
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
} else { // target level <= -31 dB
|
||
|
// playback -31 dB
|
||
|
newHeavy = 0;
|
||
|
if (mIsDownmix) { // we do downmixing.
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
} // switch()
|
||
|
} // if (mEncoderTarget == GPM_ENCODER_TARGET_LEVEL)
|
||
|
|
||
|
// Validation check again
|
||
|
if (newHeavy == 1) {
|
||
|
newBoostFactor=127; // not really needed as the same would be done by the decoder anyway
|
||
|
newAttFactor = 127;
|
||
|
}
|
||
|
|
||
|
// update the decoder
|
||
|
if (newTarget != mLastTarget) {
|
||
|
aacDecoder_SetParam(mHandleDecoder, AAC_DRC_REFERENCE_LEVEL, newTarget);
|
||
|
mLastTarget = newTarget;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
if (newTarget != mDesTarget)
|
||
|
ALOGV("DRC presentation mode wrapper: forced target level to %d (from %d)\n", newTarget, mDesTarget);
|
||
|
else
|
||
|
ALOGV("DRC presentation mode wrapper: set target level to %d\n", newTarget);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (newAttFactor != mLastAttFactor) {
|
||
|
aacDecoder_SetParam(mHandleDecoder, AAC_DRC_ATTENUATION_FACTOR, newAttFactor);
|
||
|
mLastAttFactor = newAttFactor;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
if (newAttFactor != mDesAttFactor)
|
||
|
ALOGV("DRC presentation mode wrapper: forced attenuation factor to %d (from %d)\n", newAttFactor, mDesAttFactor);
|
||
|
else
|
||
|
ALOGV("DRC presentation mode wrapper: set attenuation factor to %d\n", newAttFactor);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (newBoostFactor != mLastBoostFactor) {
|
||
|
aacDecoder_SetParam(mHandleDecoder, AAC_DRC_BOOST_FACTOR, newBoostFactor);
|
||
|
mLastBoostFactor = newBoostFactor;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
if (newBoostFactor != mDesBoostFactor)
|
||
|
ALOGV("DRC presentation mode wrapper: forced boost factor to %d (from %d)\n",
|
||
|
newBoostFactor, mDesBoostFactor);
|
||
|
else
|
||
|
ALOGV("DRC presentation mode wrapper: set boost factor to %d\n", newBoostFactor);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if (newHeavy != mLastHeavy) {
|
||
|
aacDecoder_SetParam(mHandleDecoder, AAC_DRC_HEAVY_COMPRESSION, newHeavy);
|
||
|
mLastHeavy = newHeavy;
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
if (newHeavy != mDesHeavy)
|
||
|
ALOGV("DRC presentation mode wrapper: forced heavy compression to %d (from %d)\n",
|
||
|
newHeavy, mDesHeavy);
|
||
|
else
|
||
|
ALOGV("DRC presentation mode wrapper: set heavy compression to %d\n", newHeavy);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifdef DRC_PRES_MODE_WRAP_DEBUG
|
||
|
ALOGV("DRC config: tgt_lev: %3d, cut: %3d, boost: %3d, heavy: %d\n", newTarget,
|
||
|
newAttFactor, newBoostFactor, newHeavy);
|
||
|
#endif
|
||
|
mDataUpdate = false;
|
||
|
|
||
|
} // if (mDataUpdate)
|
||
|
}
|