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