C2SoftAacDec: Add support for DRC
Bug: 110423231
Test: cts -m CtsMediaTestCases -t android.media.cts.DecoderTestAacDrc
Test: cts -m CtsMediaTestCases -t android.media.cts.DecoderTestXheAac
Change-Id: I6b6f856a34fdcf39cb61885f6853603226694748
diff --git a/media/codecs/aac/C2SoftAacDec.cpp b/media/codecs/aac/C2SoftAacDec.cpp
index 4848bd0..c7b1191 100644
--- a/media/codecs/aac/C2SoftAacDec.cpp
+++ b/media/codecs/aac/C2SoftAacDec.cpp
@@ -35,11 +35,12 @@
#define FILEREAD_MAX_LAYERS 2
-#define DRC_DEFAULT_MOBILE_REF_LEVEL 64 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_CUT 127 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_BOOST 127 /* maximum compression of dynamic range for mobile conf */
-#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1 /* switch for heavy compression for mobile conf */
-#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
+#define DRC_DEFAULT_MOBILE_REF_LEVEL -16.0 /* 64*-0.25dB = -16 dB below full scale for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_CUT 1.0 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_BOOST 1.0 /* maximum compression of dynamic range for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_HEAVY C2Config::DRC_COMPRESSION_HEAVY /* switch for heavy compression for mobile conf */
+#define DRC_DEFAULT_MOBILE_DRC_EFFECT 3 /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_ENC_LEVEL (0.25) /* encoder target level; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
#define MAX_CHANNEL_COUNT 8 /* maximum number of audio channels that can be decoded */
// names of properties that can be used to override the default DRC settings
#define PROP_DRC_OVERRIDE_REF_LEVEL "aac_drc_reference_level"
@@ -47,6 +48,7 @@
#define PROP_DRC_OVERRIDE_BOOST "aac_drc_boost"
#define PROP_DRC_OVERRIDE_HEAVY "aac_drc_heavy"
#define PROP_DRC_OVERRIDE_ENC_LEVEL "aac_drc_enc_target_level"
+#define PROP_DRC_OVERRIDE_EFFECT "ro.aac_drc_effect_type"
namespace android {
@@ -135,6 +137,65 @@
})
.withSetter(ProfileLevelSetter)
.build());
+
+ addParameter(
+ DefineParam(mDrcCompressMode, C2_PARAMKEY_DRC_COMPRESSION_MODE)
+ .withDefault(new C2StreamDrcCompressionModeTuning::input(0u, C2Config::DRC_COMPRESSION_HEAVY))
+ .withFields({
+ C2F(mDrcCompressMode, value).oneOf({
+ C2Config::DRC_COMPRESSION_ODM_DEFAULT,
+ C2Config::DRC_COMPRESSION_NONE,
+ C2Config::DRC_COMPRESSION_LIGHT,
+ C2Config::DRC_COMPRESSION_HEAVY})
+ })
+ .withSetter(Setter<decltype(*mDrcCompressMode)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mDrcTargetRefLevel, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL)
+ .withDefault(new C2StreamDrcTargetReferenceLevelTuning::input(0u, DRC_DEFAULT_MOBILE_REF_LEVEL))
+ .withFields({C2F(mDrcTargetRefLevel, value).inRange(-31.75, 0.25)})
+ .withSetter(Setter<decltype(*mDrcTargetRefLevel)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mDrcEncTargetLevel, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL)
+ .withDefault(new C2StreamDrcEncodedTargetLevelTuning::input(0u, DRC_DEFAULT_MOBILE_ENC_LEVEL))
+ .withFields({C2F(mDrcEncTargetLevel, value).inRange(-31.75, 0.25)})
+ .withSetter(Setter<decltype(*mDrcEncTargetLevel)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mDrcBoostFactor, C2_PARAMKEY_DRC_BOOST_FACTOR)
+ .withDefault(new C2StreamDrcBoostFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_BOOST))
+ .withFields({C2F(mDrcBoostFactor, value).inRange(0, 1.)})
+ .withSetter(Setter<decltype(*mDrcBoostFactor)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mDrcAttenuationFactor, C2_PARAMKEY_DRC_ATTENUATION_FACTOR)
+ .withDefault(new C2StreamDrcAttenuationFactorTuning::input(0u, DRC_DEFAULT_MOBILE_DRC_CUT))
+ .withFields({C2F(mDrcAttenuationFactor, value).inRange(0, 1.)})
+ .withSetter(Setter<decltype(*mDrcAttenuationFactor)>::StrictValueWithNoDeps)
+ .build());
+
+ addParameter(
+ DefineParam(mDrcEffectType, C2_PARAMKEY_DRC_EFFECT_TYPE)
+ .withDefault(new C2StreamDrcEffectTypeTuning::input(0u, C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE))
+ .withFields({
+ C2F(mDrcEffectType, value).oneOf({
+ C2Config::DRC_EFFECT_ODM_DEFAULT,
+ C2Config::DRC_EFFECT_OFF,
+ C2Config::DRC_EFFECT_NONE,
+ C2Config::DRC_EFFECT_LATE_NIGHT,
+ C2Config::DRC_EFFECT_NOISY_ENVIRONMENT,
+ C2Config::DRC_EFFECT_LIMITED_PLAYBACK_RANGE,
+ C2Config::DRC_EFFECT_LOW_PLAYBACK_LEVEL,
+ C2Config::DRC_EFFECT_DIALOG_ENHANCEMENT,
+ C2Config::DRC_EFFECT_GENERAL_COMPRESSION})
+ })
+ .withSetter(Setter<decltype(*mDrcEffectType)>::StrictValueWithNoDeps)
+ .build());
}
bool isAdts() const { return mAacFormat->value == C2AacStreamFormatAdts; }
@@ -143,8 +204,14 @@
(void)me; // TODO: validate
return C2R::Ok();
}
-private:
+ int32_t getDrcCompressMode() const { return mDrcCompressMode->value == C2Config::DRC_COMPRESSION_HEAVY ? 1 : 0; }
+ int32_t getDrcTargetRefLevel() const { return (mDrcTargetRefLevel->value <= 0 ? -mDrcTargetRefLevel->value * 4. + 0.5 : -1); }
+ int32_t getDrcEncTargetLevel() const { return (mDrcEncTargetLevel->value <= 0 ? -mDrcEncTargetLevel->value * 4. + 0.5 : -1); }
+ int32_t getDrcBoostFactor() const { return mDrcBoostFactor->value * 127. + 0.5; }
+ int32_t getDrcAttenuationFactor() const { return mDrcAttenuationFactor->value * 127. + 0.5; }
+ int32_t getDrcEffectType() const { return mDrcEffectType->value; }
+private:
std::shared_ptr<C2StreamFormatConfig::input> mInputFormat;
std::shared_ptr<C2StreamFormatConfig::output> mOutputFormat;
std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
@@ -155,6 +222,13 @@
std::shared_ptr<C2StreamMaxBufferSizeInfo::input> mInputMaxBufSize;
std::shared_ptr<C2StreamAacFormatInfo::input> mAacFormat;
std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
+ std::shared_ptr<C2StreamDrcCompressionModeTuning::input> mDrcCompressMode;
+ std::shared_ptr<C2StreamDrcTargetReferenceLevelTuning::input> mDrcTargetRefLevel;
+ std::shared_ptr<C2StreamDrcEncodedTargetLevelTuning::input> mDrcEncTargetLevel;
+ std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
+ std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
+ std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
+ // TODO Add : C2StreamAacSbrModeTuning
};
constexpr char COMPONENT_NAME[] = "c2.android.aac.decoder";
@@ -243,52 +317,37 @@
// for streams that contain metadata, use the mobile profile DRC settings unless overridden by platform properties
// TODO: change the DRC settings depending on audio output device type (HDMI, loadspeaker, headphone)
- char value[PROPERTY_VALUE_MAX];
+
// DRC_PRES_MODE_WRAP_DESIRED_TARGET
- if (property_get(PROP_DRC_OVERRIDE_REF_LEVEL, value, NULL)) {
- unsigned refLevel = atoi(value);
- ALOGV("AAC decoder using desired DRC target reference level of %d instead of %d", refLevel,
- DRC_DEFAULT_MOBILE_REF_LEVEL);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, refLevel);
- } else {
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, DRC_DEFAULT_MOBILE_REF_LEVEL);
- }
+ int32_t targetRefLevel = mIntf->getDrcTargetRefLevel();
+ ALOGV("AAC decoder using desired DRC target reference level of %d", targetRefLevel);
+ mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET, (unsigned)targetRefLevel);
+
// DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR
- if (property_get(PROP_DRC_OVERRIDE_CUT, value, NULL)) {
- unsigned cut = atoi(value);
- ALOGV("AAC decoder using desired DRC attenuation factor of %d instead of %d", cut,
- DRC_DEFAULT_MOBILE_DRC_CUT);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, cut);
- } else {
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, DRC_DEFAULT_MOBILE_DRC_CUT);
- }
+
+ int32_t attenuationFactor = mIntf->getDrcAttenuationFactor();
+ ALOGV("AAC decoder using desired DRC attenuation factor of %d", attenuationFactor);
+ mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, (unsigned)attenuationFactor);
+
// DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR
- if (property_get(PROP_DRC_OVERRIDE_BOOST, value, NULL)) {
- unsigned boost = atoi(value);
- ALOGV("AAC decoder using desired DRC boost factor of %d instead of %d", boost,
- DRC_DEFAULT_MOBILE_DRC_BOOST);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, boost);
- } else {
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, DRC_DEFAULT_MOBILE_DRC_BOOST);
- }
+ int32_t boostFactor = mIntf->getDrcBoostFactor();
+ ALOGV("AAC decoder using desired DRC boost factor of %d", boostFactor);
+ mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR, (unsigned)boostFactor);
+
// DRC_PRES_MODE_WRAP_DESIRED_HEAVY
- if (property_get(PROP_DRC_OVERRIDE_HEAVY, value, NULL)) {
- unsigned heavy = atoi(value);
- ALOGV("AAC decoder using desried DRC heavy compression switch of %d instead of %d", heavy,
- DRC_DEFAULT_MOBILE_DRC_HEAVY);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, heavy);
- } else {
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
- }
+ int32_t compressMode = mIntf->getDrcCompressMode();
+ ALOGV("AAC decoder using desried DRC heavy compression switch of %d", compressMode);
+ mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY, (unsigned)compressMode);
+
// DRC_PRES_MODE_WRAP_ENCODER_TARGET
- if (property_get(PROP_DRC_OVERRIDE_ENC_LEVEL, value, NULL)) {
- unsigned encoderRefLevel = atoi(value);
- ALOGV("AAC decoder using encoder-side DRC reference level of %d instead of %d",
- encoderRefLevel, DRC_DEFAULT_MOBILE_ENC_LEVEL);
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, encoderRefLevel);
- } else {
- mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, DRC_DEFAULT_MOBILE_ENC_LEVEL);
- }
+ int32_t encTargetLevel = mIntf->getDrcEncTargetLevel();
+ ALOGV("AAC decoder using encoder-side DRC reference level of %d", encTargetLevel);
+ mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET, (unsigned)encTargetLevel);
+
+ // AAC_UNIDRC_SET_EFFECT
+ int32_t effectType = mIntf->getDrcEffectType();
+ ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
+ aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
// By default, the decoder creates a 5.1 channel downmix signal.
// For seven and eight channel input streams, enable 6.1 and 7.1 channel output
diff --git a/media/codecs/aac/DrcPresModeWrap.cpp b/media/codecs/aac/DrcPresModeWrap.cpp
index 74ab530..5b9aebc 100644
--- a/media/codecs/aac/DrcPresModeWrap.cpp
+++ b/media/codecs/aac/DrcPresModeWrap.cpp
@@ -24,7 +24,7 @@
//#define DRC_PRES_MODE_WRAP_DEBUG
#define GPM_ENCODER_TARGET_LEVEL 64
-#define MAX_TARGET_LEVEL 64
+#define MAX_TARGET_LEVEL 40
CDrcPresModeWrapper::CDrcPresModeWrapper()
{
@@ -164,7 +164,7 @@
if (mDataUpdate) {
// sanity check
if (mDesTarget < MAX_TARGET_LEVEL){
- mDesTarget = MAX_TARGET_LEVEL; // limit target level to -16 dB or below
+ mDesTarget = MAX_TARGET_LEVEL; // limit target level to -10 dB or below
newTarget = MAX_TARGET_LEVEL;
}