/*
 * 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 "SoftAAC2_DrcWrapper"
//#define LOG_NDEBUG 0
#include <utils/Log.h>

//#define DRC_PRES_MODE_WRAP_DEBUG

#define GPM_ENCODER_TARGET_LEVEL 64
#define MAX_TARGET_LEVEL 64

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. */
    /* Initialized to the same values as the desired values */
    mLastTarget = -1;
    mLastAttFactor = 0;
    mLastBoostFactor = 0;
    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) {
        // sanity check
        if (mDesTarget < MAX_TARGET_LEVEL){
            mDesTarget = MAX_TARGET_LEVEL;  // limit target level to -16 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

            // Sanity 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)

        // sanity 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)
}
