182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON/*
282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Licensed under the Apache License, Version 2.0 (the "License");
582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* you may not use this file except in compliance with the License.
682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* You may obtain a copy of the License at
782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* http://www.apache.org/licenses/LICENSE-2.0
982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*
1082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* Unless required by applicable law or agreed to in writing, software
1182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* distributed under the License is distributed on an "AS IS" BASIS,
1282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* See the License for the specific language governing permissions and
1482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON* limitations under the License.
1582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON*/
1682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
1782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderMPEG4.h"
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderTrace.h"
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <string.h>
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderMPEG4::VideoDecoderMPEG4(const char *mimeType)
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    : VideoDecoderBase(mimeType, VBP_MPEG4),
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mLastVOPTimeIncrement(0),
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mExpectingNVOP(false),
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mSendIQMatrixBuf(false),
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mLastVOPCodingType(MP4_VOP_TYPE_I),
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mIsShortHeader(false) {
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderMPEG4::~VideoDecoderMPEG4() {
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    stop();
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::start(VideoConfigBuffer *buffer) {
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = VideoDecoderBase::start(buffer);
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::start");
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->data == NULL || buffer->size == 0) {
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("No config data to start VA.");
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_data_mp42 *data = NULL;
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = VideoDecoderBase::parseBuffer(buffer->data, buffer->size, true, (void**)&data);
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::parseBuffer");
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = startVA(data);
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderMPEG4::stop(void) {
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // drop the last frame and ignore return value
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::stop();
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastVOPTimeIncrement = 0;
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mExpectingNVOP = false;
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastVOPCodingType = MP4_VOP_TYPE_I;
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::decode(VideoDecodeBuffer *buffer) {
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_data_mp42 *data = NULL;
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicbuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & IS_SYNC_FRAME) {
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mIsSyncFrame = true;
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mIsSyncFrame = false;
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    buffer->ext = NULL;
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status =  VideoDecoderBase::parseBuffer(
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->data,
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->size,
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            false,
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (void**)&data);
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::parseBuffer");
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mVAStarted) {
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = startVA(data);
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("startVA");
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSizeChanged && !useGraphicbuffer) {
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // some container has the incorrect width/height.
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // send the format change to OMX to update the crop info.
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = false;
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Video size is changed during startVA");
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FORMAT_CHANGE;
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((mVideoFormatInfo.width != (uint32_t)data->codec_data.video_object_layer_width ||
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height != (uint32_t)data->codec_data.video_object_layer_height) &&
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_width &&
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_height) {
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // update  encoded image size
1011175ce579a69e847027026f615a053af76b792d5Tianmi Chen        ITRACE("Video size is changed. from %dx%d to %dx%d\n", mVideoFormatInfo.width, mVideoFormatInfo.height,
1021175ce579a69e847027026f615a053af76b792d5Tianmi Chen        data->codec_data.video_object_layer_width,data->codec_data.video_object_layer_height);
1031175ce579a69e847027026f615a053af76b792d5Tianmi Chen
1041175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (useGraphicbuffer && mStoreMetaData) {
1051175ce579a69e847027026f615a053af76b792d5Tianmi Chen            pthread_mutex_lock(&mFormatLock);
1061175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.width = data->codec_data.video_object_layer_width;
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height = data->codec_data.video_object_layer_height;
1091175ce579a69e847027026f615a053af76b792d5Tianmi Chen        bool needFlush = false;
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (useGraphicbuffer) {
1111175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mStoreMetaData) {
1121175ce579a69e847027026f615a053af76b792d5Tianmi Chen                needFlush = true;
1131175ce579a69e847027026f615a053af76b792d5Tianmi Chen
1141175ce579a69e847027026f615a053af76b792d5Tianmi Chen                mVideoFormatInfo.valid = false;
1151175ce579a69e847027026f615a053af76b792d5Tianmi Chen                pthread_mutex_unlock(&mFormatLock);
1161175ce579a69e847027026f615a053af76b792d5Tianmi Chen            } else {
1171175ce579a69e847027026f615a053af76b792d5Tianmi Chen                needFlush = (mVideoFormatInfo.width > mVideoFormatInfo.surfaceWidth)
1181175ce579a69e847027026f615a053af76b792d5Tianmi Chen                         || (mVideoFormatInfo.height > mVideoFormatInfo.surfaceHeight);
1191175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
1211175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (needFlush) {
1221175ce579a69e847027026f615a053af76b792d5Tianmi Chen            if (mStoreMetaData) {
1231175ce579a69e847027026f615a053af76b792d5Tianmi Chen                status = endDecodingFrame(false);
1241175ce579a69e847027026f615a053af76b792d5Tianmi Chen                CHECK_STATUS("endDecodingFrame");
1251175ce579a69e847027026f615a053af76b792d5Tianmi Chen            } else {
1261175ce579a69e847027026f615a053af76b792d5Tianmi Chen                flushSurfaceBuffers();
1271175ce579a69e847027026f615a053af76b792d5Tianmi Chen            }
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSizeChanged = false;
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FORMAT_CHANGE;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSizeChanged = true;
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        setRenderRect();
1351175ce579a69e847027026f615a053af76b792d5Tianmi Chen    } else {
1361175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (useGraphicbuffer && mStoreMetaData) {
1371175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVideoFormatInfo.valid = true;
1381175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = decodeFrame(buffer, data);
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("decodeFrame");
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderMPEG4::flush(void) {
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::flush();
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mExpectingNVOP = false;
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastVOPTimeIncrement = 0;
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastVOPCodingType = MP4_VOP_TYPE_I;
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_mp42 *data) {
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // check if any slice is parsed, we may just receive configuration data
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data->number_picture_data == 0) {
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("number_picture_data == 0");
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
1629892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    if (data->picture_data && (data->picture_data->picture_param.vop_width == 0 || data->picture_data->picture_param.vop_height == 0)) {
1639892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        if (!data->codec_data.got_vol && data->codec_data.got_vop) {
1649892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding            // error enhancement if vol is missing
1659892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding            data->picture_data->picture_param.vop_width = mVideoFormatInfo.width;
1669892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding            data->picture_data->picture_param.vop_height = mVideoFormatInfo.height;
1679892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        } else {
1689892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding            return DECODE_PARSER_FAIL;
1699892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        }
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint64_t lastPTS = mCurrentPTS;
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = buffer->timeStamp;
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (lastPTS != mCurrentPTS) {
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // finish decoding the last frame
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = endDecodingFrame(false);
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("endDecodingFrame");
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // start decoding a new frame
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = beginDecodingFrame(data);
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (status == DECODE_MULTIPLE_FRAME) {
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->ext = &mExtensionBuffer;
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extType = PACKED_FRAME_TYPE;
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extSize = sizeof(mPackedFrame);
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else if (status != DECODE_SUCCESS) {
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            endDecodingFrame(true);
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("beginDecodingFrame");
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = continueDecodingFrame(data);
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (status == DECODE_MULTIPLE_FRAME) {
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->ext = &mExtensionBuffer;
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extType = PACKED_FRAME_TYPE;
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extSize = sizeof(mPackedFrame);
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else if (status != DECODE_SUCCESS) {
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            endDecodingFrame(true);
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("continueDecodingFrame");
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & HAS_COMPLETE_FRAME) {
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // finish decoding current frame
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = endDecodingFrame(false);
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("endDecodingFrame");
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::beginDecodingFrame(vbp_data_mp42 *data) {
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status = DECODE_SUCCESS;
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_mp42 *picData = data->picture_data;
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureParameterBufferMPEG4 *picParam = &(picData->picture_param);
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int codingType = picParam->vop_fields.bits.vop_coding_type;
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // start sanity checking
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mExpectingNVOP) {
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // if we are waiting for n-vop for packed frame, and the new frame is coded, the coding type
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // of this frame must be B
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // for example: {PB} B N P B B P...
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (picData->vop_coded == 1 && codingType != MP4_VOP_TYPE_B) {
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Invalid coding type while waiting for n-vop for packed frame.");
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExpectingNVOP = false;
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // handle N-VOP picuture, it could be a skipped frame or a simple placeholder of packed frame
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (picData->vop_coded == 0) {
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mLastReference == NULL) {
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("The last reference is unavailable to construct skipped frame.");
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            flush();
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExpectingNVOP = false;
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: handle this case
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_SUCCESS;
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mExpectingNVOP) {
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // P frame is already in queue, just need to update time stamp.
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mLastReference->renderBuffer.timeStamp = mCurrentPTS;
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mExpectingNVOP = false;
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        else {
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Do nothing for skip frame as the last frame will be rendered agian by natively
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // No needs to handle reference frame neither
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if 0
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this is skipped frame, use the last reference frame as output
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = acquireSurfaceBuffer();
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("acquireSurfaceBuffer");
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.flag = 0;
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.scanFormat = mLastReference->renderBuffer.scanFormat;
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.surface = mLastReference->renderBuffer.surface;
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // No need to update mappedData for HW decoding
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            //mAcquiredBuffer->mappedData.data = mLastReference->mappedData.data;
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->referenceFrame = true;
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = outputSurfaceBuffer();
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("outputSurfaceBuffer");
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (data->number_picture_data > 1) {
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Unexpected to have more picture data following a non-coded VOP.");
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            //picture data is thrown away. No issue if picture data is for N-VOP. if picture data is for
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // coded picture, a frame is lost.
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: handle this case
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // return DECODE_FAIL;
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    else {
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Check if we have reference frame(s)  for decoding
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (codingType == MP4_VOP_TYPE_B)  {
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mForwardReference ==  NULL ||
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mLastReference == NULL) {
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mIsShortHeader) {
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    status = DECODE_SUCCESS;
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    VTRACE("%s: No reference frame but keep decoding", __FUNCTION__);
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    return DECODE_NO_REFERENCE;
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else if (codingType == MP4_VOP_TYPE_P || codingType == MP4_VOP_TYPE_S) {
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mLastReference == NULL && mIsSyncFrame == false) {
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mIsShortHeader) {
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    status = DECODE_SUCCESS;
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    VTRACE("%s: No reference frame but keep decoding", __FUNCTION__);
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    return DECODE_NO_REFERENCE;
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // all sanity checks pass, continue decoding through continueDecodingFrame
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = continueDecodingFrame(data);
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::continueDecodingFrame(vbp_data_mp42 *data) {
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status = DECODE_SUCCESS;
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus = VA_STATUS_SUCCESS;
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool useGraphicBuffer = mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER;
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    /*
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         Packed Frame Assumption:
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         1. In one packed frame, there's only one P or I frame and only one B frame.
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         2. In packed frame, there's no skipped frame (vop_coded = 0)
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         3. For one packed frame, there will be one N-VOP frame to follow the packed frame (may not immediately).
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         4. N-VOP frame is the frame with vop_coded = 0.
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         5. The timestamp of  N-VOP frame will be used for P or I frame in the packed frame
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         I, P, {P, B}, B, N, P, N, I, ...
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         I, P, {P, B}, N, P, N, I, ...
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         The first N is placeholder for P frame in the packed frame
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         The second N is a skipped frame
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         */
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_mp42 *picData = data->picture_data;
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (uint32_t i = 0; i < data->number_picture_data; i++, picData = picData->next_picture_data) {
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // each slice has its own picture data, video_packet_header following resync_marker may reset picture header, see MP4 spec
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VAPictureParameterBufferMPEG4 *picParam = &(picData->picture_param);
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int codingType = picParam->vop_fields.bits.vop_coding_type;
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (codingType == MP4_VOP_TYPE_S && picParam->no_of_sprite_warping_points > 1) {
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Hardware only supports up to one warping point (stationary or translation)");
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (picData->vop_coded == 0) {
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Unexpected to have non-coded VOP.");
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_FAIL;
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (picData->new_picture_flag == 1 || mDecodingFrame == false) {
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // either condition indicates start of a new frame
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (picData->new_picture_flag == 0) {
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                WTRACE("First slice of picture is lost!");
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // TODO: handle this case
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mDecodingFrame) {
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (codingType == MP4_VOP_TYPE_B){
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // this indicates the start of a new frame in the packed frame
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // Update timestamp for P frame in the packed frame as timestamp here is for the B frame!
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (picParam->vop_time_increment_resolution){
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        uint64_t increment = mLastVOPTimeIncrement - picData->vop_time_increment +
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                picParam->vop_time_increment_resolution;
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        increment = increment % picParam->vop_time_increment_resolution;
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        // convert to micro-second
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        // TODO: unit of time stamp varies on different frame work
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        increment = increment * 1e6 / picParam->vop_time_increment_resolution;
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        mAcquiredBuffer->renderBuffer.timeStamp += increment;
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        if (useGraphicBuffer){
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                           mPackedFrame.timestamp = mCurrentPTS;
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                           mCurrentPTS = mAcquiredBuffer->renderBuffer.timeStamp;
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else {
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // this indicates the start of a new frame in the packed frame. no B frame int the packet
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // Update the timestamp according the increment
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (picParam->vop_time_increment_resolution){
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        int64_t increment = picData->vop_time_increment - mLastVOPTimeIncrement + picParam->vop_time_increment_resolution;
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        increment = increment % picParam->vop_time_increment_resolution;
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        //convert to micro-second
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        increment = increment * 1e6 / picParam->vop_time_increment_resolution;
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        if (useGraphicBuffer) {
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            mPackedFrame.timestamp = mCurrentPTS + increment;
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        else {
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            mCurrentPTS += increment;
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    } else {
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        if (useGraphicBuffer) {
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            mPackedFrame.timestamp = mCurrentPTS + 30000;
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        else {
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            mCurrentPTS += 30000;
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                endDecodingFrame(false);
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mExpectingNVOP = true;
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (codingType != MP4_VOP_TYPE_B) {
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    mExpectingNVOP = false;
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (useGraphicBuffer) {
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    int32_t count = i - 1;
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (count < 0) {
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        WTRACE("Shuld not be here!");
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        return DECODE_SUCCESS;
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    vbp_picture_data_mp42 *lastpic = data->picture_data;
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    for(int k = 0; k < count; k++ ) {
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        lastpic = lastpic->next_picture_data;
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    mPackedFrame.offSet = lastpic->slice_data.slice_offset + lastpic->slice_data.slice_size;
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    VTRACE("Report OMX to handle for Multiple frame offset=%d time=%lld",mPackedFrame.offSet,mPackedFrame.timestamp);
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    return DECODE_MULTIPLE_FRAME;
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // acquire a new surface buffer
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = acquireSurfaceBuffer();
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("acquireSurfaceBuffer");
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // sprite is treated as P frame in the display order, so only B frame frame is not used as "reference"
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->referenceFrame = (codingType != MP4_VOP_TYPE_B);
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (picData->picture_param.vol_fields.bits.interlaced) {
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // only MPEG-4 studio profile can have field coding. All other profiles
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // use frame coding only, i.e, there is no field VOP.  (see vop_structure in MP4 spec)
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO:  set discontinuity flag
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.flag = 0;
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mSizeChanged) {
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mSizeChanged = false;
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (codingType != MP4_VOP_TYPE_B) {
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mLastVOPCodingType = codingType;
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mLastVOPTimeIncrement = picData->vop_time_increment;
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // start decoding a frame
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_VA_STATUS("vaBeginPicture");
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mDecodingFrame = true;
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSendIQMatrixBuf = true;
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = decodeSlice(data, picData);
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("decodeSlice");
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::decodeSlice(vbp_data_mp42 *data, vbp_picture_data_mp42 *picData) {
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t bufferIDCount = 0;
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VABufferID bufferIDs[4];
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureParameterBufferMPEG4 *picParam = &(picData->picture_param);
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_slice_data_mp42 *sliceData = &(picData->slice_data);
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASliceParameterBufferMPEG4 *sliceParam = &(sliceData->slice_param);
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // send picture parametre for each slice
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = setReference(picParam);
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("setReference");
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VAPictureParameterBufferType,
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sizeof(VAPictureParameterBufferMPEG4),
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        picParam,
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (picParam->vol_fields.bits.quant_type && mSendIQMatrixBuf)
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    {
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // only send IQ matrix for the first slice in the picture
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAIQMatrixBufferType,
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeof(VAIQMatrixBufferMPEG4),
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &(data->iq_matrix_buffer),
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSendIQMatrixBuf = false;
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceParameterBufferType,
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sizeof(VASliceParameterBufferMPEG4),
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceParam,
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //slice data buffer pointer
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //Note that this is the original data buffer ptr;
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // offset to the actual slice data is provided in
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // slice_data_offset in VASliceParameterBufferMP42
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceDataBufferType,
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceData->slice_size, //size
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,        //num_elements
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceData->buffer_addr + sliceData->slice_offset,
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSliceDataBuffer");
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
51582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaRenderPicture(
51782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
51882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
51982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDs,
52082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount);
52182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaRenderPicture");
52282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
52382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
52482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
52582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
52682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
52782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::setReference(VAPictureParameterBufferMPEG4 *picParam) {
52882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (picParam->vop_fields.bits.vop_coding_type) {
52982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case MP4_VOP_TYPE_I:
53082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->forward_reference_picture = VA_INVALID_SURFACE;
53182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->backward_reference_picture = VA_INVALID_SURFACE;
53282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
53382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case MP4_VOP_TYPE_P:
53482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mLastReference == NULL && mIsSyncFrame == false && !mIsShortHeader) {
53582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_NO_REFERENCE;
53682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
53782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mLastReference != NULL) {
53882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
53982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
54082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                VTRACE("%s: no reference frame, but keep decoding", __FUNCTION__);
54182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                picParam->forward_reference_picture = VA_INVALID_SURFACE;
54282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
54382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->backward_reference_picture = VA_INVALID_SURFACE;
54482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
54582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case MP4_VOP_TYPE_B:
54682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->vop_fields.bits.backward_reference_vop_coding_type = mLastVOPCodingType;
54782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // WEIRD, CHECK AGAIN !!!!!!!
54882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mIsShortHeader) {
54982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mLastReference != NULL) {
55082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
55182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else {
55282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    VTRACE("%s: no forward reference frame, but keep decoding", __FUNCTION__);
55382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    picParam->forward_reference_picture = VA_INVALID_SURFACE;
55482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
55582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (mForwardReference != NULL) {
55682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    picParam->backward_reference_picture = mForwardReference->renderBuffer.surface;
55782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                } else {
55882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    VTRACE("%s: no backward reference frame, but keep decoding", __FUNCTION__);
55982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    picParam->backward_reference_picture = VA_INVALID_SURFACE;
56082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
56182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else if (mLastReference == NULL || mForwardReference == NULL) {
56282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_NO_REFERENCE;
56382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
56482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
56582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                picParam->backward_reference_picture = mForwardReference->renderBuffer.surface;
56682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
56782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
56882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case MP4_VOP_TYPE_S:
56982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // WEIRD, CHECK AGAIN!!!! WAS using mForwardReference
57082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (mLastReference == NULL) {
57182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_NO_REFERENCE;
57282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
57382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->forward_reference_picture = mLastReference->renderBuffer.surface;
57482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam->backward_reference_picture = VA_INVALID_SURFACE;
57582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
57682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
57782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default:
57882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Will never reach here;
57982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_PARSER_FAIL;
58082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
58182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
58282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
58382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::startVA(vbp_data_mp42 *data) {
58582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    updateFormatInfo(data);
58682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAProfile vaProfile;
58882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
58982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((data->codec_data.profile_and_level_indication & 0xF8) == 0xF0) {
59082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaProfile = VAProfileMPEG4AdvancedSimple;
59182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
59282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaProfile = VAProfileMPEG4Simple;
59382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
59482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mIsShortHeader = data->codec_data.short_video_header;
59682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return VideoDecoderBase::setupVA(MP4_SURFACE_NUMBER, vaProfile);
59882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
59982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderMPEG4::updateFormatInfo(vbp_data_mp42 *data) {
60182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d",
60282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.width, mVideoFormatInfo.height,
60382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_width,
60482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_height);
6059892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    // error enhancement if vol is missing
6069892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    if (!data->codec_data.got_vol && data->codec_data.got_vop) {
6079892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        data->codec_data.video_object_layer_width = mVideoFormatInfo.width;
6089892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding        data->codec_data.video_object_layer_height = mVideoFormatInfo.height;
6099892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    }
61082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
61182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropBottom = data->codec_data.video_object_layer_height > mVideoFormatInfo.height ?
61282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                                                          data->codec_data.video_object_layer_height - mVideoFormatInfo.height : 0;
61382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropRight = data->codec_data.video_object_layer_width > mVideoFormatInfo.width ?
61482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                                                     data->codec_data.video_object_layer_width - mVideoFormatInfo.width : 0;
61582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
61682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((mVideoFormatInfo.width != (uint32_t)data->codec_data.video_object_layer_width ||
61782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height != (uint32_t)data->codec_data.video_object_layer_height) &&
61882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_width &&
61982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data.video_object_layer_height) {
62082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // update  encoded image size
62182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.width = data->codec_data.video_object_layer_width;
62282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height = data->codec_data.video_object_layer_height;
62382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = true;
62482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("Video size is changed.");
62582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
62682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // video_range has default value of 0. Y ranges from 16 to 235.
62882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.videoRange = data->codec_data.video_range;
62982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (data->codec_data.matrix_coefficients) {
63182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 1:
63282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = VA_SRC_BT709;
63382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
63482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
63582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // ITU-R Recommendation BT.470-6 System B, G (MP4), same as
63682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // SMPTE 170M/BT601
63782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 5:
63882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 6:
63982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = VA_SRC_BT601;
64082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
64182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default:
64382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // unknown color matrix, set to 0 so color space flag will not be set.
64482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = 0;
64582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
64682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
64782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.aspectX = data->codec_data.par_width;
64982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.aspectY = data->codec_data.par_height;
65082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //mVideoFormatInfo.bitrate = data->codec_data.bit_rate;
65182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.valid = true;
65282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRenderRect();
6549892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);
65582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
65682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderMPEG4::checkHardwareCapability() {
65882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
65982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib cfgAttribs[2];
66082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    cfgAttribs[0].type = VAConfigAttribMaxPictureWidth;
66182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    cfgAttribs[1].type = VAConfigAttribMaxPictureHeight;
66282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaGetConfigAttributes(mVADisplay,
66382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mIsShortHeader ? VAProfileH263Baseline : VAProfileMPEG4AdvancedSimple,
66482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD, cfgAttribs, 2);
66582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaGetConfigAttributes");
66682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (cfgAttribs[0].value * cfgAttribs[1].value < (uint32_t)mVideoFormatInfo.width * (uint32_t)mVideoFormatInfo.height) {
66782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("hardware supports resolution %d * %d smaller than the clip resolution %d * %d",
66882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                cfgAttribs[0].value, cfgAttribs[1].value, mVideoFormatInfo.width, mVideoFormatInfo.height);
66982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_DRIVER_FAIL;
67082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
67182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
67382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
674