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