AAC decoder: support album mode

Bug: 144351156
Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc
Change-Id: Ifc360b5907bfe1255834e5323617703634170188
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index 680771f..f39620e 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -40,6 +40,7 @@
 #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_DRC_ALBUM  0  /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
 #define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS (0.25) /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
 #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 */
@@ -193,6 +194,17 @@
                 .build());
 
         addParameter(
+                DefineParam(mDrcAlbumMode, C2_PARAMKEY_DRC_ALBUM_MODE)
+                .withDefault(new C2StreamDrcAlbumModeTuning::input(0u, C2Config::DRC_ALBUM_MODE_OFF))
+                .withFields({
+                    C2F(mDrcAlbumMode, value).oneOf({
+                            C2Config::DRC_ALBUM_MODE_OFF,
+                            C2Config::DRC_ALBUM_MODE_ON})
+                })
+                .withSetter(Setter<decltype(*mDrcAlbumMode)>::StrictValueWithNoDeps)
+                .build());
+
+        addParameter(
                 DefineParam(mDrcOutputLoudness, C2_PARAMKEY_DRC_OUTPUT_LOUDNESS)
                 .withDefault(new C2StreamDrcOutputLoudnessTuning::output(0u, DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS))
                 .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)})
@@ -212,6 +224,7 @@
     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; }
+    int32_t getDrcAlbumMode() const { return mDrcAlbumMode->value; }
     int32_t getDrcOutputLoudness() const { return (mDrcOutputLoudness->value <= 0 ? -mDrcOutputLoudness->value * 4. + 0.5 : -1); }
 
 private:
@@ -227,6 +240,7 @@
     std::shared_ptr<C2StreamDrcBoostFactorTuning::input> mDrcBoostFactor;
     std::shared_ptr<C2StreamDrcAttenuationFactorTuning::input> mDrcAttenuationFactor;
     std::shared_ptr<C2StreamDrcEffectTypeTuning::input> mDrcEffectType;
+    std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode;
     std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness;
     // TODO Add : C2StreamAacSbrModeTuning
 };
@@ -347,6 +361,11 @@
     ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
     aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
 
+    // AAC_UNIDRC_ALBUM_MODE
+    int32_t albumMode = mIntf->getDrcAlbumMode();
+    ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
+    aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
+
     // 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
     aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
@@ -683,6 +702,11 @@
         ALOGV("AAC decoder using MPEG-D DRC effect type %d", effectType);
         aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
 
+        // AAC_UNIDRC_ALBUM_MODE
+        int32_t albumMode = mIntf->getDrcAlbumMode();
+        ALOGV("AAC decoder using MPEG-D DRC album mode %d", albumMode);
+        aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
+
         mDrcWrap.update();
 
         UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index c30e409..74fdc8b 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -58,6 +58,7 @@
     enum bitrate_mode_t : uint32_t;         ///< bitrate control mode
     enum drc_compression_mode_t : int32_t;  ///< DRC compression mode
     enum drc_effect_type_t : int32_t;       ///< DRC effect type
+    enum drc_album_mode_t : int32_t;        ///< DRC album mode
     enum drc_output_loudness : int32_t;     ///< DRC output loudness
     enum intra_refresh_mode_t : uint32_t;   ///< intra refresh modes
     enum level_t : uint32_t;                ///< coding level
@@ -220,6 +221,7 @@
     kParamIndexDrcAttenuationFactor, // drc, float (0-1)
     kParamIndexDrcEffectType, // drc, enum
     kParamIndexDrcOutputLoudness, // drc, float (dBFS)
+    kParamIndexDrcAlbumMode, // drc, enum
 
     /* ============================== platform-defined parameters ============================== */
 
@@ -1944,6 +1946,17 @@
 constexpr char C2_PARAMKEY_DRC_EFFECT_TYPE[] = "coding.drc.effect-type";
 
 /**
+ * DRC album mode. Used during decoding.
+ */
+C2ENUM(C2Config::drc_album_mode_t, int32_t,
+    DRC_ALBUM_MODE_OFF = 0,
+    DRC_ALBUM_MODE_ON = 1
+)
+typedef C2StreamParam<C2Info, C2SimpleValueStruct<C2Config::drc_album_mode_t>, kParamIndexDrcAlbumMode>
+        C2StreamDrcAlbumModeTuning;
+constexpr char C2_PARAMKEY_DRC_ALBUM_MODE[] = "coding.drc.album-mode";
+
+/**
  * DRC output loudness in dBFS. Retrieved during decoding
  */
  typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcOutputLoudness>
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 460bdb0..b019d0d 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -34,6 +34,7 @@
 #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_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0   /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
 #define DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS -1 /* decoder output loudness; -1 => the value is unknown, otherwise dB step value (e.g. 64 for -16 dB) */
 #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) */
 // names of properties that can be used to override the default DRC settings
@@ -815,6 +816,29 @@
             }
         }));
 
+    // convert to album mode and add default
+    add(ConfigMapper(KEY_AAC_DRC_ALBUM_MODE, C2_PARAMKEY_DRC_ALBUM_MODE, "value")
+        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
+        .withMappers([](C2Value v) -> C2Value {
+            int32_t value;
+            if (!v.get(&value) || value < 0 || value > 1) {
+                value = DRC_DEFAULT_MOBILE_DRC_ALBUM;
+                // ensure value is within range
+                if (value < 0 || value > 1) {
+                    value = DRC_DEFAULT_MOBILE_DRC_ALBUM;
+                }
+            }
+            return value;
+        },[](C2Value v) -> C2Value {
+            int32_t value;
+            if (v.get(&value)) {
+              return value;
+            }
+            else {
+              return C2Value();
+            }
+        }));
+
     add(ConfigMapper(KEY_AAC_DRC_OUTPUT_LOUDNESS, C2_PARAMKEY_DRC_OUTPUT_LOUDNESS, "value")
         .limitTo(D::OUTPUT & D::DECODER & D::READ)
         .withMappers([](C2Value v) -> C2Value {
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 8c78d99..73d3a0b 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2187,6 +2187,10 @@
                 // value is unknown
                 drc.effectType = -2; // valid values are -1 and over
             }
+            if (!msg->findInt32("aac-drc-album-mode", &drc.albumMode)) {
+                // value is unknown
+                drc.albumMode = -1; // valid values are 0 and 1
+            }
             if (!msg->findInt32("aac-drc-output-loudness", &drc.outputLoudness)) {
                 // value is unknown
                 drc.outputLoudness = -1;
@@ -2880,6 +2884,7 @@
     presentation.nEncodedTargetLevel = drc.encodedTargetLevel;
     presentation.nPCMLimiterEnable = pcmLimiterEnable;
     presentation.nDrcEffectType = drc.effectType;
+    presentation.nDrcAlbumMode = drc.albumMode;
     presentation.nDrcOutputLoudness = drc.outputLoudness;
 
     status_t res = mOMXNode->setParameter(
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 739dce4..2aeddd7 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -37,6 +37,7 @@
 #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_DRC_EFFECT 3  /* MPEG-D DRC effect type; 3 => Limited playback range */
+#define DRC_DEFAULT_MOBILE_DRC_ALBUM 0  /* MPEG-D DRC album mode; 0 => album mode is disabled, 1 => album mode is enabled */
 #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 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
@@ -219,6 +220,11 @@
     ALOGV("AAC decoder using MPEG-D DRC effect type %d (default=%d)",
             effectType, DRC_DEFAULT_MOBILE_DRC_EFFECT);
     aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, effectType);
+    // AAC_UNIDRC_ALBUM_MODE
+    int32_t albumMode = DRC_DEFAULT_MOBILE_DRC_ALBUM;
+    ALOGV("AAC decoder using MPEG-D Album mode value %d (default=%d)", albumMode,
+            DRC_DEFAULT_MOBILE_DRC_ALBUM);
+    aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE, albumMode);
 
     // 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
@@ -459,6 +465,11 @@
                 ALOGV("set nDrcEffectType=%d", aacPresParams->nDrcEffectType);
                 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, aacPresParams->nDrcEffectType);
             }
+            if (aacPresParams->nDrcAlbumMode >= -1) {
+                ALOGV("set nDrcAlbumMode=%d", aacPresParams->nDrcAlbumMode);
+                aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE,
+                        aacPresParams->nDrcAlbumMode);
+            }
             bool updateDrcWrapper = false;
             if (aacPresParams->nDrcBoost >= 0) {
                 ALOGV("set nDrcBoost=%d", aacPresParams->nDrcBoost);
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 5111069..83e92b9 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -476,6 +476,7 @@
         int32_t targetRefLevel;
         int32_t encodedTargetLevel;
         int32_t effectType;
+        int32_t albumMode;
         int32_t outputLoudness;
     } drcParams_t;
 
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index f5404cc..bfdc9e7 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -733,6 +733,7 @@
 constexpr int32_t COLOR_TRANSFER_SDR_VIDEO = 3;
 constexpr int32_t COLOR_TRANSFER_ST2084 = 6;
 
+constexpr char KEY_AAC_DRC_ALBUM_MODE[] = "aac-drc-album-mode";
 constexpr char KEY_AAC_DRC_ATTENUATION_FACTOR[] = "aac-drc-cut-level";
 constexpr char KEY_AAC_DRC_BOOST_FACTOR[] = "aac-drc-boost-level";
 constexpr char KEY_AAC_DRC_EFFECT_TYPE[] = "aac-drc-effect-type";