/*
 * Copyright (C) 2009 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.
 */
/* INTEL CONFIDENTIAL
 * Copyright (c) 2009 Intel Corporation.  All rights reserved.
 *
 * The source code contained or described herein and all documents
 * related to the source code ("Material") are owned by Intel
 * Corporation or its suppliers or licensors.  Title to the
 * Material remains with Intel Corporation or its suppliers and
 * licensors.  The Material contains trade secrets and proprietary
 * and confidential information of Intel or its suppliers and
 * licensors. The Material is protected by worldwide copyright and
 * trade secret laws and treaty provisions.  No part of the Material
 * may be used, copied, reproduced, modified, published, uploaded,
 * posted, transmitted, distributed, or disclosed in any way without
 * Intel's prior express written permission.
 *
 * No license under any patent, copyright, trade secret or other
 * intellectual property right is granted to or conferred upon you
 * by disclosure or delivery of the Materials, either expressly, by
 * implication, inducement, estoppel or otherwise. Any license
 * under such intellectual property rights must be express and
 * approved by Intel in writing.
 *
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "PVSoftMPEG4Encoder"
#include <utils/Log.h>

#include "mp4enc_api.h"
#include "OMX_Video.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>

#include "PVSoftMPEG4Encoder.h"
#include "VideoEncoderLog.h"

inline static void ConvertYUV420SemiPlanarToYUV420Planar(
        uint8_t *inyuv, uint8_t* outyuv,
        int32_t width, int32_t height) {

    int32_t outYsize = width * height;
    uint32_t *outy =  (uint32_t *) outyuv;
    uint16_t *outcb = (uint16_t *) (outyuv + outYsize);
    uint16_t *outcr = (uint16_t *) (outyuv + outYsize + (outYsize >> 2));

    /* Y copying */
    memcpy(outy, inyuv, outYsize);

    /* U & V copying */
    uint32_t *inyuv_4 = (uint32_t *) (inyuv + outYsize);
    for (int32_t i = height >> 1; i > 0; --i) {
        for (int32_t j = width >> 2; j > 0; --j) {
            uint32_t temp = *inyuv_4++;
            uint32_t tempU = temp & 0xFF;
            tempU = tempU | ((temp >> 8) & 0xFF00);

            uint32_t tempV = (temp >> 8) & 0xFF;
            tempV = tempV | ((temp >> 16) & 0xFF00);

            // Flip U and V
            *outcb++ = tempU;
            *outcr++ = tempV;
        }
    }
}

inline static void trimBuffer(uint8_t *dataIn, uint8_t *dataOut,
        int32_t width, int32_t height,
        int32_t stride) {
    int32_t h;
    uint8_t *y_start, *uv_start, *_y_start, *_uv_start;
    y_start = dataOut;
    uv_start = dataOut + width * height;
    _y_start = dataIn;
    _uv_start = dataIn + stride * height;

    for (h = 0; h < height; h++)
        memcpy(y_start + h * width, _y_start + h * stride, width);
    for (h = 0; h < height / 2; h++)
        memcpy(uv_start + h * width,
                _uv_start + h * stride, width);
}

PVSoftMPEG4Encoder::PVSoftMPEG4Encoder(const char *name)
    :  mEncodeMode(COMBINE_MODE_WITH_ERR_RES),
      mVideoWidth(176),
      mVideoHeight(144),
      mVideoFrameRate(30),
      mVideoBitRate(192000),
      mVideoColorFormat(OMX_COLOR_FormatYUV420SemiPlanar),
      mStoreMetaDataInBuffers(false),
      mIDRFrameRefreshIntervalInSec(1),
      mNumInputFrames(-1),
      mStarted(false),
      mSawInputEOS(false),
      mSignalledError(false),
      mHandle(new tagvideoEncControls),
      mEncParams(new tagvideoEncOptions),
      mInputFrameData(NULL)
{

    if (!strcmp(name, "OMX.google.h263.encoder")) {
        mEncodeMode = H263_MODE;
        LOG_I("construct h263 encoder");
    } else {
        CHECK(!strcmp(name, "OMX.google.mpeg4.encoder"));
        LOG_I("construct mpeg4 encoder");
    }

    setDefaultParams();

    LOG_I("Construct PVSoftMPEG4Encoder");

}

PVSoftMPEG4Encoder::~PVSoftMPEG4Encoder() {
    LOG_I("Destruct PVSoftMPEG4Encoder");
    releaseEncoder();

}

void PVSoftMPEG4Encoder::setDefaultParams() {

    // Set default value for input parameters
    mComParams.profile = VAProfileH264Baseline;
    mComParams.level = 41;
    mComParams.rawFormat = RAW_FORMAT_NV12;
    mComParams.frameRate.frameRateNum = 30;
    mComParams.frameRate.frameRateDenom = 1;
    mComParams.resolution.width = 0;
    mComParams.resolution.height = 0;
    mComParams.intraPeriod = 30;
    mComParams.rcMode = RATE_CONTROL_NONE;
    mComParams.rcParams.initQP = 15;
    mComParams.rcParams.minQP = 0;
    mComParams.rcParams.bitRate = 640000;
    mComParams.rcParams.targetPercentage= 0;
    mComParams.rcParams.windowSize = 0;
    mComParams.rcParams.disableFrameSkip = 0;
    mComParams.rcParams.disableBitsStuffing = 1;
    mComParams.cyclicFrameInterval = 30;
    mComParams.refreshType = VIDEO_ENC_NONIR;
    mComParams.airParams.airMBs = 0;
    mComParams.airParams.airThreshold = 0;
    mComParams.airParams.airAuto = 1;
    mComParams.disableDeblocking = 2;
    mComParams.syncEncMode = false;
    mComParams.codedBufNum = 2;

}

Encode_Status PVSoftMPEG4Encoder::initEncParams() {
    CHECK(mHandle != NULL);
    memset(mHandle, 0, sizeof(tagvideoEncControls));

    CHECK(mEncParams != NULL);
    memset(mEncParams, 0, sizeof(tagvideoEncOptions));
    if (!PVGetDefaultEncOption(mEncParams, 0)) {
        LOG_E("Failed to get default encoding parameters");
        return ENCODE_FAIL;
    }
    mEncParams->encMode = mEncodeMode;
    mEncParams->encWidth[0] = mVideoWidth;
    mEncParams->encHeight[0] = mVideoHeight;
    mEncParams->encFrameRate[0] = mVideoFrameRate;
    mEncParams->rcType = VBR_1;
    mEncParams->vbvDelay = 5.0f;

    // FIXME:
    // Add more profile and level support for MPEG4 encoder
    mEncParams->profile_level = CORE_PROFILE_LEVEL2;
    mEncParams->packetSize = 32;
    mEncParams->rvlcEnable = PV_OFF;
    mEncParams->numLayers = 1;
    mEncParams->timeIncRes = 1000;
    mEncParams->tickPerSrc = mEncParams->timeIncRes / mVideoFrameRate;

    mEncParams->bitRate[0] = mVideoBitRate;
    mEncParams->iQuant[0] = 15;
    mEncParams->pQuant[0] = 12;
    mEncParams->quantType[0] = 0;
    mEncParams->noFrameSkipped = PV_OFF;

    mTrimedInputData =
        (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
    CHECK(mTrimedInputData != NULL);

    if (mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
        // Color conversion is needed.
        CHECK(mInputFrameData == NULL);
        mInputFrameData =
            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
        CHECK(mInputFrameData != NULL);
    }

    // PV's MPEG4 encoder requires the video dimension of multiple
    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) {
        LOG_E("Video frame size %dx%d must be a multiple of 16",
            mVideoWidth, mVideoHeight);
        return ENCODE_INVALID_PARAMS;
    }

    // Set IDR frame refresh interval
    if (mIDRFrameRefreshIntervalInSec < 0) {
        mEncParams->intraPeriod = -1;
    } else if (mIDRFrameRefreshIntervalInSec == 0) {
        mEncParams->intraPeriod = 1;  // All I frames
    } else {
        mEncParams->intraPeriod =
            (mIDRFrameRefreshIntervalInSec * mVideoFrameRate);
    }

    mEncParams->numIntraMB = 0;
    mEncParams->sceneDetect = PV_ON;
    mEncParams->searchRange = 16;
    mEncParams->mv8x8Enable = PV_OFF;
    mEncParams->gobHeaderInterval = 0;
    mEncParams->useACPred = PV_ON;
    mEncParams->intraDCVlcTh = 0;

    return ENCODE_SUCCESS;
}

Encode_Status PVSoftMPEG4Encoder::initEncoder() {
    LOG_V("Begin\n");

    CHECK(!mStarted);

    Encode_Status ret = ENCODE_SUCCESS;
    if (ENCODE_SUCCESS != (ret = initEncParams())) {
        LOG_E("Failed to initialized encoder params");
        mSignalledError = true;
        return ret;
    }

    if (!PVInitVideoEncoder(mHandle, mEncParams)) {
        LOG_E("Failed to initialize the encoder");
        mSignalledError = true;
        return ENCODE_FAIL;
    }

    mNumInputFrames = -1;  // 1st buffer for codec specific data
    mStarted = true;
    mCurTimestampUs = 0;
    mLastTimestampUs = 0;
    mVolHeaderLength = 256;

    LOG_V("End\n");

    return ENCODE_SUCCESS;
}

Encode_Status PVSoftMPEG4Encoder::releaseEncoder() {
    LOG_V("Begin\n");

    if (!mStarted) {
        return ENCODE_SUCCESS;
    }

    PVCleanUpVideoEncoder(mHandle);

    delete mTrimedInputData;
    mTrimedInputData = NULL;

    delete mInputFrameData;
    mInputFrameData = NULL;

    delete mEncParams;
    mEncParams = NULL;

    delete mHandle;
    mHandle = NULL;

    mStarted = false;

    LOG_V("End\n");

    return ENCODE_SUCCESS;
}

Encode_Status PVSoftMPEG4Encoder::setParameters(
        VideoParamConfigSet *videoEncParams)
{

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
    LOG_I("Config type = %d\n", (int)videoEncParams->type);

    if (mStarted) {
        LOG_E("Encoder has been initialized, should use setConfig to change configurations\n");
        return ENCODE_ALREADY_INIT;
    }

    switch (videoEncParams->type) {
        case VideoParamsTypeCommon: {

            VideoParamsCommon *paramsCommon =
                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);
            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
                return ENCODE_INVALID_PARAMS;
            }
            if(paramsCommon->codedBufNum < 2)
                paramsCommon->codedBufNum =2;
            mComParams = *paramsCommon;

            mVideoWidth = mComParams.resolution.width;
            mVideoHeight = mComParams.resolution.height;
            mVideoFrameRate =  mComParams.frameRate.frameRateNum / \
                               mComParams.frameRate.frameRateDenom;
            mVideoBitRate = mComParams.rcParams.bitRate;
            mVideoColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
            break;
        }

        case VideoParamsTypeStoreMetaDataInBuffers: {
            VideoParamsStoreMetaDataInBuffers *metadata =
                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);

            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
                return ENCODE_INVALID_PARAMS;
            }

            mStoreMetaDataInBuffers = metadata->isEnabled;

            break;
        }

        default: {
            LOG_I ("Wrong ParamType here\n");
            break;
        }
    }

    return ret;
}

Encode_Status PVSoftMPEG4Encoder::getParameters(
        VideoParamConfigSet *videoEncParams) {

    Encode_Status ret = ENCODE_SUCCESS;
    CHECK_NULL_RETURN_IFFAIL(videoEncParams);
    LOG_I("Config type = %d\n", (int)videoEncParams->type);

    switch (videoEncParams->type) {
        case VideoParamsTypeCommon: {

            VideoParamsCommon *paramsCommon =
                    reinterpret_cast <VideoParamsCommon *> (videoEncParams);

            if (paramsCommon->size != sizeof (VideoParamsCommon)) {
                return ENCODE_INVALID_PARAMS;
            }
            *paramsCommon = mComParams;
            break;
        }

        case VideoParamsTypeStoreMetaDataInBuffers: {
            VideoParamsStoreMetaDataInBuffers *metadata =
                    reinterpret_cast <VideoParamsStoreMetaDataInBuffers *> (videoEncParams);

            if (metadata->size != sizeof (VideoParamsStoreMetaDataInBuffers)) {
                return ENCODE_INVALID_PARAMS;
            }

            metadata->isEnabled = mStoreMetaDataInBuffers;

            break;
        }

        default: {
            LOG_I ("Wrong ParamType here\n");
            break;
        }

    }
    return ret;
}

Encode_Status PVSoftMPEG4Encoder::encode(VideoEncRawBuffer *inBuffer, uint32_t timeout)
{
    LOG_V("Begin\n");

    Encode_Status ret = ENCODE_SUCCESS;

    if (mCurTimestampUs <= inBuffer->timeStamp) {
        mLastTimestampUs = mCurTimestampUs;
        mCurTimestampUs = inBuffer->timeStamp;
    }

    if (mNumInputFrames < 0) {
        if (!PVGetVolHeader(mHandle, mVolHeader, &mVolHeaderLength, 0)) {
            LOG_E("Failed to get VOL header");
            mSignalledError = true;
            return ENCODE_FAIL;
        }
        LOG_I("Output VOL header: %d bytes", mVolHeaderLength);
        mNumInputFrames++;
        //return ENCODE_SUCCESS;
    }

    if (mStoreMetaDataInBuffers) {
        IntelMetadataBuffer imb;
        int32_t type;
        int32_t value;
        ValueInfo vinfo;
        ValueInfo *pvinfo = &vinfo;
        CHECK(IMB_SUCCESS == imb.UnSerialize(inBuffer->data, inBuffer->size));
        imb.GetType((::MetadataBufferType&)type);
        imb.GetValue(value);
        imb.GetValueInfo(pvinfo);
        if (mNumInputFrames == 0)
            LOG_I("%d %d %d\n", pvinfo->width,
                    pvinfo->height, pvinfo->lumaStride);
        if (pvinfo != NULL)
            trimBuffer((uint8_t*)value, mTrimedInputData, pvinfo->width, pvinfo->height, pvinfo->lumaStride);
        else
            LOG_E("failed to parse metadata info");
    } else {
        memcpy(mTrimedInputData, inBuffer->data,
                (mVideoWidth * mVideoHeight * 3 ) >> 1);
    }

    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
        ConvertYUV420SemiPlanarToYUV420Planar(
                mTrimedInputData, mInputFrameData, mVideoWidth, mVideoHeight);
    } else {
        memcpy(mTrimedInputData, mInputFrameData,
                (mVideoWidth * mVideoHeight * 3 ) >> 1);
    }

    LOG_V("End\n");

    return ret;
}

Encode_Status PVSoftMPEG4Encoder::getOutput(VideoEncOutputBuffer *outBuffer, uint32_t timeout)
{
    LOG_V("Begin\n");

    Encode_Status ret = ENCODE_SUCCESS;
    uint8_t *outPtr = outBuffer->data;
    int32_t dataLength = outBuffer->bufferSize;
    outBuffer->flag = 0;

    if ((mEncodeMode == COMBINE_MODE_WITH_ERR_RES) &&
            (outBuffer->format == OUTPUT_CODEC_DATA)) {
        memcpy(outPtr, mVolHeader, mVolHeaderLength);
        ++mNumInputFrames;
        outBuffer->flag |= ENCODE_BUFFERFLAG_CODECCONFIG;
        outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
        outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
        outBuffer->dataSize = mVolHeaderLength;
        outBuffer->remainingSize = 0;
        return ENCODE_SUCCESS;
    }

    outBuffer->timeStamp = mCurTimestampUs;
    LOG_I("info.mTimeUs %lld\n", outBuffer->timeStamp);

    VideoEncFrameIO vin, vout;
    memset(&vin, 0, sizeof(vin));
    memset(&vout, 0, sizeof(vout));
    vin.height = ((mVideoHeight  + 15) >> 4) << 4;
    vin.pitch = ((mVideoWidth + 15) >> 4) << 4;
    vin.timestamp = (outBuffer->timeStamp + 500) / 1000;  // in ms
    vin.yChan = mInputFrameData;
    vin.uChan = vin.yChan + vin.height * vin.pitch;
    vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);

    unsigned long modTimeMs = 0;
    int32_t nLayer = 0;
    MP4HintTrack hintTrack;
    if (!PVEncodeVideoFrame(mHandle, &vin, &vout,
                &modTimeMs, outPtr, &dataLength, &nLayer) ||
            !PVGetHintTrack(mHandle, &hintTrack)) {
        LOG_E("Failed to encode frame or get hink track at frame %lld",
                mNumInputFrames);
        mSignalledError = true;
        hintTrack.CodeType = 0;
        ret = ENCODE_FAIL;
    }
    LOG_I("dataLength %d\n", dataLength);
    CHECK(NULL == PVGetOverrunBuffer(mHandle));
    if (hintTrack.CodeType == 0) {  // I-frame serves as sync frame
        outBuffer->flag |= ENCODE_BUFFERFLAG_SYNCFRAME;
    }

    ++mNumInputFrames;

    outBuffer->flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
    outBuffer->dataSize = dataLength;

    LOG_V("End\n");

    return ret;
}

