/*
 * Copyright (C) 2011 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 "SoftVPX"
#include <utils/Log.h>

#include "SoftVPX.h"

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


namespace android {

SoftVPX::SoftVPX(
        const char *name,
        const char *componentRole,
        OMX_VIDEO_CODINGTYPE codingType,
        const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData,
        OMX_COMPONENTTYPE **component)
    : SoftVideoDecoderOMXComponent(
            name, componentRole, codingType,
            NULL /* profileLevels */, 0 /* numProfileLevels */,
            320 /* width */, 240 /* height */, callbacks, appData, component),
      mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9),
      mEOSStatus(INPUT_DATA_AVAILABLE),
      mCtx(NULL),
      mFrameParallelMode(false),
      mTimeStampIdx(0),
      mImg(NULL) {
    // arbitrary from avc/hevc as vpx does not specify a min compression ratio
    const size_t kMinCompressionRatio = mMode == MODE_VP8 ? 2 : 4;
    const char *mime = mMode == MODE_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9;
    const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;
    initPorts(
            kNumBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* inputBufferSize */,
            kNumBuffers, mime, kMinCompressionRatio);
    CHECK_EQ(initDecoder(), (status_t)OK);
}

SoftVPX::~SoftVPX() {
    destroyDecoder();
}

static int GetCPUCoreCount() {
    int cpuCoreCount = 1;
#if defined(_SC_NPROCESSORS_ONLN)
    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
#else
    // _SC_NPROC_ONLN must be defined...
    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
#endif
    CHECK(cpuCoreCount >= 1);
    ALOGV("Number of CPU cores: %d", cpuCoreCount);
    return cpuCoreCount;
}

status_t SoftVPX::initDecoder() {
    mCtx = new vpx_codec_ctx_t;
    vpx_codec_err_t vpx_err;
    vpx_codec_dec_cfg_t cfg;
    vpx_codec_flags_t flags;
    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
    memset(&flags, 0, sizeof(vpx_codec_flags_t));
    cfg.threads = GetCPUCoreCount();

    if (mFrameParallelMode) {
        flags |= VPX_CODEC_USE_FRAME_THREADING;
    }

    if ((vpx_err = vpx_codec_dec_init(
                (vpx_codec_ctx_t *)mCtx,
                 mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo,
                 &cfg, flags))) {
        ALOGE("on2 decoder failed to initialize. (%d)", vpx_err);
        return UNKNOWN_ERROR;
    }

    return OK;
}

status_t SoftVPX::destroyDecoder() {
    vpx_codec_destroy((vpx_codec_ctx_t *)mCtx);
    delete (vpx_codec_ctx_t *)mCtx;
    mCtx = NULL;
    return OK;
}

bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset) {
    List<BufferInfo *> &outQueue = getPortQueue(1);
    BufferInfo *outInfo = NULL;
    OMX_BUFFERHEADERTYPE *outHeader = NULL;
    vpx_codec_iter_t iter = NULL;

    if (flushDecoder && mFrameParallelMode) {
        // Flush decoder by passing NULL data ptr and 0 size.
        // Ideally, this should never fail.
        if (vpx_codec_decode((vpx_codec_ctx_t *)mCtx, NULL, 0, NULL, 0)) {
            ALOGE("Failed to flush on2 decoder.");
            return false;
        }
    }

    if (!display) {
        if (!flushDecoder) {
            ALOGE("Invalid operation.");
            return false;
        }
        // Drop all the decoded frames in decoder.
        while ((mImg = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter))) {
        }
        return true;
    }

    while (!outQueue.empty()) {
        if (mImg == NULL) {
            mImg = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
            if (mImg == NULL) {
                break;
            }
        }
        uint32_t width = mImg->d_w;
        uint32_t height = mImg->d_h;
        outInfo = *outQueue.begin();
        outHeader = outInfo->mHeader;
        CHECK_EQ(mImg->fmt, VPX_IMG_FMT_I420);
        handlePortSettingsChange(portWillReset, width, height);
        if (*portWillReset) {
            return true;
        }

        outHeader->nOffset = 0;
        outHeader->nFlags = 0;
        outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
        outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv;
        if (outHeader->nAllocLen >= outHeader->nFilledLen) {
            uint8_t *dst = outHeader->pBuffer;
            const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y];
            const uint8_t *srcU = (const uint8_t *)mImg->planes[VPX_PLANE_U];
            const uint8_t *srcV = (const uint8_t *)mImg->planes[VPX_PLANE_V];
            size_t srcYStride = mImg->stride[VPX_PLANE_Y];
            size_t srcUStride = mImg->stride[VPX_PLANE_U];
            size_t srcVStride = mImg->stride[VPX_PLANE_V];
            copyYV12FrameToOutputBuffer(dst, srcY, srcU, srcV, srcYStride, srcUStride, srcVStride);
        } else {
            ALOGE("b/27597103, buffer too small");
            android_errorWriteLog(0x534e4554, "27597103");
            outHeader->nFilledLen = 0;
        }

        mImg = NULL;
        outInfo->mOwnedByUs = false;
        outQueue.erase(outQueue.begin());
        outInfo = NULL;
        notifyFillBufferDone(outHeader);
        outHeader = NULL;
    }

    if (!eos) {
        return true;
    }

    if (!outQueue.empty()) {
        outInfo = *outQueue.begin();
        outQueue.erase(outQueue.begin());
        outHeader = outInfo->mHeader;
        outHeader->nTimeStamp = 0;
        outHeader->nFilledLen = 0;
        outHeader->nFlags = OMX_BUFFERFLAG_EOS;
        outInfo->mOwnedByUs = false;
        notifyFillBufferDone(outHeader);
        mEOSStatus = OUTPUT_FRAMES_FLUSHED;
    }
    return true;
}

void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) {
    if (mOutputPortSettingsChange != NONE || mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
        return;
    }

    List<BufferInfo *> &inQueue = getPortQueue(0);
    List<BufferInfo *> &outQueue = getPortQueue(1);
    bool EOSseen = false;
    bool portWillReset = false;

    while ((mEOSStatus == INPUT_EOS_SEEN || !inQueue.empty())
            && !outQueue.empty()) {
        // Output the pending frames that left from last port reset or decoder flush.
        if (mEOSStatus == INPUT_EOS_SEEN || mImg != NULL) {
            if (!outputBuffers(
                     mEOSStatus == INPUT_EOS_SEEN, true /* display */,
                     mEOSStatus == INPUT_EOS_SEEN, &portWillReset)) {
                ALOGE("on2 decoder failed to output frame.");
                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
                return;
            }
            if (portWillReset || mEOSStatus == OUTPUT_FRAMES_FLUSHED ||
                    mEOSStatus == INPUT_EOS_SEEN) {
                return;
            }
        }

        BufferInfo *inInfo = *inQueue.begin();
        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
        mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp;

        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
            mEOSStatus = INPUT_EOS_SEEN;
            EOSseen = true;
        }

        if (inHeader->nFilledLen > 0 &&
            vpx_codec_decode((vpx_codec_ctx_t *)mCtx,
                              inHeader->pBuffer + inHeader->nOffset,
                              inHeader->nFilledLen,
                              &mTimeStamps[mTimeStampIdx], 0)) {
            ALOGE("on2 decoder failed to decode frame.");
            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
            return;
        }
        mTimeStampIdx = (mTimeStampIdx + 1) % kNumBuffers;

        if (!outputBuffers(
                 EOSseen /* flushDecoder */, true /* display */, EOSseen, &portWillReset)) {
            ALOGE("on2 decoder failed to output frame.");
            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
            return;
        }
        if (portWillReset) {
            return;
        }

        inInfo->mOwnedByUs = false;
        inQueue.erase(inQueue.begin());
        inInfo = NULL;
        notifyEmptyBufferDone(inHeader);
        inHeader = NULL;
    }
}

void SoftVPX::onPortFlushCompleted(OMX_U32 portIndex) {
    if (portIndex == kInputPortIndex) {
        bool portWillReset = false;
        if (!outputBuffers(
                 true /* flushDecoder */, false /* display */, false /* eos */, &portWillReset)) {
            ALOGE("Failed to flush decoder.");
            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
            return;
        }
        mEOSStatus = INPUT_DATA_AVAILABLE;
    }
}

void SoftVPX::onReset() {
    bool portWillReset = false;
    if (!outputBuffers(
             true /* flushDecoder */, false /* display */, false /* eos */, &portWillReset)) {
        ALOGW("Failed to flush decoder. Try to hard reset decoder");
        destroyDecoder();
        initDecoder();
    }
    mEOSStatus = INPUT_DATA_AVAILABLE;
}

}  // namespace android

android::SoftOMXComponent *createSoftOMXComponent(
        const char *name, const OMX_CALLBACKTYPE *callbacks,
        OMX_PTR appData, OMX_COMPONENTTYPE **component) {
    if (!strcmp(name, "OMX.google.vp8.decoder")) {
        return new android::SoftVPX(
                name, "video_decoder.vp8", OMX_VIDEO_CodingVP8,
                callbacks, appData, component);
    } else if (!strcmp(name, "OMX.google.vp9.decoder")) {
        return new android::SoftVPX(
                name, "video_decoder.vp9", OMX_VIDEO_CodingVP9,
                callbacks, appData, component);
    } else {
        CHECK(!"Unknown component");
    }
    return NULL;
}
