/*
 * Copyright (C) 2010 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.
 */

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

#include "M4vH263Encoder.h"

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

#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>

namespace android {

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++ = tempV;
            *outcr++ = tempU;
        }
    }
}

M4vH263Encoder::M4vH263Encoder(
        const sp<MediaSource>& source,
        const sp<MetaData>& meta)
    : mSource(source),
      mMeta(meta),
      mNumInputFrames(-1),
      mNextModTimeUs(0),
      mPrevTimestampUs(-1),
      mStarted(false),
      mInputBuffer(NULL),
      mInputFrameData(NULL),
      mGroup(NULL) {

    LOGV("Construct software M4vH263Encoder");

    mHandle = new tagvideoEncControls;
    memset(mHandle, 0, sizeof(tagvideoEncControls));

    mInitCheck = initCheck(meta);
}

M4vH263Encoder::~M4vH263Encoder() {
    LOGV("Destruct software M4vH263Encoder");
    if (mStarted) {
        stop();
    }

    delete mEncParams;
    delete mHandle;
}

status_t M4vH263Encoder::initCheck(const sp<MetaData>& meta) {
    LOGV("initCheck");
    CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
    CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
    CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
    CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));

    // XXX: Add more color format support
    CHECK(meta->findInt32(kKeyColorFormat, &mVideoColorFormat));
    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
        if (mVideoColorFormat != OMX_COLOR_FormatYUV420SemiPlanar) {
            LOGE("Color format %d is not supported", mVideoColorFormat);
            return BAD_VALUE;
        }
        // Allocate spare buffer only when color conversion is needed.
        // Assume the color format is OMX_COLOR_FormatYUV420SemiPlanar.
        mInputFrameData =
            (uint8_t *) malloc((mVideoWidth * mVideoHeight * 3 ) >> 1);
        CHECK(mInputFrameData);
    }

    // XXX: Remove this restriction
    if (mVideoWidth % 16 != 0 || mVideoHeight % 16 != 0) {
        LOGE("Video frame size %dx%d must be a multiple of 16",
            mVideoWidth, mVideoHeight);
        return BAD_VALUE;
    }

    mEncParams = new tagvideoEncOptions;
    memset(mEncParams, 0, sizeof(tagvideoEncOptions));
    if (!PVGetDefaultEncOption(mEncParams, 0)) {
        LOGE("Failed to get default encoding parameters");
        return BAD_VALUE;
    }

    // Need to know which role the encoder is in.
    // XXX: Set the mode proper for other types of applications
    //      like streaming or video conference
    const char *mime;
    CHECK(meta->findCString(kKeyMIMEType, &mime));
    CHECK(!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
          !strcmp(mime, MEDIA_MIMETYPE_VIDEO_H263));
    if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)) {
        mEncParams->encMode = COMBINE_MODE_WITH_ERR_RES;
    } else {
        mEncParams->encMode = H263_MODE;
    }
    mEncParams->encWidth[0] = mVideoWidth;
    mEncParams->encHeight[0] = mVideoHeight;
    mEncParams->encFrameRate[0] = mVideoFrameRate;
    mEncParams->rcType = VBR_1;
    mEncParams->vbvDelay = (float)5.0;

    // Set profile and level
    // If profile and level setting is not correct, failure
    // is reported when the encoder is initialized.
    mEncParams->profile_level = CORE_PROFILE_LEVEL2;
    int32_t profileLevel;
    if (meta->findInt32(kKeyVideoLevel, &profileLevel)) {
        mEncParams->profile_level = (ProfileLevelType)profileLevel;
    }

    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;

    // Set IDR frame refresh interval
    int32_t iFramesIntervalSec;
    CHECK(meta->findInt32(kKeyIFramesInterval, &iFramesIntervalSec));
    if (iFramesIntervalSec < 0) {
        mEncParams->intraPeriod = -1;
    } else if (iFramesIntervalSec == 0) {
        mEncParams->intraPeriod = 1;  // All I frames
    } else {
        mEncParams->intraPeriod =
            (iFramesIntervalSec * 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;

    mFormat = new MetaData;
    mFormat->setInt32(kKeyWidth, mVideoWidth);
    mFormat->setInt32(kKeyHeight, mVideoHeight);
    mFormat->setInt32(kKeyBitRate, mVideoBitRate);
    mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
    mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);

    mFormat->setCString(kKeyMIMEType, mime);
    mFormat->setCString(kKeyDecoderComponent, "M4vH263Encoder");
    return OK;
}

status_t M4vH263Encoder::start(MetaData *params) {
    LOGV("start");
    if (mInitCheck != OK) {
        return mInitCheck;
    }

    if (mStarted) {
        LOGW("Call start() when encoder already started");
        return OK;
    }

    if (!PVInitVideoEncoder(mHandle, mEncParams)) {
        LOGE("Failed to initialize the encoder");
        return UNKNOWN_ERROR;
    }

    mGroup = new MediaBufferGroup();
    int32_t maxSize;
    if (!PVGetMaxVideoFrameSize(mHandle, &maxSize)) {
        maxSize = 256 * 1024;  // Magic #
    }
    LOGV("Max output buffer size: %d", maxSize);
    mGroup->add_buffer(new MediaBuffer(maxSize));

    mSource->start(params);
    mNumInputFrames = -1;  // 1st frame contains codec specific data
    mStarted = true;

    return OK;
}

status_t M4vH263Encoder::stop() {
    LOGV("stop");
    if (!mStarted) {
        LOGW("Call stop() when encoder has not started");
        return OK;
    }

    if (mInputBuffer) {
        mInputBuffer->release();
        mInputBuffer = NULL;
    }

    if (mGroup) {
        delete mGroup;
        mGroup = NULL;
    }

    if (mInputFrameData) {
        delete mInputFrameData;
        mInputFrameData = NULL;
    }

    CHECK(PVCleanUpVideoEncoder(mHandle));

    mSource->stop();
    mStarted = false;

    return OK;
}

sp<MetaData> M4vH263Encoder::getFormat() {
    LOGV("getFormat");
    return mFormat;
}

status_t M4vH263Encoder::read(
        MediaBuffer **out, const ReadOptions *options) {

    *out = NULL;

    MediaBuffer *outputBuffer;
    CHECK_EQ(OK, mGroup->acquire_buffer(&outputBuffer));
    uint8_t *outPtr = (uint8_t *) outputBuffer->data();
    int32_t dataLength = outputBuffer->size();

    // Output codec specific data
    if (mNumInputFrames < 0) {
        if (!PVGetVolHeader(mHandle, outPtr, &dataLength, 0)) {
            LOGE("Failed to get VOL header");
            return UNKNOWN_ERROR;
        }
        LOGV("Output VOL header: %d bytes", dataLength);
        outputBuffer->meta_data()->setInt32(kKeyIsCodecConfig, 1);
        outputBuffer->set_range(0, dataLength);
        *out = outputBuffer;
        ++mNumInputFrames;
        return OK;
    }

    // Ready for accepting an input video frame
    if (OK != mSource->read(&mInputBuffer, options)) {
        LOGE("Failed to read from data source");
        outputBuffer->release();
        return UNKNOWN_ERROR;
    }

    if (mInputBuffer->size() - ((mVideoWidth * mVideoHeight * 3) >> 1) != 0) {
        outputBuffer->release();
        mInputBuffer->release();
        mInputBuffer = NULL;
        return UNKNOWN_ERROR;
    }

    int64_t timeUs;
    CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));

    // When the timestamp of the current sample is the same as that
    // of the previous sample, encoding of the current sample is
    // bypassed, and the output length of the sample is set to 0
    if (mNumInputFrames >= 1 &&
        (mNextModTimeUs > timeUs || mPrevTimestampUs == timeUs)) {
        // Frame arrives too late
        outputBuffer->set_range(0, 0);
        *out = outputBuffer;
        mInputBuffer->release();
        mInputBuffer = NULL;
        return OK;
    }

    // Don't accept out-of-order samples
    CHECK(mPrevTimestampUs < timeUs);
    mPrevTimestampUs = timeUs;

    // Color convert to OMX_COLOR_FormatYUV420Planar if necessary
    outputBuffer->meta_data()->setInt64(kKeyTime, timeUs);
    uint8_t *inPtr = (uint8_t *) mInputBuffer->data();
    if (mVideoColorFormat != OMX_COLOR_FormatYUV420Planar) {
        CHECK(mInputFrameData);
        CHECK(mVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar);
        ConvertYUV420SemiPlanarToYUV420Planar(
            inPtr, mInputFrameData, mVideoWidth, mVideoHeight);
        inPtr = mInputFrameData;
    }
    CHECK(inPtr != NULL);

    // Ready for encoding a video frame
    VideoEncFrameIO vin, vout;
    vin.height = ((mVideoHeight + 15) >> 4) << 4;
    vin.pitch  = ((mVideoWidth  + 15) >> 4) << 4;
    vin.timestamp = (timeUs + 500) / 1000; // in ms
    vin.yChan = inPtr;
    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)) {
        LOGE("Failed to encode frame or get hink track at frame %lld",
            mNumInputFrames);
        outputBuffer->release();
        mInputBuffer->release();
        mInputBuffer = NULL;
        return UNKNOWN_ERROR;
    }
    CHECK_EQ(NULL, PVGetOverrunBuffer(mHandle));
    if (hintTrack.CodeType == 0) {  // I-frame serves as sync frame
        outputBuffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
    }

    ++mNumInputFrames;
    mNextModTimeUs = modTimeMs * 1000LL;
    outputBuffer->set_range(0, dataLength);
    *out = outputBuffer;
    mInputBuffer->release();
    mInputBuffer = NULL;
    return OK;
}

void M4vH263Encoder::signalBufferReturned(MediaBuffer *buffer) {
}

}  // namespace android
