/*
 * 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 "VideoSourceDownSampler"

#include <media/stagefright/VideoSourceDownSampler.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/YUVImage.h>
#include <media/stagefright/YUVCanvas.h>
#include "OMX_Video.h"

namespace android {

VideoSourceDownSampler::VideoSourceDownSampler(const sp<MediaSource> &videoSource,
        int32_t width, int32_t height) {
    LOGV("Construct VideoSourceDownSampler");
    CHECK(width > 0);
    CHECK(height > 0);

    mRealVideoSource = videoSource;
    mWidth = width;
    mHeight = height;

    mMeta = new MetaData(*(mRealVideoSource->getFormat()));
    CHECK(mMeta->findInt32(kKeyWidth, &mRealSourceWidth));
    CHECK(mMeta->findInt32(kKeyHeight, &mRealSourceHeight));

    if ((mWidth != mRealSourceWidth) || (mHeight != mRealSourceHeight)) {
        // Change meta data for width and height.
        CHECK(mWidth <= mRealSourceWidth);
        CHECK(mHeight <= mRealSourceHeight);

        mNeedDownSampling = true;
        computeDownSamplingParameters();
        mMeta->setInt32(kKeyWidth, mWidth);
        mMeta->setInt32(kKeyHeight, mHeight);
    } else {
        mNeedDownSampling = false;
    }
}

VideoSourceDownSampler::~VideoSourceDownSampler() {
}

void VideoSourceDownSampler::computeDownSamplingParameters() {
    mDownSampleSkipX = mRealSourceWidth / mWidth;
    mDownSampleSkipY = mRealSourceHeight / mHeight;

    mDownSampleOffsetX = mRealSourceWidth - mDownSampleSkipX * mWidth;
    mDownSampleOffsetY = mRealSourceHeight - mDownSampleSkipY * mHeight;
}

void VideoSourceDownSampler::downSampleYUVImage(
        const MediaBuffer &sourceBuffer, MediaBuffer **buffer) const {
    // find the YUV format
    int32_t srcFormat;
    CHECK(mMeta->findInt32(kKeyColorFormat, &srcFormat));
    YUVImage::YUVFormat yuvFormat;
    if (srcFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
        yuvFormat = YUVImage::YUV420SemiPlanar;
    } else if (srcFormat == OMX_COLOR_FormatYUV420Planar) {
        yuvFormat = YUVImage::YUV420Planar;
    }

    // allocate mediaBuffer for down sampled image and setup a canvas.
    *buffer = new MediaBuffer(YUVImage::bufferSize(yuvFormat, mWidth, mHeight));
    YUVImage yuvDownSampledImage(yuvFormat,
            mWidth, mHeight,
            (uint8_t *)(*buffer)->data());
    YUVCanvas yuvCanvasDownSample(yuvDownSampledImage);

    YUVImage yuvImageSource(yuvFormat,
            mRealSourceWidth, mRealSourceHeight,
            (uint8_t *)sourceBuffer.data());
    yuvCanvasDownSample.downsample(mDownSampleOffsetX, mDownSampleOffsetY,
            mDownSampleSkipX, mDownSampleSkipY,
            yuvImageSource);
}

status_t VideoSourceDownSampler::start(MetaData *params) {
    LOGV("start");
    return mRealVideoSource->start();
}

status_t VideoSourceDownSampler::stop() {
    LOGV("stop");
    return mRealVideoSource->stop();
}

sp<MetaData> VideoSourceDownSampler::getFormat() {
    LOGV("getFormat");
    return mMeta;
}

status_t VideoSourceDownSampler::read(
        MediaBuffer **buffer, const ReadOptions *options) {
    LOGV("read");
    MediaBuffer *realBuffer;
    status_t err = mRealVideoSource->read(&realBuffer, options);

    if (mNeedDownSampling) {
        downSampleYUVImage(*realBuffer, buffer);

        int64_t frameTime;
        realBuffer->meta_data()->findInt64(kKeyTime, &frameTime);
        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);

        // We just want this buffer to be deleted when the encoder releases it.
        // So don't add a reference to it and set the observer to NULL.
        (*buffer)->setObserver(NULL);

        // The original buffer is no longer required. Release it.
        realBuffer->release();
    } else {
        *buffer = realBuffer;
    }

    return err;
}

status_t VideoSourceDownSampler::pause() {
    LOGV("pause");
    return mRealVideoSource->pause();
}

}  // namespace android
