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 "VideoDecoderAVC.h"
1882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include "VideoDecoderTrace.h"
1982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <string.h>
2082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#include <cutils/properties.h>
2182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON// Macros for actual buffer needed calculation
2382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define WIDI_CONSUMED   6
2482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define HDMI_CONSUMED   2
2582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define NW_CONSUMED     2
2682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#define POC_DEFAULT     0x7FFFFFFF
2782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
2882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVC::VideoDecoderAVC(const char *mimeType)
2982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    : VideoDecoderBase(mimeType, VBP_H264),
3082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mToggleDPB(0),
3182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON      mErrorConcealment(false){
3282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(0);
3482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(1);
3582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastPictureFlags = VA_PICTURE_H264_INVALID;
3682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
3782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
3882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoDecoderAVC::~VideoDecoderAVC() {
3982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    stop();
4082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
4182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::start(VideoConfigBuffer *buffer) {
4382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
4482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = VideoDecoderBase::start(buffer);
4682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::start");
4782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
4882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // We don't want base class to manage reference.
4982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::ManageReference(false);
5082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // output by picture order count
5182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::setOutputMethod(OUTPUT_BY_POC);
5282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mErrorConcealment = buffer->flag & WANT_ERROR_CONCEALMENT;
5482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->data == NULL || buffer->size == 0) {
5582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("No config data to start VA.");
5682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((buffer->flag & HAS_SURFACE_NUMBER) && (buffer->flag & HAS_VA_PROFILE)) {
5782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ITRACE("Used client supplied profile and surface to start VA.");
5882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return VideoDecoderBase::setupVA(buffer->surfaceNumber, buffer->profile);
5982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
6082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
6182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
6282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_data_h264 *data = NULL;
6482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = VideoDecoderBase::parseBuffer(buffer->data, buffer->size, true, (void**)&data);
6582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::parseBuffer");
6682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
6782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = startVA(data);
6882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
6982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
7082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::stop(void) {
7282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // drop the last  frame and ignore return value
7382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    endDecodingFrame(true);
7482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::stop();
7582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(0);
7682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(1);
7782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mToggleDPB = 0;
7882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mErrorConcealment = false;
7982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastPictureFlags = VA_PICTURE_H264_INVALID;
8082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
8182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::flush(void) {
8382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // drop the frame and ignore return value
8482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::flush();
8582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(0);
8682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(1);
8782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mToggleDPB = 0;
8882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mLastPictureFlags = VA_PICTURE_H264_INVALID;
8982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
9082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
9182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::decode(VideoDecodeBuffer *buffer) {
9282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
9382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_data_h264 *data = NULL;
9482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer == NULL) {
9582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_INVALID_DATA;
9682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
9782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status =  VideoDecoderBase::parseBuffer(
9882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->data,
9982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            buffer->size,
10082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            false,
10182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (void**)&data);
10282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("VideoDecoderBase::parseBuffer");
10382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
10482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!mVAStarted) {
10582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON         if (data->has_sps && data->has_pps) {
10682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = startVA(data);
10782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("startVA");
10882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
10982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("Can't start VA as either SPS or PPS is still not available.");
11082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_SUCCESS;
11182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
11282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
11382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::setRotationDegrees(buffer->rotationDegrees);
11582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
11682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = decodeFrame(buffer, data);
11782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (status == DECODE_MULTIPLE_FRAME) {
11882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        buffer->ext = &mExtensionBuffer;
11982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mExtensionBuffer.extType = PACKED_FRAME_TYPE;
12082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mExtensionBuffer.extSize = sizeof(mPackedFrame);
12182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mExtensionBuffer.extData = (uint8_t*)&mPackedFrame;
12282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
12382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
12482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
12582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
12682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::decodeFrame(VideoDecodeBuffer *buffer, vbp_data_h264 *data) {
12782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
12882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data->has_sps == 0 || data->has_pps == 0) {
12982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_NO_CONFIG;
13082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
13182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
13282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.flags = 0;
13382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t fieldFlags = 0;
13482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (unsigned int i = 0; i < data->num_pictures; i++) {
13582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VAPictureH264 &pic = data->pic_data[i].pic_parms->CurrPic;
13682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        fieldFlags |= pic.flags;
13782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Don't remove the following codes, it can be enabled for debugging DPB.
13882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if 0
13982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VTRACE("%d: decoding frame %.2f, poc top = %d, poc bottom = %d, flags = %d,  reference = %d",
14082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                i,
14182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                buffer->timeStamp/1E6,
14282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pic.TopFieldOrderCnt,
14382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pic.BottomFieldOrderCnt,
14482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                pic.flags,
14582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (pic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
14682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                (pic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE));
14782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
14882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
14982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t topField = fieldFlags & VA_PICTURE_H264_TOP_FIELD;
15082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t botField = fieldFlags & VA_PICTURE_H264_BOTTOM_FIELD;
15182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((topField == 0 && botField != 0) || (topField != 0 && botField == 0)) {
15282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.flags |= IS_SINGLE_FIELD;
15382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
15482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
15582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data->new_sps || data->new_pps) {
15682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = handleNewSequence(data);
15782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("handleNewSequence");
15882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
15982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (isWiDiStatusChanged()) {
16182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = false;
16282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        flushSurfaceBuffers();
16382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FORMAT_CHANGE;
16482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
16582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
16682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // first pic_data always exists, check if any slice is parsed
16782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data->pic_data[0].num_slices == 0) {
16882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("No slice available for decoding.");
16982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = mSizeChanged ? DECODE_FORMAT_CHANGE : DECODE_SUCCESS;
17082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = false;
17182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return status;
17282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
17382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
17482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint64_t lastPTS = mCurrentPTS;
17582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mCurrentPTS = buffer->timeStamp;
17682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //if (lastPTS != mCurrentPTS) {
17782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (isNewFrame(data, lastPTS == mCurrentPTS)) {
17882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mLowDelay) {
17982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // start decoding a new frame
18082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = beginDecodingFrame(data);
18182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (status != DECODE_SUCCESS) {
18282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                Decode_Status st = status;
18382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // finish decoding the last frame if
18482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // encounter error when decode the new frame
18582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                status = endDecodingFrame(false);
18682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                CHECK_STATUS("endDecodingFrame");
18782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return st;
18882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
18982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
19082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // finish decoding the last frame
19282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = endDecodingFrame(false);
19382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("endDecodingFrame");
19482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
19582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (!mLowDelay) {
19682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // start decoding a new frame
19782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = beginDecodingFrame(data);
19882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_STATUS("beginDecodingFrame");
19982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
20082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
20182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = continueDecodingFrame(data);
20282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("continueDecodingFrame");
20382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
20482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
20582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // HAS_COMPLETE_FRAME is not reliable as it may indicate end of a field
20682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#if 0
20782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (buffer->flag & HAS_COMPLETE_FRAME) {
20882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // finish decoding current frame
20982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = endDecodingFrame(false);
21082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("endDecodingFrame");
21182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
21282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
21382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
21482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
21582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::beginDecodingFrame(vbp_data_h264 *data) {
21782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
21882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
21982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = acquireSurfaceBuffer();
22082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("acquireSurfaceBuffer");
22182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *picture = &(data->pic_data[0].pic_parms->CurrPic);
22282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((picture->flags  & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
22382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (picture->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
22482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->referenceFrame = true;
22582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
22682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->referenceFrame = false;
22782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
22882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // set asReference in updateDPB
22982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (picture->flags & VA_PICTURE_H264_TOP_FIELD) {
23182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.scanFormat = VA_BOTTOM_FIELD | VA_TOP_FIELD;
23282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
23382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.scanFormat = VA_FRAME_PICTURE;
23482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
23582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
23682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: Set the discontinuity flag
23782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.flag = 0;
23882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->renderBuffer.timeStamp = mCurrentPTS;
23982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mAcquiredBuffer->pictureOrder = getPOC(picture);
24082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mSizeChanged) {
24282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mAcquiredBuffer->renderBuffer.flag |= IS_RESOLUTION_CHANGE;
24382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = false;
24482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
24582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
24682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status  = continueDecodingFrame(data);
24782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // surface buffer is released if decode fails
24882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return status;
24982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
25082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::continueDecodingFrame(vbp_data_h264 *data) {
25382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
25482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_h264 *picData = data->pic_data;
25582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
25682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: remove these debugging codes
25782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mAcquiredBuffer == NULL || mAcquiredBuffer->renderBuffer.surface == VA_INVALID_SURFACE) {
25882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("mAcquiredBuffer is NULL. Implementation bug.");
25982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
26082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
26182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (uint32_t picIndex = 0; picIndex < data->num_pictures; picIndex++, picData++) {
26282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // sanity check
26382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (picData == NULL || picData->pic_parms == NULL || picData->slc_data == NULL || picData->num_slices == 0) {
26482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_PARSER_FAIL;
26582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
26682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
26782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (picIndex > 0 &&
26882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            (picData->pic_parms->CurrPic.flags & (VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD)) == 0) {
26982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // it is a packed frame buffer
27082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vbp_picture_data_h264 *lastPic = &data->pic_data[picIndex - 1];
27182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vbp_slice_data_h264 *sliceData = &(lastPic->slc_data[lastPic->num_slices - 1]);
27282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mPackedFrame.offSet = sliceData->slice_size + sliceData->slice_offset;
27382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mPackedFrame.timestamp = mCurrentPTS; // use the current time stamp for the packed frame
27482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ITRACE("slice data offset= %d, size = %d", sliceData->slice_offset, sliceData->slice_size);
27582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_MULTIPLE_FRAME;
27682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
27782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
27882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (uint32_t sliceIndex = 0; sliceIndex < picData->num_slices; sliceIndex++) {
27982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            status = decodeSlice(data, picIndex, sliceIndex);
28082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (status != DECODE_SUCCESS) {
28182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                endDecodingFrame(true);
28282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // TODO: this is new code
28382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // remove current frame from DPB as it can't be decoded.
28482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                removeReferenceFromDPB(picData->pic_parms);
28582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return status;
28682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
28782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
28882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
28982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
29082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
29182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::decodeSlice(vbp_data_h264 *data, uint32_t picIndex, uint32_t sliceIndex) {
29382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    Decode_Status status;
29482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
29582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t bufferIDCount = 0;
29682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // maximum 4 buffers to render a slice: picture parameter, IQMatrix, slice parameter, slice data
29782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VABufferID bufferIDs[4];
29882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
29982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_h264 *picData = &(data->pic_data[picIndex]);
30082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_slice_data_h264 *sliceData = &(picData->slc_data[sliceIndex]);
30182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
30282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASliceParameterBufferH264 *sliceParam = &(sliceData->slc_parms);
30382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
30482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (sliceParam->first_mb_in_slice == 0 || mDecodingFrame == false) {
30582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // either condition indicates start of a new frame
30682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (sliceParam->first_mb_in_slice != 0) {
30782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("The first slice is lost.");
30882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: handle the first slice lost
30982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
31082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mDecodingFrame) {
31182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // interlace content, complete decoding the first field
31282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaStatus = vaEndPicture(mVADisplay, mVAContext);
31382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            CHECK_VA_STATUS("vaEndPicture");
31482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
31582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // for interlace content, top field may be valid only after the second field is parsed
31682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            int32_t poc = getPOC(&(picParam->CurrPic));
31782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (poc < mAcquiredBuffer->pictureOrder) {
31882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mAcquiredBuffer->pictureOrder = poc;
31982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
32082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
32182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Check there is no reference frame loss before decoding a frame
32382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // Update  the reference frames and surface IDs for DPB and current frame
32582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = updateDPB(picParam);
32682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("updateDPB");
32782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
32882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_AVC_SHORT_FORMAT
32982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        //We have to provide a hacked DPB rather than complete DPB for libva as workaround
33082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        status = updateReferenceFrames(picData);
33182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_STATUS("updateReferenceFrames");
33282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
33382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaBeginPicture(mVADisplay, mVAContext, mAcquiredBuffer->renderBuffer.surface);
33482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaBeginPicture");
33582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // start decoding a frame
33782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mDecodingFrame = true;
33882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
33982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
34082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
34182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
34282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAPictureParameterBufferType,
34382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeof(VAPictureParameterBufferH264),
34482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
34582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            picParam,
34682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
34782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreatePictureParameterBuffer");
34882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
34982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
35082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        vaStatus = vaCreateBuffer(
35182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
35282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVAContext,
35382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAIQMatrixBufferType,
35482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            sizeof(VAIQMatrixBufferH264),
35582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            1,
35682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            data->IQ_matrix_buf,
35782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &bufferIDs[bufferIDCount]);
35882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        CHECK_VA_STATUS("vaCreateIQMatrixBuffer");
35982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount++;
36082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
36182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_AVC_SHORT_FORMAT
36382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    status = setReference(sliceParam);
36582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_STATUS("setReference");
36682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
36782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
36882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
36982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
37082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceParameterBufferType,
37182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sizeof(VASliceParameterBufferH264),
37282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,
37382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceParam,
37482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
37582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
37682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
37782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
37882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
37982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceParameterBufferType,
38082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sizeof(VASliceParameterBufferH264Base),
38182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,
38282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceParam,
38382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
38482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
38582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSliceParameterBuffer");
38682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
38782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
38882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateBuffer(
38982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
39082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
39182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        VASliceDataBufferType,
39282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceData->slice_size, //size
39382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        1,        //num_elements
39482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceData->buffer_addr + sliceData->slice_offset,
39582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        &bufferIDs[bufferIDCount]);
39682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateSliceDataBuffer");
39782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bufferIDCount++;
39882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
39982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaRenderPicture(
40082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVADisplay,
40182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVAContext,
40282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDs,
40382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        bufferIDCount);
40482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaRenderPicture");
40582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
40782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
40882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
40982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::setReference(VASliceParameterBufferH264 *sliceParam) {
41082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t numList = 1;
41182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: set numList to 0 if it is I slice
41282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (sliceParam->slice_type == 1 || sliceParam->slice_type == 6) {
41382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // B slice
41482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        numList = 2;
41582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
41682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
41782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t activeMinus1 = sliceParam->num_ref_idx_l0_active_minus1;
41882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *ref = sliceParam->RefPicList0;
41982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
42082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < numList; i++) {
42182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (activeMinus1 >= REF_LIST_SIZE) {
42282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Invalid activeMinus1 (%d)", activeMinus1);
42382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return DECODE_PARSER_FAIL;
42482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
42582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t j = 0; j <= activeMinus1; j++, ref++) {
42682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (!(ref->flags & VA_PICTURE_H264_INVALID)) {
42782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                ref->picture_id = findSurface(ref);
42882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (ref->picture_id == VA_INVALID_SURFACE) {
42982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // Error DecodeRefMissing is counted once even there're multiple
43082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 1;
43182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    mAcquiredBuffer->renderBuffer.errBuf.errorArray[0].type = DecodeRefMissing;
43282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
43382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (mLastReference) {
43482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        WTRACE("Reference frame %d is missing. Use last reference", getPOC(ref));
43582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        ref->picture_id = mLastReference->renderBuffer.surface;
43682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    } else {
43782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        ETRACE("Reference frame %d is missing. Stop decoding.", getPOC(ref));
43882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        return DECODE_NO_REFERENCE;
43982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
44082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
44182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
44282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
44382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        activeMinus1 = sliceParam->num_ref_idx_l1_active_minus1;
44482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ref = sliceParam->RefPicList1;
44582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
44682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
44782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
44882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
44982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::updateDPB(VAPictureParameterBufferH264 *picParam) {
45082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    clearAsReference(mToggleDPB);
45182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // pointer to toggled DPB (new)
45282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    DecodedPictureBuffer *dpb = mDPBs[!mToggleDPB];
45382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *ref = picParam->ReferenceFrames;
45482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // update current picture ID
45682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    picParam->CurrPic.picture_id = mAcquiredBuffer->renderBuffer.surface;
45782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
45882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // build new DPB
45982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < MAX_REF_NUMBER; i++, ref++) {
46082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (ref->flags & VA_PICTURE_H264_INVALID) {
46182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            continue;
46282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
46382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef USE_AVC_SHORT_FORMAT
46482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ref->picture_id = findSurface(ref);
46582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
46682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb->poc = getPOC(ref);
46782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // looking for the latest ref frame in the DPB with specified POC, in case frames have same POC
46882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb->surfaceBuffer = findRefSurfaceBuffer(ref);
46982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (dpb->surfaceBuffer == NULL) {
47082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Reference frame %d is missing for current frame %d", dpb->poc, getPOC(&(picParam->CurrPic)));
47182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // Error DecodeRefMissing is counted once even there're multiple
47282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.errBuf.errorNumber = 1;
47382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mAcquiredBuffer->renderBuffer.errBuf.errorArray[0].type = DecodeRefMissing;
47482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (dpb->poc == getPOC(&(picParam->CurrPic))) {
47582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                WTRACE("updateDPB: Using the current picture for missing reference.");
47682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                dpb->surfaceBuffer = mAcquiredBuffer;
47782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else if (mLastReference) {
47882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                WTRACE("updateDPB: Use last reference frame %d for missing reference.", mLastReference->pictureOrder);
47982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // TODO: this is new code for error resilience
48082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                dpb->surfaceBuffer = mLastReference;
48182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            } else {
48282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                WTRACE("updateDPB: Unable to recover the missing reference frame.");
48382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // continue buillding DPB without updating dpb pointer.
48482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                continue;
48582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // continue building DPB as this reference may not be actually used.
48682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // especially happen after seeking to a non-IDR I frame.
48782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                //return DECODE_NO_REFERENCE;
48882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
48982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
49082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (dpb->surfaceBuffer) {
49182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // this surface is used as reference
49282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpb->surfaceBuffer->asReferernce = true;
49382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
49482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb++;
49582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
49682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
49782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // add current frame to DPB if it  is a reference frame
49882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
49982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
50082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb->poc = getPOC(&(picParam->CurrPic));
50182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb->surfaceBuffer = mAcquiredBuffer;
50282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        dpb->surfaceBuffer->asReferernce = true;
50382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
50482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // invalidate the current used DPB
50582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    invalidateDPB(mToggleDPB);
50682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mToggleDPB = !mToggleDPB;
50782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
50882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
50982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
51082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::updateReferenceFrames(vbp_picture_data_h264 *picData) {
51182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool found = false;
51282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t flags = 0;
51382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureParameterBufferH264 *picParam = picData->pic_parms;
51482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VASliceParameterBufferH264 *sliceParam = NULL;
51582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint8_t activeMinus1 = 0;
51682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *refList = NULL;
51782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *dpb = picParam->ReferenceFrames;
51882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAPictureH264 *refFrame = NULL;
51982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
5204ed41ba5c78e10aec0b96206709082c83d47af99ywan    for(int i = 0; i < picParam->num_ref_frames; i++) {
5214ed41ba5c78e10aec0b96206709082c83d47af99ywan        dpb->picture_id = findSurface(dpb);
5224ed41ba5c78e10aec0b96206709082c83d47af99ywan        dpb++;
5234ed41ba5c78e10aec0b96206709082c83d47af99ywan    }
5244ed41ba5c78e10aec0b96206709082c83d47af99ywan
5254ed41ba5c78e10aec0b96206709082c83d47af99ywan    return DECODE_SUCCESS;
5264ed41ba5c78e10aec0b96206709082c83d47af99ywan
52782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // invalidate DPB in the picture buffer
52882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    memset(picParam->ReferenceFrames, 0xFF, sizeof(picParam->ReferenceFrames));
52982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    picParam->num_ref_frames = 0;
53082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // update DPB  from the reference list in each slice.
53282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (uint32_t slice = 0; slice < picData->num_slices; slice++) {
53382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        sliceParam = &(picData->slc_data[slice].slc_parms);
53482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
53582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t list = 0; list < 2; list++) {
53682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            refList = (list == 0) ? sliceParam->RefPicList0 :
53782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                    sliceParam->RefPicList1;
53882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            activeMinus1 = (list == 0) ? sliceParam->num_ref_idx_l0_active_minus1 :
53982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                         sliceParam->num_ref_idx_l1_active_minus1;
54082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (activeMinus1 >= REF_LIST_SIZE) {
54182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                return DECODE_PARSER_FAIL;
54282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
54382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            for (uint8_t item = 0; item < (uint8_t)(activeMinus1 + 1); item++, refList++) {
54482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (refList->flags & VA_PICTURE_H264_INVALID) {
54582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    break;
54682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
54782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                found = false;
54882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                refFrame = picParam->ReferenceFrames;
54982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                for (uint8_t frame = 0; frame < picParam->num_ref_frames; frame++, refFrame++) {
55082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (refFrame->TopFieldOrderCnt == refList->TopFieldOrderCnt) {
55182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        ///check for complementary field
55282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        flags = refFrame->flags | refList->flags;
55382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        //If both TOP and BOTTOM are set, we'll clear those flags
55482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        if ((flags & VA_PICTURE_H264_TOP_FIELD) &&
55582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            (flags & VA_PICTURE_H264_BOTTOM_FIELD)) {
55682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            refFrame->flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
55782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
55882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        found = true;  //already in the DPB; will not add this one
55982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        break;
56082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
56182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
56282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (found == false) {
56382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // add a new reference to the DPB
56482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->picture_id = findSurface(refList);
56582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (dpb->picture_id == VA_INVALID_SURFACE) {
56682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        if (mLastReference != NULL) {
56782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            dpb->picture_id = mLastReference->renderBuffer.surface;
56882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        } else {
56982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            ETRACE("Reference frame %d is missing. Stop updating references frames.", getPOC(refList));
57082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                            return DECODE_NO_REFERENCE;
57182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        }
57282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    }
57382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->flags = refList->flags;
57482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // if it's bottom field in dpb, there must have top field in DPB,
57582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    // so clear the bottom flag, or will confuse VED to address top field
57682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    if (dpb->flags & VA_PICTURE_H264_BOTTOM_FIELD)
57782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                        dpb->flags &= (~VA_PICTURE_H264_BOTTOM_FIELD);
57882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->frame_idx = refList->frame_idx;
57982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->TopFieldOrderCnt = refList->TopFieldOrderCnt;
58082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->BottomFieldOrderCnt = refList->BottomFieldOrderCnt;
58182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb++;
58282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    picParam->num_ref_frames++;
58382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
58482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
58582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
58682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
58782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
58882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
58982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
59082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::removeReferenceFromDPB(VAPictureParameterBufferH264 *picParam) {
59182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // remove the current frame from DPB as it can't be decoded.
59282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((picParam->CurrPic.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE) ||
59382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (picParam->CurrPic.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE)) {
59482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
59582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t poc = getPOC(&(picParam->CurrPic));
59682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
59782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (poc == dpb->poc) {
59882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                dpb->poc = (int32_t)POC_DEFAULT;
59982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                if (dpb->surfaceBuffer) {
60082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    dpb->surfaceBuffer->asReferernce = false;
60182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                }
60282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                dpb->surfaceBuffer = NULL;
60382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                break;
60482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
60582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
60682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
60782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
60882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
60982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint32_t VideoDecoderAVC::getPOC(VAPictureH264 *pic) {
61082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) {
61182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return pic->BottomFieldOrderCnt;
61282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
61382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return pic->TopFieldOrderCnt;
61482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
61582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
61682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVASurfaceID VideoDecoderAVC::findSurface(VAPictureH264 *pic) {
61782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoSurfaceBuffer *p = findSurfaceBuffer(pic);
61882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (p == NULL) {
61982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Could not find surface for poc %d", getPOC(pic));
62082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return VA_INVALID_SURFACE;
62182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
62282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return p->renderBuffer.surface;
62382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
62482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
62582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderAVC::findSurfaceBuffer(VAPictureH264 *pic) {
62682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
62782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < DPB_SIZE; i++, dpb++) {
62882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (dpb->poc == pic->BottomFieldOrderCnt ||
62982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpb->poc == pic->TopFieldOrderCnt) {
63082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: remove these debugging codes
63182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (dpb->surfaceBuffer == NULL) {
63282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                ETRACE("Invalid surface buffer in the DPB for poc %d.", getPOC(pic));
63382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
63482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return dpb->surfaceBuffer;
63582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
63682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
63782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // ETRACE("Unable to find surface for poc %d", getPOC(pic));
63882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NULL;
63982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
64082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
64182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONVideoSurfaceBuffer* VideoDecoderAVC::findRefSurfaceBuffer(VAPictureH264 *pic) {
64282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    DecodedPictureBuffer *dpb = mDPBs[mToggleDPB];
64382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // always looking for the latest one in the DPB, in case ref frames have same POC
64482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    dpb += (DPB_SIZE - 1);
64582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = DPB_SIZE; i > 0; i--, dpb--) {
64682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (dpb->poc == pic->BottomFieldOrderCnt ||
64782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            dpb->poc == pic->TopFieldOrderCnt) {
64882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // TODO: remove these debugging codes
64982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if (dpb->surfaceBuffer == NULL) {
65082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                ETRACE("Invalid surface buffer in the DPB for poc %d.", getPOC(pic));
65182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
65282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return dpb->surfaceBuffer;
65382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
65482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
65582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ETRACE("Unable to find surface for poc %d", getPOC(pic));
65682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return NULL;
65782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
65882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
65982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::invalidateDPB(int toggle) {
66082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    DecodedPictureBuffer* p = mDPBs[toggle];
66182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < DPB_SIZE; i++) {
66282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->poc = (int32_t) POC_DEFAULT;
66382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p->surfaceBuffer = NULL;
66482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p++;
66582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
66682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
66782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
66882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::clearAsReference(int toggle) {
66982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    DecodedPictureBuffer* p = mDPBs[toggle];
67082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int i = 0; i < DPB_SIZE; i++) {
67182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (p->surfaceBuffer) {
67282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            p->surfaceBuffer->asReferernce = false;
67382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
67482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        p++;
67582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
67682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
67782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
67882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::startVA(vbp_data_h264 *data) {
67982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t DPBSize = getDPBSize(data);
68082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
68182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    //Use high profile for all kinds of H.264 profiles (baseline, main and high) except for constrained baseline
68282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAProfile vaProfile = VAProfileH264High;
68382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
684f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai    if (mConfigBuffer.flag & WANT_ADAPTIVE_PLAYBACK) {
685f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai        // When Adaptive playback is enabled, turn off low delay mode.
686f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai        // Otherwise there may be a 240ms stuttering if the output mode is changed from LowDelay to Delay.
687f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai        enableLowDelayMode(false);
688f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai    } else {
689f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai        // for baseline profile or constrained high profile, enable low delay mode automatically
690f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai        enableLowDelayMode((data->codec_data->profile_idc == 66) || (data->codec_data->profile_idc == 100 && data->codec_data->constraint_set4_flag == 1 && data->codec_data->constraint_set5_flag == 1));
691f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai    }
692f75cf2c23758e265bd54ad71ea2d07f52b7e0f1fLang Dai
69382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // TODO: determine when to use VAProfileH264ConstrainedBaseline, set only if we are told to do so
69482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((data->codec_data->profile_idc == 66 || data->codec_data->constraint_set0_flag == 1) &&
69582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data->constraint_set1_flag == 1) {
69682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (mErrorConcealment) {
69782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            vaProfile = VAProfileH264ConstrainedBaseline;
69882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
69982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
70082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
70182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VideoDecoderBase::setOutputWindowSize(mConfigBuffer.flag & WANT_ADAPTIVE_PLAYBACK ? OUTPUT_WINDOW_SIZE : DPBSize);
70282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    updateFormatInfo(data);
70382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
70482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON   // for 1080p, limit the total surface to 19, according the hardware limitation
70582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON   // change the max surface number from 19->10 to workaround memory shortage
70682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON   // remove the workaround
7073ed03d0de15f3910f40ee799cafc1d6a9b309e8dXin Wang    if(mVideoFormatInfo.surfaceHeight == 1088 && DPBSize + AVC_EXTRA_SURFACE_NUMBER > 19) {
70882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        DPBSize = 19 - AVC_EXTRA_SURFACE_NUMBER;
70982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
71082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return VideoDecoderBase::setupVA(DPBSize + AVC_EXTRA_SURFACE_NUMBER, vaProfile);
71282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
71382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
71482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONvoid VideoDecoderAVC::updateFormatInfo(vbp_data_h264 *data) {
71582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // new video size
71682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t width = (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) * 16;
71782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t height = (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) * 16;
7183558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu
7193558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu    if (data->codec_data->crop_top > 0)
7203558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu        height -= data->codec_data->crop_top;
7213558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu
7223558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu    if (data->codec_data->crop_bottom > 0)
7233558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu        height -= data->codec_data->crop_bottom;
7243558fce240d7994176f200e04acd0d9d6e5b646eAustin Hu
7258008c14104b6acec387192a378aa6e976f4952ecXin Wang    if(data->codec_data->crop_left > 0)
7268008c14104b6acec387192a378aa6e976f4952ecXin Wang        width -= data->codec_data->crop_left;
7278008c14104b6acec387192a378aa6e976f4952ecXin Wang
7288008c14104b6acec387192a378aa6e976f4952ecXin Wang    if(data->codec_data->crop_right > 0)
7298008c14104b6acec387192a378aa6e976f4952ecXin Wang        width -= data->codec_data->crop_right;
7308008c14104b6acec387192a378aa6e976f4952ecXin Wang
73182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("updateFormatInfo: current size: %d x %d, new size: %d x %d",
73282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.width, mVideoFormatInfo.height, width, height);
73382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
7341175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
7351175ce579a69e847027026f615a053af76b792d5Tianmi Chen        pthread_mutex_lock(&mFormatLock);
7361175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
7371175ce579a69e847027026f615a053af76b792d5Tianmi Chen
73882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if ((mVideoFormatInfo.width != width ||
73982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height != height) &&
74082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        width && height) {
74182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (VideoDecoderBase::alignMB(mVideoFormatInfo.width) != width ||
74282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VideoDecoderBase::alignMB(mVideoFormatInfo.height) != height) {
74382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mSizeChanged = true;
74482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ITRACE("Video size is changed.");
74582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
74682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.width = width;
74782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.height = height;
74882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
74982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
75082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // video_range has default value of 0.
75182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.videoRange = data->codec_data->video_full_range_flag;
75282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
75382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    switch (data->codec_data->matrix_coefficients) {
75482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 1:
75582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = VA_SRC_BT709;
75682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
75782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
75882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // ITU-R Recommendation BT.470-6 System B, G (MP4), same as
75982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // SMPTE 170M/BT601
76082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 5:
76182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        case 6:
76282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = VA_SRC_BT601;
76382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
76482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
76582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        default:
76682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // unknown color matrix, set to 0 so color space flag will not be set.
76782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVideoFormatInfo.colorMatrix = 0;
76882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
76982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
77082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.aspectX = data->codec_data->sar_width;
77182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.aspectY = data->codec_data->sar_height;
77282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.bitrate = data->codec_data->bit_rate;
77382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropLeft = data->codec_data->crop_left;
77482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropRight = data->codec_data->crop_right;
77582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropTop = data->codec_data->crop_top;
77682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    mVideoFormatInfo.cropBottom = data->codec_data->crop_bottom;
77782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
77882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("Cropping: left = %d, top = %d, right = %d, bottom = %d",
77982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data->crop_left,
78082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data->crop_top,
78182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data->crop_right,
78282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        data->codec_data->crop_bottom);
78382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
78482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION) {
78582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.actualBufferNeeded = mConfigBuffer.surfaceNumber;
78682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
78782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // The number of actual buffer needed is
78882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // outputQueue + nativewindow_owned + num_ref_frames + widi_need_max + 1(available buffer)
78982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // while outputQueue = DPB < 8? DPB :8
79082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.actualBufferNeeded = mOutputWindowSize + NW_CONSUMED /* Owned by native window */
79182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                              + data->codec_data->num_ref_frames
79282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_GEN_HW
79382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                              + HDMI_CONSUMED /* Two extra buffers are needed for native window buffer cycling */
79482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                              + (mWiDiOn ? WIDI_CONSUMED : 0) /* WiDi maximum needs */
79582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
79682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                                              + 1;
79782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
79882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
79982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("actualBufferNeeded =%d", mVideoFormatInfo.actualBufferNeeded);
80082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8011175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if ((mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER) && mStoreMetaData) {
8021175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (mSizeChanged
8031175ce579a69e847027026f615a053af76b792d5Tianmi Chen            || isWiDiStatusChanged()
8041175ce579a69e847027026f615a053af76b792d5Tianmi Chen            || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber)) {
8051175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVideoFormatInfo.valid = false;
8061175ce579a69e847027026f615a053af76b792d5Tianmi Chen        } else {
8071175ce579a69e847027026f615a053af76b792d5Tianmi Chen            mVideoFormatInfo.valid = true;
8081175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
8091175ce579a69e847027026f615a053af76b792d5Tianmi Chen
8101175ce579a69e847027026f615a053af76b792d5Tianmi Chen        pthread_mutex_unlock(&mFormatLock);
8111175ce579a69e847027026f615a053af76b792d5Tianmi Chen    } else {
8121175ce579a69e847027026f615a053af76b792d5Tianmi Chen        mVideoFormatInfo.valid = true;
8131175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
81482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    setRenderRect();
8169892b9c8b325cc6fc1e3fb98455b3701e89c8885Haitao Ding    setColorSpaceInfo(mVideoFormatInfo.colorMatrix, mVideoFormatInfo.videoRange);
81782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
81882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
81982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONbool VideoDecoderAVC::isWiDiStatusChanged() {
82082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_GEN_HW
82182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mWiDiOn)
82282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return false;
82382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (mConfigBuffer.flag & WANT_SURFACE_PROTECTION)
82582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return false;
82682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
82782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER))
82882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return false;
82982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
83082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    char prop[PROPERTY_VALUE_MAX];
83182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool widi_on = (property_get("media.widi.enabled", prop, NULL) > 0) &&
83282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                    (!strcmp(prop, "1") || !strcasecmp(prop, "true"));
83382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (widi_on) {
83482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mVideoFormatInfo.actualBufferNeeded += WIDI_CONSUMED;
83582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mWiDiOn = true;
83682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("WiDi is enabled, actual buffer needed is %d", mVideoFormatInfo.actualBufferNeeded);
83782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return true;
83882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
83982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return false;
84082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#else
84182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return false;
84282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
84382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
84482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
84582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::handleNewSequence(vbp_data_h264 *data) {
8461175ce579a69e847027026f615a053af76b792d5Tianmi Chen    Decode_Status status;
84782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    updateFormatInfo(data);
8481175ce579a69e847027026f615a053af76b792d5Tianmi Chen
84982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool rawDataMode = !(mConfigBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER);
8501175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (rawDataMode && mSizeChanged) {
8511175ce579a69e847027026f615a053af76b792d5Tianmi Chen        flushSurfaceBuffers();
8521175ce579a69e847027026f615a053af76b792d5Tianmi Chen        mSizeChanged = false;
8531175ce579a69e847027026f615a053af76b792d5Tianmi Chen        return DECODE_FORMAT_CHANGE;
8541175ce579a69e847027026f615a053af76b792d5Tianmi Chen    }
85582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8561175ce579a69e847027026f615a053af76b792d5Tianmi Chen    bool needFlush = false;
85782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (!rawDataMode) {
8581175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (mStoreMetaData) {
8591175ce579a69e847027026f615a053af76b792d5Tianmi Chen            needFlush = mSizeChanged
8601175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    || isWiDiStatusChanged()
8611175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber);
8621175ce579a69e847027026f615a053af76b792d5Tianmi Chen        } else {
8631175ce579a69e847027026f615a053af76b792d5Tianmi Chen            needFlush = (mVideoFormatInfo.width > mVideoFormatInfo.surfaceWidth)
8641175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    || (mVideoFormatInfo.height > mVideoFormatInfo.surfaceHeight)
8651175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    || isWiDiStatusChanged()
8661175ce579a69e847027026f615a053af76b792d5Tianmi Chen                    || (mVideoFormatInfo.actualBufferNeeded > mConfigBuffer.surfaceNumber);
8671175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
86882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
86982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
8701175ce579a69e847027026f615a053af76b792d5Tianmi Chen    if (needFlush) {
8711175ce579a69e847027026f615a053af76b792d5Tianmi Chen        if (mStoreMetaData) {
8721175ce579a69e847027026f615a053af76b792d5Tianmi Chen            status = endDecodingFrame(false);
8731175ce579a69e847027026f615a053af76b792d5Tianmi Chen            CHECK_STATUS("endDecodingFrame");
8741175ce579a69e847027026f615a053af76b792d5Tianmi Chen        } else {
8751175ce579a69e847027026f615a053af76b792d5Tianmi Chen            flushSurfaceBuffers();
8761175ce579a69e847027026f615a053af76b792d5Tianmi Chen        }
87782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        mSizeChanged = false;
87882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FORMAT_CHANGE;
87982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else
88082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_SUCCESS;
88182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
88282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
88382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONbool VideoDecoderAVC::isNewFrame(vbp_data_h264 *data, bool equalPTS) {
88482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (data->num_pictures == 0) {
88582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("num_pictures == 0");
88682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return true;
88782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
88882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
88982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vbp_picture_data_h264* picData = data->pic_data;
89082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (picData->num_slices == 0) {
89182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("num_slices == 0");
89282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return true;
89382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
89482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    bool newFrame = false;
89682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    uint32_t fieldFlags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD;
89782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
89882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (picData->slc_data[0].slc_parms.first_mb_in_slice != 0) {
89982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // not the first slice, assume it is continuation of a partial frame
90082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // TODO: check if it is new frame boundary as the first slice may get lost in streaming case.
90182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        WTRACE("first_mb_in_slice != 0");
90282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (!equalPTS) {
90382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // return true if different timestamp, it is a workaround here for a streaming case
90482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("different PTS, treat it as a new frame");
90582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            return true;
90682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
90782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
90882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if ((picData->pic_parms->CurrPic.flags & fieldFlags) == fieldFlags) {
90982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            ETRACE("Current picture has both odd field and even field.");
91082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
91182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // current picture is a field or a frame, and buffer conains the first slice, check if the current picture and
91282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        // the last picture form an opposite field pair
91382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (((mLastPictureFlags | picData->pic_parms->CurrPic.flags) & fieldFlags) == fieldFlags) {
91482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            // opposite field
91582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newFrame = false;
91682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            WTRACE("current picture is not at frame boundary.");
91782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mLastPictureFlags = 0;
91882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        } else {
91982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            newFrame = true;
92082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mLastPictureFlags = 0;
92182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            for (uint32_t i = 0; i < data->num_pictures; i++) {
92282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mLastPictureFlags |= data->pic_data[i].pic_parms->CurrPic.flags;
92382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
92482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            if ((mLastPictureFlags & fieldFlags) == fieldFlags) {
92582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                // current buffer contains both odd field and even field.
92682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                mLastPictureFlags = 0;
92782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            }
92882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
92982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
93082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
93182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return newFrame;
93282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
93382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
93482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONint32_t VideoDecoderAVC::getDPBSize(vbp_data_h264 *data) {
93582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 384 ), 16
93682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    struct DPBTable {
93782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        int32_t level;
93882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        float maxDPB;
93982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } dpbTable[] = {
94082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {9,  148.5},
94182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {10, 148.5},
94282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {11, 337.5},
94382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {12, 891.0},
94482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {13, 891.0},
94582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {20, 891.0},
94682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {21, 1782.0},
94782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {22, 3037.5},
94882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {30, 3037.5},
94982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {31, 6750.0},
95082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {32, 7680.0},
95182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {40, 12288.0},
95282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {41, 12288.0},
95382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {42, 13056.0},
95482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {50, 41400.0},
95582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        {51, 69120.0}
95682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    };
95782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
95882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t count = sizeof(dpbTable)/sizeof(DPBTable);
95982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    float maxDPB = 0;
96082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    for (int32_t i = 0; i < count; i++)
96182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    {
96282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        if (dpbTable[i].level == data->codec_data->level_idc) {
96382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            maxDPB = dpbTable[i].maxDPB;
96482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            break;
96582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        }
96682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
96782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
96882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    int32_t maxDPBSize = maxDPB * 1024 / (
96982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (data->pic_data[0].pic_parms->picture_width_in_mbs_minus1 + 1) *
97082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        (data->pic_data[0].pic_parms->picture_height_in_mbs_minus1 + 1) *
97182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        384);
97282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
97382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (maxDPBSize > 16) {
97482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        maxDPBSize = 16;
97582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (maxDPBSize == 0) {
97682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        maxDPBSize = 3;
97782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
97882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if(maxDPBSize < data->codec_data->num_ref_frames) {
97982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        maxDPBSize = data->codec_data->num_ref_frames;
98082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
98182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
98282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    // add one extra frame for current frame.
98382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    maxDPBSize += 1;
98482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    ITRACE("maxDPBSize = %d, num_ref_frame = %d", maxDPBSize, data->codec_data->num_ref_frames);
98582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return maxDPBSize;
98682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
98782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
98882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::checkHardwareCapability() {
98982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifndef USE_GEN_HW
99082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
99182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib cfgAttribs[2];
99282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    cfgAttribs[0].type = VAConfigAttribMaxPictureWidth;
99382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    cfgAttribs[1].type = VAConfigAttribMaxPictureHeight;
99482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaGetConfigAttributes(mVADisplay, VAProfileH264High,
99582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD, cfgAttribs, 2);
99682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaGetConfigAttributes");
99782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (cfgAttribs[0].value * cfgAttribs[1].value < (uint32_t)mVideoFormatInfo.width * (uint32_t)mVideoFormatInfo.height) {
99882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("hardware supports resolution %d * %d smaller than the clip resolution %d * %d",
99982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON                cfgAttribs[0].value, cfgAttribs[1].value, mVideoFormatInfo.width, mVideoFormatInfo.height);
100082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_DRIVER_FAIL;
100182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
100282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
100382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
100482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
100582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
100682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#ifdef USE_AVC_SHORT_FORMAT
100782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTONDecode_Status VideoDecoderAVC::getCodecSpecificConfigs(
100882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAProfile profile, VAConfigID *config)
100982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON{
101082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAStatus vaStatus;
101182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    VAConfigAttrib attrib[2];
101282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
101382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (config == NULL) {
101482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Invalid parameter!");
101582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
101682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
101782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
101882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[0].type = VAConfigAttribRTFormat;
101982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[0].value = VA_RT_FORMAT_YUV420;
102082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[1].type = VAConfigAttribDecSliceMode;
102182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
102282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
102382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaGetConfigAttributes(mVADisplay,profile,VAEntrypointVLD, &attrib[1], 1);
102482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
102582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    if (attrib[1].value & VA_DEC_SLICE_MODE_BASE) {
102682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("AVC short format used");
102782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib[1].value = VA_DEC_SLICE_MODE_BASE;
102882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else if (attrib[1].value & VA_DEC_SLICE_MODE_NORMAL) {
102982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ITRACE("AVC long format ssed");
103082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        attrib[1].value = VA_DEC_SLICE_MODE_NORMAL;
103182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    } else {
103282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        ETRACE("Unsupported Decode Slice Mode!");
103382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON        return DECODE_FAIL;
103482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    }
103582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
103682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    vaStatus = vaCreateConfig(
103782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            mVADisplay,
103882b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            profile,
103982b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            VAEntrypointVLD,
104082b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            &attrib[0],
104182b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            2,
104282b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON            config);
104382b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    CHECK_VA_STATUS("vaCreateConfig");
104482b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON
104582b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON    return DECODE_SUCCESS;
104682b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON}
104782b428e49a70ddc051a36d2b3a25d90db79770dcGuilhem IMBERTON#endif
1048