/*
* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
*
* 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 "VideoDecoderVP8.h"
#include "VideoDecoderTrace.h"
#include <string.h>

VideoDecoderVP8::VideoDecoderVP8(const char *mimeType)
    : VideoDecoderBase(mimeType, VBP_VP8) {
    invalidateReferenceFrames(0);
    invalidateReferenceFrames(1);
}

VideoDecoderVP8::~VideoDecoderVP8() {
    stop();
}

void VideoDecoderVP8::invalidateReferenceFrames(int toggle) {
    ReferenceFrameBuffer *p = mRFBs[toggle];
    for (int i = 0; i < VP8_REF_SIZE; i++) {
        p->index = (uint32_t) -1;
        p->surfaceBuffer = NULL;
        p++;
    }
}

void VideoDecoderVP8::clearAsReference(int toggle, int ref_type) {
    ReferenceFrameBuffer ref = mRFBs[toggle][ref_type];
    if (ref.surfaceBuffer) {
        ref.surfaceBuffer->asReferernce = false;
    }
}

void VideoDecoderVP8::updateFormatInfo(vbp_data_vp8 *data) {
    uint32_t width = data->codec_data->frame_width;
    uint32_t height = data->codec_data->frame_height;
    ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d",
            mVideoFormatInfo.width, mVideoFormatInfo.height, width, height);

    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
        pthread_mutex_lock(&mFormatLock);
    }

    if ((mVideoFormatInfo.width != width ||
            mVideoFormatInfo.height != height) &&
            width && height) {
        if ((VideoDecoderBase::alignMB(mVideoFormatInfo.width) != width) ||
            (VideoDecoderBase::alignMB(mVideoFormatInfo.height) != height)) {
            mSizeChanged = true;
            ITRACE("Video size is changed.");
        }
        mVideoFormatInfo.width = width;
        mVideoFormatInfo.height = height;
    }

    // video_range has default value of 0. Y ranges from 16 to 235.
    mVideoFormatInfo.videoRange = 0;

    switch (data->codec_data->clr_type) {
        case 0:
            mVideoFormatInfo.colorMatrix = VA_SRC_BT601;
            break;
        case 1:
        default:
            mVideoFormatInfo.colorMatrix = 0;
            break;
    }

    mVideoFormatInfo.cropLeft = data->codec_data->crop_left;
    mVideoFormatInfo.cropRight = data->codec_data->crop_right;
    mVideoFormatInfo.cropTop = data->codec_data->crop_top;
    mVideoFormatInfo.cropBottom = data->codec_data->crop_bottom;
    ITRACE("Cropping: left = %d, top = %d, right = %d, bottom = %d", data->codec_data->crop_left, data->codec_data->crop_top, data->codec_data->crop_right, data->codec_data->crop_bottom);

    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
        if (mSizeChanged) {
            mVideoFormatInfo.valid = false;
        } else {
            mVideoFormatInfo.valid = true;
        }

        pthread_mutex_unlock(&mFormatLock);
    } else {
        mVideoFormatInfo.valid = true;
    }

    setRenderRect();
    setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);
}

Decode_Status VideoDecoderVP8::startVA(vbp_data_vp8 *data) {
    updateFormatInfo(data);

    VAProfile vaProfile = VAProfileVP8Version0_3;
    if (data->codec_data->version_num > 3) {
        return DECODE_PARSER_FAIL;
    }

    enableLowDelayMode(true);

    return VideoDecoderBase::setupVA(VP8_SURFACE_NUMBER + VP8_REF_SIZE, vaProfile);
}

Decode_Status VideoDecoderVP8::start(VideoConfigBuffer *buffer) {
    Decode_Status status;

    status = VideoDecoderBase::start(buffer);
    CHECK_STATUS("VideoDecoderBase::start");

    // We don't want base class to manage reference.
    VideoDecoderBase::ManageReference(false);

    if (buffer->data == NULL || buffer->size == 0) {
        WTRACE("No config data to start VA.");
        return DECODE_SUCCESS;
    }

    vbp_data_vp8 *data = NULL;
    status = VideoDecoderBase::parseBuffer(buffer->data, buffer->size, true, (void**)&data);
    CHECK_STATUS("VideoDecoderBase::parseBuffer");

    status = startVA(data);
    return status;
}

void VideoDecoderVP8::stop(void) {
    VideoDecoderBase::stop();

    invalidateReferenceFrames(0);
    invalidateReferenceFrames(1);
}

void VideoDecoderVP8::flush(void) {
    VideoDecoderBase::flush();

    invalidateReferenceFrames(0);
    invalidateReferenceFrames(1);
}

Decode_Status VideoDecoderVP8::decode(VideoDecodeBuffer *buffer) {
    Decode_Status status;
    vbp_data_vp8 *data = NULL;
    if (buffer == NULL) {
        ETRACE("VideoDecodeBuffer is NULL.");
        return DECODE_INVALID_DATA;
    }

    status = VideoDecoderBase::parseBuffer(
                 buffer->data,
                 buffer->size,
                 false,
                 (void**)&data);
    CHECK_STATUS("VideoDecoderBase::parseBuffer");

    mShowFrame = data->codec_data->show_frame;

    if (!mVAStarted) {
        status = startVA(data);
        CHECK_STATUS("startVA");
    }

    VideoDecoderBase::setRotationDegrees(buffer->rotationDegrees);

    status = decodeFrame(buffer, data);

    return status;
}

Decode_Status VideoDecoderVP8::decodeFrame(VideoDecodeBuffer* buffer, vbp_data_vp8 *data) {
    Decode_Status status;
    bool useGraphicbuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
    mCurrentPTS = buffer->timeStamp;
    if (0 == data->num_pictures || NULL == data->pic_data) {
        WTRACE("Number of pictures is 0.");
        return DECODE_SUCCESS;
    }

    if (VP8_KEY_FRAME == data->codec_data->frame_type) {
        updateFormatInfo(data);
        if (mSizeChanged && !(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
            mSizeChanged = false;
            return DECODE_FORMAT_CHANGE;
        }

        bool needFlush = false;
        if (useGraphicbuffer) {
            // For VP8 in adaptive playback legacy mode,
            // force buffer reallocation.
            needFlush = mSizeChanged;
        }
        if (needFlush) {
            if (mStoreMetaData) {
                status = endDecodingFrame(false);
                CHECK_STATUS("endDecodingFrame");
            } else {
                flushSurfaceBuffers();
            }
            mSizeChanged = false;
            return DECODE_FORMAT_CHANGE;
        }
    }

    if (data->codec_data->frame_type == VP8_SKIPPED_FRAME) {
        // Do nothing for skip frame as the last frame will be rendered agian by natively
        return DECODE_SUCCESS;
    }

    status = acquireSurfaceBuffer();
    CHECK_STATUS("acquireSurfaceBuffer");

    // set referenceFrame to true if frame decoded is I/P frame, false otherwise.
    int frameType = data->codec_data->frame_type;
    mAcquiredBuffer->referenceFrame = (frameType == VP8_KEY_FRAME || frameType == VP8_INTER_FRAME);
    // assume it is frame picture.
    mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
    mAcquiredBuffer->renderBuffer.timeStamp = buffer->timeStamp;
    mAcquiredBuffer->renderBuffer.flag = 0;
    if (buffer->flag & WANT_DECODE_ONLY) {
        mAcquiredBuffer->renderBuffer.flag |= WANT_DECODE_ONLY;
    }
    if (mSizeChanged) {
        mSizeChanged = false;
        mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
    }

    // Here data->num_pictures is always equal to 1
    for (uint32_t index = 0; index < data->num_pictures; index++) {
        status = decodePicture(data, index);
        if (status != DECODE_SUCCESS) {
            endDecodingFrame(true);
            return status;
        }
    }

    if (frameType != VP8_SKIPPED_FRAME) {
        updateReferenceFrames(data);
    }

    // if sample is successfully decoded, call outputSurfaceBuffer(); otherwise
    // call releaseSurfacebuffer();
    status = outputSurfaceBuffer();
    return status;
}

Decode_Status VideoDecoderVP8::decodePicture(vbp_data_vp8 *data, int32_t picIndex) {
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    Decode_Status status;
    uint32_t bufferIDCount = 0;
    VABufferID bufferIDs[5];

    vbp_picture_data_vp8 *picData = &(data->pic_data[picIndex]);
    VAPictureParameterBufferVP8 *picParams = picData->pic_parms;

    status = setReference(picParams);
    CHECK_STATUS("setReference");

    vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
    CHECK_VA_STATUS("vaBeginPicture");
    // setting mDecodingFrame to true so vaEndPicture will be invoked to end the picture decoding.
    mDecodingFrame = true;

    vaStatus = vaCreateBuffer(
                   mVADisplay,
                   mVAContext,
                   VAPictureParameterBufferType,
                   sizeof(VAPictureParameterBufferVP8),
                   1,
                   picParams,
                   &bufferIDs[bufferIDCount]);
    CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
    bufferIDCount++;

    vaStatus = vaCreateBuffer(
                   mVADisplay,
                   mVAContext,
                   VAProbabilityBufferType,
                   sizeof(VAProbabilityDataBufferVP8),
                   1,
                   data->prob_data,
                   &bufferIDs[bufferIDCount]);
    CHECK_VA_STATUS("vaCreateProbabilityBuffer");
    bufferIDCount++;

    vaStatus = vaCreateBuffer(
                   mVADisplay,
                   mVAContext,
                   VAIQMatrixBufferType,
                   sizeof(VAIQMatrixBufferVP8),
                   1,
                   data->IQ_matrix_buf,
                   &bufferIDs[bufferIDCount]);
    CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
    bufferIDCount++;

    /* Here picData->num_slices is always equal to 1 */
    for (uint32_t i = 0; i < picData->num_slices; i++) {
        vaStatus = vaCreateBuffer(
                       mVADisplay,
                       mVAContext,
                       VASliceParameterBufferType,
                       sizeof(VASliceParameterBufferVP8),
                       1,
                       &(picData->slc_data[i].slc_parms),
                       &bufferIDs[bufferIDCount]);
        CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
        bufferIDCount++;

        vaStatus = vaCreateBuffer(
                       mVADisplay,
                       mVAContext,
                       VASliceDataBufferType,
                       picData->slc_data[i].slice_size, //size
                       1,        //num_elements
                       picData->slc_data[i].buffer_addr + picData->slc_data[i].slice_offset,
                       &bufferIDs[bufferIDCount]);
        CHECK_VA_STATUS("vaCreateSliceDataBuffer");
        bufferIDCount++;
    }

    vaStatus = vaRenderPicture(
                   mVADisplay,
                   mVAContext,
                   bufferIDs,
                   bufferIDCount);
    CHECK_VA_STATUS("vaRenderPicture");

    vaStatus = vaEndPicture(mVADisplay, mVAContext);
    mDecodingFrame = false;
    CHECK_VA_STATUS("vaEndPicture");

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderVP8::setReference(VAPictureParameterBufferVP8 *picParam) {
    int frameType = picParam->pic_fields.bits.key_frame;
    switch (frameType) {
    case VP8_KEY_FRAME:
        picParam->last_ref_frame = VA_INVALID_SURFACE;
        picParam->alt_ref_frame = VA_INVALID_SURFACE;
        picParam->golden_ref_frame = VA_INVALID_SURFACE;
        break;
    case VP8_INTER_FRAME:
        if (mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer   == NULL ||
                mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer    == NULL ||
                mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer == NULL) {
            mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 1;
            mAcquiredBuffer->renderBuffer.errBuf.errorArray[0].type = DecodeRefMissing;
            return DECODE_NO_REFERENCE;
        }
        //mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer = mLastReference;
        picParam->last_ref_frame = mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer->renderBuffer.surface;
        picParam->alt_ref_frame = mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer->renderBuffer.surface;
        picParam->golden_ref_frame = mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer->renderBuffer.surface;
        break;
    case VP8_SKIPPED_FRAME:
        // will never happen here
        break;
    default:
        return DECODE_PARSER_FAIL;
    }

    return DECODE_SUCCESS;
}

void VideoDecoderVP8::updateReferenceFrames(vbp_data_vp8 *data) {
    /* Refresh last frame reference buffer using the currently reconstructed frame */
    refreshLastReference(data);

    /* Refresh golden frame reference buffer using the currently reconstructed frame */
    refreshGoldenReference(data);

    /* Refresh alternative frame reference buffer using the currently reconstructed frame */
    refreshAltReference(data);

    /* Update reference frames */
    for (int i = 0; i < VP8_REF_SIZE; i++) {
        VideoSurfaceBuffer *p = mRFBs[1][i].surfaceBuffer;
        int j;
        for (j = 0; j < VP8_REF_SIZE; j++) {
            if (p == mRFBs[0][j].surfaceBuffer) {
                break;
            }
        }
        if (j == VP8_REF_SIZE) {
            clearAsReference(1, i);
        }
    }
}

void VideoDecoderVP8::refreshLastReference(vbp_data_vp8 *data) {
    /* Save previous last reference */
    mRFBs[1][VP8_LAST_REF_PIC].surfaceBuffer = mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer;
    mRFBs[1][VP8_LAST_REF_PIC].index = mRFBs[0][VP8_LAST_REF_PIC].index;

    /* For key frame, this is always true */
    if (data->codec_data->refresh_last_frame) {
        mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer = mAcquiredBuffer;
        mRFBs[0][VP8_LAST_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
        mRFBs[0][VP8_LAST_REF_PIC].surfaceBuffer->asReferernce = true;
    }
}

void VideoDecoderVP8::refreshGoldenReference(vbp_data_vp8 *data) {
    /* Save previous golden reference */
    mRFBs[1][VP8_GOLDEN_REF_PIC].surfaceBuffer = mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer;
    mRFBs[1][VP8_GOLDEN_REF_PIC].index = mRFBs[0][VP8_GOLDEN_REF_PIC].index;

    if (data->codec_data->golden_copied != BufferCopied_NoneToGolden) {
        if (data->codec_data->golden_copied == BufferCopied_LastToGolden) {
            /* LastFrame is copied to GoldenFrame */
            mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer = mRFBs[1][VP8_LAST_REF_PIC].surfaceBuffer;
            mRFBs[0][VP8_GOLDEN_REF_PIC].index = mRFBs[1][VP8_LAST_REF_PIC].index;
        } else if (data->codec_data->golden_copied == BufferCopied_AltRefToGolden) {
            /* AltRefFrame is copied to GoldenFrame */
            mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer = mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer;
            mRFBs[0][VP8_GOLDEN_REF_PIC].index = mRFBs[0][VP8_ALT_REF_PIC].index;
        }
    }

    /* For key frame, this is always true */
    if (data->codec_data->refresh_golden_frame) {
        mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer = mAcquiredBuffer;
        mRFBs[0][VP8_GOLDEN_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
        mRFBs[0][VP8_GOLDEN_REF_PIC].surfaceBuffer->asReferernce = true;
    }
}

void VideoDecoderVP8::refreshAltReference(vbp_data_vp8 *data) {
    /* Save previous alternative reference */
    mRFBs[1][VP8_ALT_REF_PIC].surfaceBuffer = mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer;
    mRFBs[1][VP8_ALT_REF_PIC].index = mRFBs[0][VP8_ALT_REF_PIC].index;

    if (data->codec_data->altref_copied != BufferCopied_NoneToAltRef) {
        if (data->codec_data->altref_copied == BufferCopied_LastToAltRef) {
            /* LastFrame is copied to AltRefFrame */
            mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer = mRFBs[1][VP8_LAST_REF_PIC].surfaceBuffer;
            mRFBs[0][VP8_ALT_REF_PIC].index = mRFBs[1][VP8_LAST_REF_PIC].index;
        } else if (data->codec_data->altref_copied == BufferCopied_GoldenToAltRef) {
            /* GoldenFrame is copied to AltRefFrame */
            mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer = mRFBs[1][VP8_GOLDEN_REF_PIC].surfaceBuffer;
            mRFBs[0][VP8_ALT_REF_PIC].index = mRFBs[1][VP8_GOLDEN_REF_PIC].index;
        }
    }

    /* For key frame, this is always true */
    if (data->codec_data->refresh_alt_frame) {
        mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer = mAcquiredBuffer;
        mRFBs[0][VP8_ALT_REF_PIC].index = mAcquiredBuffer->renderBuffer.surface;
        mRFBs[0][VP8_ALT_REF_PIC].surfaceBuffer->asReferernce = true;
    }
}


Decode_Status VideoDecoderVP8::checkHardwareCapability() {
    VAStatus vaStatus;
    VAConfigAttrib cfgAttribs[2];
    cfgAttribs[0].type = VAConfigAttribMaxPictureWidth;
    cfgAttribs[1].type = VAConfigAttribMaxPictureHeight;
    vaStatus = vaGetConfigAttributes(mVADisplay, VAProfileVP8Version0_3,
            VAEntrypointVLD, cfgAttribs, 2);
    CHECK_VA_STATUS("vaGetConfigAttributes");
    if (cfgAttribs[0].value * cfgAttribs[1].value < (uint32_t)mVideoFormatInfo.width * (uint32_t)mVideoFormatInfo.height) {
        ETRACE("hardware supports resolution %d * %d smaller than the clip resolution %d * %d",
                cfgAttribs[0].value, cfgAttribs[1].value, mVideoFormatInfo.width, mVideoFormatInfo.height);
        return DECODE_DRIVER_FAIL;
    }

    return DECODE_SUCCESS;
}

