OMX AAC decode don't support getting DRC parameters

Test: android.media.cts.DecoderTestAacDrc#testDecodeAacDrclevelM4a
Test: android.media.cts.DecoderTestAacDrc#testDecodeAacDrcHeavyM4a
Test: android.media.cts.DecoderTestAacDrc#testDecodeAacUsacLoudnessM4a
Test: android.media.cts.DecoderTestAacDrc#testDecodeAacDrcOutputLoudnessM4a
Test: android.media.cts.DecoderTestAacDrc#testDecodeAacDrcOffM4a
Test: android.media.cts.DecoderTestAacDrc#testDecodeAacDrcHalfM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacStreamSwithingM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacDrcBoostAndAttenuationM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacDrcAlbumModeM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacDrcOutputLoudnessM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacDrcLoudnessPreferenceM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacSamplingRatesM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacSyncSampleSeekingM4a
Test: android.media.cts.DecoderTestXheAac#testDecodeUsacDrcEffectTypeM4a

Bug: 167754316
Change-Id: I50fcc5ef35cb7e96592c2267652228b5fa074ba9
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 63ab654..3163316 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5283,6 +5283,34 @@
                     if (mChannelMaskPresent) {
                         notify->setInt32("channel-mask", mChannelMask);
                     }
+
+                    if (!mIsEncoder && portIndex == kPortIndexOutput) {
+                        AString mime;
+                        if (mConfigFormat->findString("mime", &mime)
+                                && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
+
+                            OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
+                            InitOMXParams(&presentation);
+                            err = mOMXNode->getParameter(
+                                    (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                                    &presentation, sizeof(presentation));
+                            if (err != OK) {
+                                return err;
+                            }
+                            notify->setInt32("aac-encoded-target-level",
+                                             presentation.nEncodedTargetLevel);
+                            notify->setInt32("aac-drc-cut-level", presentation.nDrcCut);
+                            notify->setInt32("aac-drc-boost-level", presentation.nDrcBoost);
+                            notify->setInt32("aac-drc-heavy-compression",
+                                             presentation.nHeavyCompression);
+                            notify->setInt32("aac-target-ref-level",
+                                             presentation.nTargetReferenceLevel);
+                            notify->setInt32("aac-drc-effect-type", presentation.nDrcEffectType);
+                            notify->setInt32("aac-drc-album-mode", presentation.nDrcAlbumMode);
+                            notify->setInt32("aac-drc-output-loudness",
+                                             presentation.nDrcOutputLoudness);
+                        }
+                    }
                     break;
                 }
 
@@ -7704,6 +7732,58 @@
     // Ignore errors as failure is expected for codecs that aren't video encoders.
     (void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
 
+    AString mime;
+    if (!mIsEncoder
+            && (mConfigFormat->findString("mime", &mime))
+            && !strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime.c_str())) {
+        OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE presentation;
+        InitOMXParams(&presentation);
+        mOMXNode->getParameter(
+                    (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                    &presentation, sizeof(presentation));
+        int32_t value32 = 0;
+        bool updated = false;
+        if (params->findInt32("aac-pcm-limiter-enable", &value32)) {
+            presentation.nPCMLimiterEnable = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-encoded-target-level", &value32)) {
+            presentation.nEncodedTargetLevel = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-cut-level", &value32)) {
+            presentation.nDrcCut = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-boost-level", &value32)) {
+            presentation.nDrcBoost = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-heavy-compression", &value32)) {
+            presentation.nHeavyCompression = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-target-ref-level", &value32)) {
+            presentation.nTargetReferenceLevel = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-effect-type", &value32)) {
+            presentation.nDrcEffectType = value32;
+            updated = true;
+        }
+        if (params->findInt32("aac-drc-album-mode", &value32)) {
+            presentation.nDrcAlbumMode = value32;
+            updated = true;
+        }
+        if (!params->findInt32("aac-drc-output-loudness", &value32)) {
+            presentation.nDrcOutputLoudness = value32;
+            updated = true;
+        }
+        if (updated) {
+            mOMXNode->setParameter((OMX_INDEXTYPE)OMX_IndexParamAudioAndroidAacDrcPresentation,
+                &presentation, sizeof(presentation));
+        }
+    }
     return setVendorParameters(params);
 }
 
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 2aeddd7..28a7a1e 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -38,6 +38,7 @@
 #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) */
 #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
@@ -230,6 +231,15 @@
     // For seven and eight channel input streams, enable 6.1 and 7.1 channel output
     aacDecoder_SetParam(mAACDecoder, AAC_PCM_MAX_OUTPUT_CHANNELS, -1);
 
+    mDrcCompressMode = DRC_DEFAULT_MOBILE_DRC_HEAVY;
+    mDrcTargetRefLevel = DRC_DEFAULT_MOBILE_REF_LEVEL;
+    mDrcEncTargetLevel = DRC_DEFAULT_MOBILE_ENC_LEVEL;
+    mDrcBoostFactor = DRC_DEFAULT_MOBILE_DRC_BOOST;
+    mDrcAttenuationFactor = DRC_DEFAULT_MOBILE_DRC_CUT;
+    mDrcEffectType = DRC_DEFAULT_MOBILE_DRC_EFFECT;
+    mDrcAlbumMode = DRC_DEFAULT_MOBILE_DRC_ALBUM;
+    mDrcOutputLoudness = DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS;
+
     return status;
 }
 
@@ -358,6 +368,27 @@
             return OMX_ErrorNone;
         }
 
+        case OMX_IndexParamAudioAndroidAacDrcPresentation:
+        {
+             OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *aacPresParams =
+                    (OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *)params;
+
+            ALOGD("get OMX_IndexParamAudioAndroidAacDrcPresentation");
+
+            if (!isValidOMXParam(aacPresParams)) {
+                return OMX_ErrorBadParameter;
+            }
+            aacPresParams->nDrcEffectType = mDrcEffectType;
+            aacPresParams->nDrcAlbumMode = mDrcAlbumMode;
+            aacPresParams->nDrcBoost =  mDrcBoostFactor;
+            aacPresParams->nDrcCut = mDrcAttenuationFactor;
+            aacPresParams->nHeavyCompression = mDrcCompressMode;
+            aacPresParams->nTargetReferenceLevel = mDrcTargetRefLevel;
+            aacPresParams->nEncodedTargetLevel = mDrcEncTargetLevel;
+            aacPresParams ->nDrcOutputLoudness = mDrcOutputLoudness;
+            return OMX_ErrorNone;
+        }
+
         default:
             return SimpleSoftOMXComponent::internalGetParameter(index, params);
     }
@@ -464,11 +495,13 @@
             if (aacPresParams->nDrcEffectType >= -1) {
                 ALOGV("set nDrcEffectType=%d", aacPresParams->nDrcEffectType);
                 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_SET_EFFECT, aacPresParams->nDrcEffectType);
+                mDrcEffectType = aacPresParams->nDrcEffectType;
             }
             if (aacPresParams->nDrcAlbumMode >= -1) {
                 ALOGV("set nDrcAlbumMode=%d", aacPresParams->nDrcAlbumMode);
                 aacDecoder_SetParam(mAACDecoder, AAC_UNIDRC_ALBUM_MODE,
                         aacPresParams->nDrcAlbumMode);
+                mDrcAlbumMode = aacPresParams->nDrcAlbumMode;
             }
             bool updateDrcWrapper = false;
             if (aacPresParams->nDrcBoost >= 0) {
@@ -476,34 +509,42 @@
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_BOOST_FACTOR,
                         aacPresParams->nDrcBoost);
                 updateDrcWrapper = true;
+                mDrcBoostFactor = aacPresParams->nDrcBoost;
             }
             if (aacPresParams->nDrcCut >= 0) {
                 ALOGV("set nDrcCut=%d", aacPresParams->nDrcCut);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_ATT_FACTOR, aacPresParams->nDrcCut);
                 updateDrcWrapper = true;
+                mDrcAttenuationFactor = aacPresParams->nDrcCut;
             }
             if (aacPresParams->nHeavyCompression >= 0) {
                 ALOGV("set nHeavyCompression=%d", aacPresParams->nHeavyCompression);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_HEAVY,
                         aacPresParams->nHeavyCompression);
                 updateDrcWrapper = true;
+                mDrcCompressMode = aacPresParams->nHeavyCompression;
             }
             if (aacPresParams->nTargetReferenceLevel >= -1) {
                 ALOGV("set nTargetReferenceLevel=%d", aacPresParams->nTargetReferenceLevel);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_DESIRED_TARGET,
                         aacPresParams->nTargetReferenceLevel);
                 updateDrcWrapper = true;
+                mDrcTargetRefLevel = aacPresParams->nTargetReferenceLevel;
             }
             if (aacPresParams->nEncodedTargetLevel >= 0) {
                 ALOGV("set nEncodedTargetLevel=%d", aacPresParams->nEncodedTargetLevel);
                 mDrcWrap.setParam(DRC_PRES_MODE_WRAP_ENCODER_TARGET,
                         aacPresParams->nEncodedTargetLevel);
                 updateDrcWrapper = true;
+                mDrcEncTargetLevel = aacPresParams->nEncodedTargetLevel;
             }
             if (aacPresParams->nPCMLimiterEnable >= 0) {
                 aacDecoder_SetParam(mAACDecoder, AAC_PCM_LIMITER_ENABLE,
                         (aacPresParams->nPCMLimiterEnable != 0));
             }
+            if (aacPresParams ->nDrcOutputLoudness != DRC_DEFAULT_MOBILE_OUTPUT_LOUDNESS) {
+                mDrcOutputLoudness = aacPresParams ->nDrcOutputLoudness;
+            }
             if (updateDrcWrapper) {
                 mDrcWrap.update();
             }
@@ -854,6 +895,11 @@
                     // fall through
                 }
 
+                if ( mDrcOutputLoudness != mStreamInfo->outputLoudness) {
+                    ALOGD("update Loudness, before = %d, now = %d", mDrcOutputLoudness, mStreamInfo->outputLoudness);
+                    mDrcOutputLoudness = mStreamInfo->outputLoudness;
+                }
+
                 /*
                  * AAC+/eAAC+ streams can be signalled in two ways: either explicitly
                  * or implicitly, according to MPEG4 spec. AAC+/eAAC+ is a dual
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 5bee710..9f98aa1 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -85,6 +85,17 @@
     int32_t mOutputDelayRingBufferWritePos;
     int32_t mOutputDelayRingBufferReadPos;
     int32_t mOutputDelayRingBufferFilled;
+
+    //drc
+    int32_t mDrcCompressMode;
+    int32_t mDrcTargetRefLevel;
+    int32_t mDrcEncTargetLevel;
+    int32_t mDrcBoostFactor;
+    int32_t mDrcAttenuationFactor;
+    int32_t mDrcEffectType;
+    int32_t mDrcAlbumMode;
+    int32_t mDrcOutputLoudness;
+
     bool outputDelayRingBufferPutSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples);
     int32_t outputDelayRingBufferSamplesAvailable();
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index ddb459f..44415aa 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -17,6 +17,10 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "SimpleSoftOMXComponent"
 #include <utils/Log.h>
+#include <OMX_Core.h>
+#include <OMX_Audio.h>
+#include <OMX_IndexExt.h>
+#include <OMX_AudioExt.h>
 
 #include <media/stagefright/omx/SimpleSoftOMXComponent.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -74,7 +78,7 @@
 
     OMX_U32 portIndex;
 
-    switch (index) {
+    switch ((int)index) {
         case OMX_IndexParamPortDefinition:
         {
             const OMX_PARAM_PORTDEFINITIONTYPE *portDefs =
@@ -108,6 +112,19 @@
             break;
         }
 
+         case OMX_IndexParamAudioAndroidAacDrcPresentation:
+        {
+            if (mState == OMX_StateInvalid) {
+                return false;
+            }
+            const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *aacPresParams =
+                            (const OMX_AUDIO_PARAM_ANDROID_AACDRCPRESENTATIONTYPE *)params;
+            if (!isValidOMXParam(aacPresParams)) {
+                return false;
+            }
+            return true;
+         }
+
         default:
             return false;
     }