/* 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.
*
*/

#include "VideoDecoderAVC.h"
#include "VideoDecoderTrace.h"
#include <string.h>

VideoDecoderAVC::VideoDecoderAVC(const char *mimeType)
    : VideoDecoderBase(mimeType, VBP_H264),
      mToggleDPB(0),
      mErrorConcealment(false){

    invalidateDPB(0);
    invalidateDPB(1);
    mLastPictureFlags = VA_PICTURE_H264_INVALID;
}

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

Decode_Status VideoDecoderAVC::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);
    // output by picture order count
    VideoDecoderBase::setOutputMethod(OUTPUT_BY_POC);

    mErrorConcealment = buffer->flag & WANT_ERROR_CONCEALMENT;
    if (buffer->data == NULL || buffer->size == 0) {
        WTRACE("No config data to start VA.");
        if ((buffer->flag & HAS_SURFACE_NUMBER) && (buffer->flag & HAS_VA_PROFILE)) {
            ITRACE("Used client supplied profile and surface to start VA.");
            return VideoDecoderBase::setupVA(buffer->surfaceNumber, buffer->profile);
        }
        return DECODE_SUCCESS;
    }

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

    status = startVA(data);
    return status;
}

void VideoDecoderAVC::stop(void) {
    // drop the last  frame and ignore return value
    endDecodingFrame(true);
    VideoDecoderBase::stop();
    invalidateDPB(0);
    invalidateDPB(1);
    mToggleDPB = 0;
    mErrorConcealment = false;
    mLastPictureFlags = VA_PICTURE_H264_INVALID;
}

void VideoDecoderAVC::flush(void) {
    // drop the frame and ignore return value
    VideoDecoderBase::flush();
    invalidateDPB(0);
    invalidateDPB(1);
    mToggleDPB = 0;
    mLastPictureFlags = VA_PICTURE_H264_INVALID;
}

Decode_Status VideoDecoderAVC::decode(VideoDecodeBuffer *buffer) {
    Decode_Status status;
    vbp_data_h264 *data = NULL;
    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }
    status =  VideoDecoderBase::parseBuffer(
            buffer->data,
            buffer->size,
            false,
            (void**)&data);
    CHECK_STATUS("VideoDecoderBase::parseBuffer");

    if (!mVAStarted) {
         if (data->has_sps && data->has_pps) {
            status = startVA(data);
            CHECK_STATUS("startVA");
        } else {
            WTRACE("Can't start VA as either SPS or PPS is still not available.");
            return DECODE_SUCCESS;
        }
    }

    status = decodeFrame(buffer, data);
    if (status == DECODE_MULTIPLE_FRAME) {
        buffer->ext = &mExtensionBuffer;
        mExtensionBuffer.extType = PACKED_FRAME_TYPE;
        mExtensionBuffer.extSize = sizeof(mPackedFrame);
        mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
    }
    return status;
}

Decode_Status VideoDecoderAVC::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
    Decode_Status status;
    if (data->has_sps == 0 || data->has_pps == 0) {
        return DECODE_NO_CONFIG;
    }

    // Don't remove the following codes, it can be enabled for debugging DPB.
#if 0
    for (unsigned int i = 0; i < data->num_pictures; i++) {
        VAPictureH264 &pic = data->pic_data[i].pic_parms->CurrPic;
        VTRACE("%d: decoding frame %.2f, poc top = %d, poc bottom = %d, flags = %d,  reference = %d",
                i,
                buffer->timeStamp/1E6,
                pic.TopFieldOrderCnt,
                pic.BottomFieldOrderCnt,
                pic.flags,
                (pic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
                (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
    }
#endif
    if (data->new_sps || data->new_pps) {
        status = handleNewSequence(data);
        CHECK_STATUS("handleNewSequence");
    }

    // first pic_data always exists, check if any slice is parsed
    if (data->pic_data[0].num_slices == 0) {
        ITRACE("No slice available for decoding.");
        status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
        mSizeChanged = false;
        return status;
    }

    uint64_t lastPTS = mCurrentPTS;
    mCurrentPTS = buffer->timeStamp;

    //if (lastPTS != mCurrentPTS) {
    if (isNewFrame(data, lastPTS == mCurrentPTS)) {
        // finish decoding the last frame
        status = endDecodingFrame(false);
        CHECK_STATUS("endDecodingFrame");

        // start decoding a new frame
        status = beginDecodingFrame(data);
        CHECK_STATUS("beginDecodingFrame");
    } else {
        status = continueDecodingFrame(data);
        CHECK_STATUS("continueDecodingFrame");
    }

    // HAS_COMPLETE_FRAME is not reliable as it may indicate end of a field
#if 0
    if (buffer->flag & HAS_COMPLETE_FRAME) {
        // finish decoding current frame
        status = endDecodingFrame(false);
        CHECK_STATUS("endDecodingFrame");
    }
#endif

    if (mSizeChanged) {
        mSizeChanged = false;
        return DECODE_FORMAT_CHANGE;
    }
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderAVC::beginDecodingFrame(vbp_data_h264 *data) {
    Decode_Status status;

    status = acquireSurfaceBuffer();
    CHECK_STATUS("acquireSurfaceBuffer");
    VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
    if ((picture->flags  & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
        (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
        mAcquiredBuffer->referenceFrame = true;
    } else {
        mAcquiredBuffer->referenceFrame = false;
    }
    // set asReference in updateDPB

    if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
        mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
    } else {
        mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
    }

    // TODO: Set the discontinuity flag
    mAcquiredBuffer->renderBuffer.flag = 0;
    mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
    mAcquiredBuffer->pictureOrder = getPOC(picture);

    status  = continueDecodingFrame(data);
    // surface buffer is released if decode fails
    return status;
}


Decode_Status VideoDecoderAVC::continueDecodingFrame(vbp_data_h264 *data) {
    Decode_Status status;
    vbp_picture_data_h264 *picData = data->pic_data;

    // TODO: remove these debugging codes
    if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
        return DECODE_FAIL;
    }
    for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
        // sanity check
        if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
            return DECODE_PARSER_FAIL;
        }

        if (picIndex > 0 &&
            (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
            // it is a packed frame buffer
            vbp_picture_data_h264 *lastPic = &data->pic_data[picIndex - 1];
            vbp_slice_data_h264 *sliceData = &(lastPic->slc_data[lastPic->num_slices - 1]);
            mPackedFrame.offSet = sliceData->slice_size + sliceData->slice_offset;
            mPackedFrame.timestamp = mCurrentPTS; // use the current time stamp for the packed frame
            ITRACE("slice data offset= %d, size = %d", sliceData->slice_offset, sliceData->slice_size);
            return DECODE_MULTIPLE_FRAME;
        }

        for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
            status = decodeSlice(data, picIndex, sliceIndex);
            if (status != DECODE_SUCCESS) {
                endDecodingFrame(true);
                // TODO: this is new code
                // remove current frame from DPB as it can't be decoded.
                removeReferenceFromDPB(picData->pic_parms);
                return status;
            }
        }
    }
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderAVC::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
    Decode_Status status;
    VAStatus vaStatus;
    uint32_t bufferIDCount = 0;
    // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
    VABufferID bufferIDs[4];

    vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
    vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
    VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);

    if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
        // either condition indicates start of a new frame
        if (sliceParam->first_mb_in_slice != 0) {
            WTRACE("The first slice is lost.");
            // TODO: handle the first slice lost
        }
        if (mDecodingFrame) {
            // interlace content, complete decoding the first field
            vaStatus = vaEndPicture(mVADisplay, mVAContext);
            CHECK_VA_STATUS("vaEndPicture");

            // for interlace content, top field may be valid only after the second field is parsed
            int32_t poc = getPOC(&(picParam->CurrPic));
            if (poc < mAcquiredBuffer->pictureOrder) {
                mAcquiredBuffer->pictureOrder = poc;
            }
        }

        // Check there is no reference frame loss before decoding a frame

        // Update  the reference frames and surface IDs for DPB and current frame
        status = updateDPB(picParam);
        CHECK_STATUS("updateDPB");

        //We have to provide a hacked DPB rather than complete DPB for libva as workaround
        status = updateReferenceFrames(picData);
        CHECK_STATUS("updateReferenceFrames");

        vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
        CHECK_VA_STATUS("vaBeginPicture");

        // start decoding a frame
        mDecodingFrame = true;

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

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

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

    vaStatus = vaCreateBuffer(
        mVADisplay,
        mVAContext,
        VASliceParameterBufferType,
        sizeof(VASliceParameterBufferH264),
        1,
        sliceParam,
        &bufferIDs[bufferIDCount]);
    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
    bufferIDCount++;

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

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

    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderAVC::setReference(VASliceParameterBufferH264 *sliceParam) {
    int32_t numList = 1;
    // TODO: set numList to 0 if it is I slice
    if (sliceParam->slice_type == 1 || sliceParam->slice_type == 6) {
        // B slice
        numList = 2;
    }

    int32_t activeMinus1 = sliceParam->num_ref_idx_l0_active_minus1;
    VAPictureH264 *ref = sliceParam->RefPicList0;

    for (int32_t i = 0; i < numList; i++) {
        if (activeMinus1 >= REF_LIST_SIZE) {
            ETRACE("Invalid activeMinus1 (%d)", activeMinus1);
            return DECODE_PARSER_FAIL;
        }
        for (int32_t j = 0; j <= activeMinus1; j++, ref++) {
            if (!(ref->flags & VA_PICTURE_H264_INVALID)) {
                ref->picture_id = findSurface(ref);
                if (ref->picture_id == VA_INVALID_SURFACE) {
                    if (mLastReference) {
                        WTRACE("Reference frame %d is missing. Use last reference", getPOC(ref));
                        ref->picture_id = mLastReference->renderBuffer.surface;
                    } else {
                        ETRACE("Reference frame %d is missing. Stop decoding.", getPOC(ref));
                        return DECODE_NO_REFERENCE;
                    }
                }
            }
        }
        activeMinus1 = sliceParam->num_ref_idx_l1_active_minus1;
        ref = sliceParam->RefPicList1;
    }
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderAVC::updateDPB(VAPictureParameterBufferH264 *picParam) {
    clearAsReference(mToggleDPB);
    // pointer to toggled DPB (new)
    DecodedPictureBuffer *dpb = mDPBs[!mToggleDPB];
    VAPictureH264 *ref = picParam->ReferenceFrames;

    // update current picture ID
    picParam->CurrPic.picture_id = mAcquiredBuffer->renderBuffer.surface;

    // build new DPB
    for (int32_t i = 0; i < MAX_REF_NUMBER; i++, ref++) {
        if (ref->flags & VA_PICTURE_H264_INVALID) {
            continue;
        }
        dpb->poc = getPOC(ref);
        dpb->surfaceBuffer = findSurfaceBuffer(ref);
        if (dpb->surfaceBuffer == NULL) {
            ETRACE("Reference frame %d is missing for current frame %d", dpb->poc, getPOC(&(picParam->CurrPic)));
            if (dpb->poc == getPOC(&(picParam->CurrPic))) {
                WTRACE("updateDPB: Using the current picture for missing reference.");
                dpb->surfaceBuffer = mAcquiredBuffer;
            } else if (mLastReference) {
                WTRACE("updateDPB: Use last reference frame %d for missing reference.", mLastReference->pictureOrder);
                // TODO: this is new code for error resilience
                dpb->surfaceBuffer = mLastReference;
            } else {
                WTRACE("updateDPB: Unable to recover the missing reference frame.");
                // continue buillding DPB without updating dpb pointer.
                continue;
                // continue building DPB as this reference may not be actually used.
                // especially happen after seeking to a non-IDR I frame.
                //return DECODE_NO_REFERENCE;
            }
        }
        if (dpb->surfaceBuffer) {
            // this surface is used as reference
            dpb->surfaceBuffer->asReferernce = true;
        }
        dpb++;
    }

    // add current frame to DPB if it  is a reference frame
    if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
        (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
        dpb->poc = getPOC(&(picParam->CurrPic));
        dpb->surfaceBuffer = mAcquiredBuffer;
        dpb->surfaceBuffer->asReferernce = true;
    }
    // invalidate the current used DPB
    invalidateDPB(mToggleDPB);
    mToggleDPB = !mToggleDPB;
    return DECODE_SUCCESS;
}

Decode_Status VideoDecoderAVC::updateReferenceFrames(vbp_picture_data_h264 *picData) {
    bool found = false;
    uint32_t flags = 0;
    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
    VASliceParameterBufferH264 *sliceParam = NULL;
    uint8_t activeMinus1 = 0;
    VAPictureH264 *refList = NULL;
    VAPictureH264 *dpb = picParam->ReferenceFrames;
    VAPictureH264 *refFrame = NULL;

    // invalidate DPB in the picture buffer
    memset(picParam->ReferenceFrames, 0xFF, sizeof(picParam->ReferenceFrames));
    picParam->num_ref_frames = 0;

    // update DPB  from the reference list in each slice.
    for (uint32_t slice = 0; slice < picData->num_slices; slice++) {
        sliceParam = &(picData->slc_data[slice].slc_parms);
        for (int32_t list = 0; list < 2; list++) {
            refList = (list == 0) ? sliceParam->RefPicList0 :
                                    sliceParam->RefPicList1;
            activeMinus1 = (list == 0) ? sliceParam->num_ref_idx_l0_active_minus1 :
                                         sliceParam->num_ref_idx_l1_active_minus1;
            if (activeMinus1 >= REF_LIST_SIZE) {
                return DECODE_PARSER_FAIL;
            }
            for (uint8_t item = 0; item < (uint8_t)(activeMinus1 + 1); item++, refList++) {
                if (refList->flags & VA_PICTURE_H264_INVALID) {
                    break;
                }
                found = false;
                refFrame = picParam->ReferenceFrames;
                for (uint8_t frame = 0; frame < picParam->num_ref_frames; frame++, refFrame++) {
                    if (refFrame->TopFieldOrderCnt == refList->TopFieldOrderCnt) {
                        ///check for complementary field
                        flags = refFrame->flags | refList->flags;
                        //If both TOP and BOTTOM are set, we'll clear those flags
                        if ((flags & VA_PICTURE_H264_TOP_FIELD) &&
                            (flags & VA_PICTURE_H264_BOTTOM_FIELD)) {
                            refFrame->flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
                        }
                        found = true;  //already in the DPB; will not add this one
                        break;
                    }
                }
                if (found == false) {
                    // add a new reference to the DPB
                    dpb->picture_id = findSurface(refList);
                    if (dpb->picture_id == VA_INVALID_SURFACE) {
                        if (mLastReference != NULL) {
                            dpb->picture_id = mLastReference->renderBuffer.surface;
                        } else {
                            ETRACE("Reference frame %d is missing. Stop updating references frames.", getPOC(refList));
                            return DECODE_NO_REFERENCE;
                        }
                    }
                    dpb->flags = refList->flags;
                    dpb->frame_idx = refList->frame_idx;
                    dpb->TopFieldOrderCnt = refList->TopFieldOrderCnt;
                    dpb->BottomFieldOrderCnt = refList->BottomFieldOrderCnt;
                    dpb++;
                    picParam->num_ref_frames++;
                }
            }
        }
    }
    return DECODE_SUCCESS;
}

void VideoDecoderAVC::removeReferenceFromDPB(VAPictureParameterBufferH264 *picParam) {
    // remove the current frame from DPB as it can't be decoded.
    if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
        (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
        DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
        uint32_t poc = getPOC(&(picParam->CurrPic));
        for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
            if (poc == dpb->poc) {
                dpb->poc = (uint32_t)-1;
                if (dpb->surfaceBuffer) {
                    dpb->surfaceBuffer->asReferernce = false;
                }
                dpb->surfaceBuffer = NULL;
                break;
            }
        }
    }
}

uint32_t VideoDecoderAVC::getPOC(VAPictureH264 *pic) {
    if (pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) {
        return pic->BottomFieldOrderCnt;
    }
    return pic->TopFieldOrderCnt;
}

VASurfaceID VideoDecoderAVC::findSurface(VAPictureH264 *pic) {
    VideoSurfaceBuffer *p = findSurfaceBuffer(pic);
    if (p == NULL) {
        ETRACE("Could not find surface for poc %d", getPOC(pic));
        return VA_INVALID_SURFACE;
    }
    return p->renderBuffer.surface;
}

VideoSurfaceBuffer* VideoDecoderAVC::findSurfaceBuffer(VAPictureH264 *pic) {
    DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
    for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
        if (dpb->poc == pic->BottomFieldOrderCnt ||
            dpb->poc == pic->TopFieldOrderCnt) {
            // TODO: remove these debugging codes
            if (dpb->surfaceBuffer == NULL) {
                ETRACE("Invalid surface buffer in the DPB for poc %d.", getPOC(pic));
            }
            return dpb->surfaceBuffer;
        }
    }
    ETRACE("Unable to find surface for poc %d", getPOC(pic));
    return NULL;
}

void VideoDecoderAVC::invalidateDPB(int toggle) {
    DecodedPictureBuffer* p = mDPBs[toggle];
    for (int i = 0; i < DPB_SIZE; i++) {
        p->poc = (uint32_t) -1;
        p->surfaceBuffer = NULL;
        p++;
    }
}

void VideoDecoderAVC::clearAsReference(int toggle) {
    DecodedPictureBuffer* p = mDPBs[toggle];
    for (int i = 0; i < DPB_SIZE; i++) {
        if (p->surfaceBuffer) {
            p->surfaceBuffer->asReferernce = false;
        }
        p++;
    }
}

Decode_Status VideoDecoderAVC::startVA(vbp_data_h264 *data) {
    int32_t DPBSize = getDPBSize(data);
    updateFormatInfo(data);

    //Use high profile for all kinds of H.264 profiles (baseline, main and high) except for constrained baseline
    VAProfile vaProfile = VAProfileH264High;

    // TODO: determine when to use VAProfileH264ConstrainedBaseline, set only if we are told to do so
    if ((data->codec_data->profile_idc == 66 || data->codec_data->constraint_set0_flag == 1) &&
        data->codec_data->constraint_set1_flag == 1) {
        if (mErrorConcealment) {
            vaProfile = VAProfileH264ConstrainedBaseline;
        }
    }

    VideoDecoderBase::setOutputWindowSize(DPBSize);

   // for 1080p, limit the total surface to 19, according the hardware limitation
   // change the max surface number from 19->10 to workaround memory shortage
   // remove the workaround
    if(mVideoFormatInfo.height == 1088 && DPBSize + AVC_EXTRA_SURFACE_NUMBER > 19) {
        DPBSize = 19 - AVC_EXTRA_SURFACE_NUMBER;
    }

    // for baseline profile, enable low delay mode automatically
    if (data->codec_data->profile_idc == 66) {
        enableLowDelayMode(true);
    }
    return VideoDecoderBase::setupVA(DPBSize + AVC_EXTRA_SURFACE_NUMBER, vaProfile);
}

void VideoDecoderAVC::updateFormatInfo(vbp_data_h264 *data) {
    // new video size
    int width = (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) * 16;
    int height = (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) * 16;
    ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d",
        mVideoFormatInfo.width, mVideoFormatInfo.height, width, height);

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

    if (data->new_sps) {
        mSizeChanged = true;
        ITRACE("New sequence is received. Assuming video size is changed.");
    }

    // video_range has default value of 0.
    mVideoFormatInfo.videoRange = data->codec_data->video_full_range_flag;

    switch (data->codec_data->matrix_coefficients) {
        case 1:
            mVideoFormatInfo.colorMatrix = VA_SRC_BT709;
            break;

        // ITU-R Recommendation BT.470-6 System B, G (MP4), same as
        // SMPTE 170M/BT601
        case 5:
        case 6:
            mVideoFormatInfo.colorMatrix = VA_SRC_BT601;
            break;

        default:
            // unknown color matrix, set to 0 so color space flag will not be set.
            mVideoFormatInfo.colorMatrix = 0;
            break;
    }
    mVideoFormatInfo.aspectX = data->codec_data->sar_width;
    mVideoFormatInfo.aspectY = data->codec_data->sar_height;
    mVideoFormatInfo.bitrate = data->codec_data->bit_rate;
    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);

    mVideoFormatInfo.valid = true;
}

Decode_Status VideoDecoderAVC::handleNewSequence(vbp_data_h264 *data) {
    updateFormatInfo(data);
    if (mSizeChanged == false) {
        return DECODE_SUCCESS;
    } else {
        mSizeChanged = false;
        flushSurfaceBuffers();
        return DECODE_FORMAT_CHANGE;
    }
}

bool VideoDecoderAVC::isNewFrame(vbp_data_h264 *data, bool equalPTS) {
    if (data->num_pictures == 0) {
        ETRACE("num_pictures == 0");
        return true;
    }

    vbp_picture_data_h264* picData = data->pic_data;
    if (picData->num_slices == 0) {
        ETRACE("num_slices == 0");
        return true;
    }

    bool newFrame = false;
    uint32_t fieldFlags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD;

    if (picData->slc_data[0].slc_parms.first_mb_in_slice != 0) {
        // not the first slice, assume it is continuation of a partial frame
        // TODO: check if it is new frame boundary as the first slice may get lost in streaming case.
        WTRACE("first_mb_in_slice != 0");
        if (!equalPTS) {
            // return true if different timestamp, it is a workaround here for a streaming case
            WTRACE("different PTS, treat it as a new frame");
            return true;
        }
    } else {
        if ((picData->pic_parms->CurrPic.flags & fieldFlags) == fieldFlags) {
            ETRACE("Current picture has both odd field and even field.");
        }
        // current picture is a field or a frame, and buffer conains the first slice, check if the current picture and
        // the last picture form an opposite field pair
        if (((mLastPictureFlags | picData->pic_parms->CurrPic.flags) & fieldFlags) == fieldFlags) {
            // opposite field
            newFrame = false;
            WTRACE("current picture is not at frame boundary.");
            mLastPictureFlags = 0;
        } else {
            newFrame = true;
            mLastPictureFlags = 0;
            for (uint32_t i = 0; i < data->num_pictures; i++) {
                mLastPictureFlags |= data->pic_data[i].pic_parms->CurrPic.flags;
            }
            if ((mLastPictureFlags & fieldFlags) == fieldFlags) {
                // current buffer contains both odd field and even field.
                mLastPictureFlags = 0;
            }
        }
    }
    
    return newFrame;
}

int32_t VideoDecoderAVC::getDPBSize(vbp_data_h264 *data) {
    // 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16
    struct DPBTable {
        int32_t level;
        float maxDPB;
    } dpbTable[] = {
        {9,  148.5},
        {10, 148.5},
        {11, 337.5},
        {12, 891.0},
        {13, 891.0},
        {20, 891.0},
        {21, 1782.0},
        {22, 3037.5},
        {30, 3037.5},
        {31, 6750.0},
        {32, 7680.0},
        {40, 12288.0},
        {41, 12288.0},
        {42, 13056.0},
        {50, 41400.0},
        {51, 69120.0}
    };

    int32_t count = sizeof(dpbTable)/sizeof(DPBTable);
    float maxDPB = 0;
    for (int32_t i = 0; i < count; i++)
    {
        if (dpbTable[i].level == data->codec_data->level_idc) {
            maxDPB = dpbTable[i].maxDPB;
            break;
        }
    }

    int32_t maxDPBSize = maxDPB * 1024 / (
        (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) *
        (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) *
        384);

    if (maxDPBSize > 16) {
        maxDPBSize = 16;
    } else if (maxDPBSize == 0) {
        maxDPBSize = 3;
    }
    if(maxDPBSize < data->codec_data->num_ref_frames) {
        maxDPBSize = data->codec_data->num_ref_frames;
    }

    // add one extra frame for current frame.
    maxDPBSize += 1;
    ITRACE("maxDPBSize = %d, num_ref_frame = %d", maxDPBSize, data->codec_data->num_ref_frames);
    return maxDPBSize;
}

