1e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu/* 2e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 3e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* 4e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Licensed under the Apache License, Version 2.0 (the "License"); 5e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* you may not use this file except in compliance with the License. 6e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* You may obtain a copy of the License at 7e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* 8e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* http://www.apache.org/licenses/LICENSE-2.0 9e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* 10e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* Unless required by applicable law or agreed to in writing, software 11e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* distributed under the License is distributed on an "AS IS" BASIS, 12e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* See the License for the specific language governing permissions and 14e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu* limitations under the License. 15e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu*/ 16e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 17e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 1854272c0e474f97ac0269706170eb9161b36a9170wgu// #define LOG_NDEBUG 0 19bcabe3079546f97c7e2dc72886e55fabaff51848Andy Qiu#define LOG_TAG "OMXVideoDecoder" 2026a110c2a29667599733db5173a751e670b366a5Thierry Strudel#include <wrs_omxil_core/log.h> 21e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu#include "OMXVideoDecoderAVC.h" 22e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 23b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao 24e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) 25e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiustatic const char* AVC_MIME_TYPE = "video/h264"; 26e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu#define INVALID_PTS (OMX_S64)-1 27e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 28e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 29e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMXVideoDecoderAVC::OMXVideoDecoderAVC() 30e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu : mAccumulateBuffer(NULL), 31e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mBufferSize(0), 32e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mFilledLen(0), 33e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp(INVALID_PTS) { 34e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGV("OMXVideoDecoderAVC is constructed."); 35e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mVideoDecoder = createVideoDecoder(AVC_MIME_TYPE); 36e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (!mVideoDecoder) { 37e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGE("createVideoDecoder failed for \"%s\"", AVC_MIME_TYPE); 38e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 39747c717e9477b5b660f39a2b737de5e968fa7f9dWeian Chen // Override default native buffer count defined in the base class 40747c717e9477b5b660f39a2b737de5e968fa7f9dWeian Chen mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT; 41e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu BuildHandlerList(); 42e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 43e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 44e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMXVideoDecoderAVC::~OMXVideoDecoderAVC() { 45e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGV("OMXVideoDecoderAVC is destructed."); 46e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 47e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 48e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { 49e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu //OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS 50e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memset(&mDecodeSettings, 0, sizeof(mDecodeSettings)); 51e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu SetTypeHeader(&mDecodeSettings, sizeof(mDecodeSettings)); 52e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mDecodeSettings.nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME; 53e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 54e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // OMX_PARAM_PORTDEFINITIONTYPE 55e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; 56e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; 57e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; 58e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; 59e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; 60e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 61e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // OMX_VIDEO_PARAM_AVCTYPE 62e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memset(&mParamAvc, 0, sizeof(mParamAvc)); 63e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); 64e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mParamAvc.nPortIndex = INPORT_INDEX; 65e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // TODO: check eProfile/eLevel 66e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline; 67e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1; 68e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 69e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 70e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 71e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 72e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorInit(void) { 73e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMXVideoDecoderBase::ProcessorInit(); 74e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 75e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 76e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorDeinit(void) { 77e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mAccumulateBuffer) { 78e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu delete mAccumulateBuffer; 79e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 80e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mAccumulateBuffer = NULL; 81e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mBufferSize = 0; 82e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mFilledLen = 0; 83e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp = INVALID_PTS; 84e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 85e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMXVideoDecoderBase::ProcessorDeinit(); 86e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 87e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 88e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorFlush(OMX_U32 portIndex) { 89e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mFilledLen = 0; 90e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp = INVALID_PTS; 91e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMXVideoDecoderBase::ProcessorFlush(portIndex); 92e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 93e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 94e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorProcess( 95b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao OMX_BUFFERHEADERTYPE ***pBuffers, 96e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu buffer_retain_t *retains, 97e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_U32 numberBuffers) { 98e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 99b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao return OMXVideoDecoderBase::ProcessorProcess(pBuffers, retains, numberBuffers); 100e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 101e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 102e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::PrepareConfigBuffer(VideoConfigBuffer *p) { 103e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_ERRORTYPE ret; 104c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen 1058332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen ret = OMXVideoDecoderBase::PrepareConfigBuffer(p); 1068332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer"); 1078332b6aabd6694874a3269850c6d6f62fd76896dWeian Chen 108c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline) { 109c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen p->flag |= WANT_LOW_DELAY; 110c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen } 111c1241ad0d5cde2667d058cad8b2bf725514301e2Weian Chen 112e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mDecodeSettings.nMaxWidth == 0 || 113e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mDecodeSettings.nMaxHeight == 0) { 114e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 115e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 116e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 117e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGW("AVC Video decoder used in Video Conferencing Mode."); 118e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 119e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // For video conferencing application 120e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->width = mDecodeSettings.nMaxWidth; 121e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->height = mDecodeSettings.nMaxHeight; 122e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->profile = VAProfileH264ConstrainedBaseline; 123b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao if(!(p->flag & USE_NATIVE_GRAPHIC_BUFFER)) { 124b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao p->surfaceNumber = mDecodeSettings.nMaxNumberOfReferenceFrame + EXTRA_REFERENCE_FRAME; 125b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao p->flag = WANT_ERROR_CONCEALMENT | WANT_LOW_DELAY | HAS_SURFACE_NUMBER | HAS_VA_PROFILE; 126b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao } else { 127b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao p->flag |= WANT_ERROR_CONCEALMENT | WANT_LOW_DELAY | HAS_SURFACE_NUMBER | HAS_VA_PROFILE; 128b2257cdcf3ffd7a4a7dedbe4842185689bcf7fb7xiao } 129e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 130e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 131e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 132e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 133e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { 134e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_ERRORTYPE ret; 135e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); 136e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer"); 137e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 138e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // OMX_BUFFERFLAG_CODECCONFIG is an optional flag 139e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // if flag is set, buffer will only contain codec data. 140e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { 141e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGV("Received AVC codec data."); 142e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return ret; 143e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 144e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 145e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // OMX_BUFFERFLAG_ENDOFFRAME is an optional flag 1467951f06f8e3b6a91d385508b6f24720bc382df96ywan if (buffer->nFlags & (OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS)) { 147e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // TODO: if OMX_BUFFERFLAG_ENDOFFRAME indicates end of a NAL unit and in OMXVideoDecodeBase 148e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // we set buffer flag to HAS_COMPLETE_FRAME, corruption will happen 149e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp = buffer->nTimeStamp; 150e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mFilledLen == 0) { 151e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // buffer is not accumulated and it contains a complete frame 152e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return ret; 153e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 154e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // buffer contains the last part of fragmented frame 155e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = AccumulateBuffer(buffer); 156e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_RETURN_VALUE("AccumulateBuffer"); 157e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = FillDecodeBuffer(p); 158e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_RETURN_VALUE("FillDecodeBuffer"); 159e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return ret; 160e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 161e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 162e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGW("Received fragmented buffer."); 163e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // use time stamp to determine frame boundary 164e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mTimeStamp == INVALID_PTS) { 165e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // first ever buffer 166e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp = buffer->nTimeStamp; 167e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 168e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 169e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mTimeStamp != buffer->nTimeStamp && mFilledLen != 0) { 170e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // buffer accumulated contains a complete frame 171e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = FillDecodeBuffer(p); 172e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_RETURN_VALUE("FillDecodeBuffer"); 173e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // retain the current buffer 174e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu *retain = BUFFER_RETAIN_GETAGAIN; 175e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } else { 176e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // buffer accumulation for beginning of fragmented buffer (mFilledLen == 0) or 177e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // middle/end of fragmented buffer (mFilledLen != 0) 178e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = AccumulateBuffer(buffer); 179e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_RETURN_VALUE("AccumulateBuffer"); 180e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu ret = OMX_ErrorNotReady; 181e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 182e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 183e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (buffer->nFilledLen != 0) { 184e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mTimeStamp = buffer->nTimeStamp; 185e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 186e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return ret; 187e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 188e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 189e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::AccumulateBuffer(OMX_BUFFERHEADERTYPE *buffer) { 190e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // check if allocated buffer is big enough 191e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mFilledLen + buffer->nFilledLen > mBufferSize) { 192e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mBufferSize = mFilledLen + buffer->nFilledLen; 193e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mBufferSize < INPORT_BUFFER_SIZE) { 194e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mBufferSize = INPORT_BUFFER_SIZE; 195e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 196e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mBufferSize == 0) { 197e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorBadParameter; 198e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 199e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_U8 *temp = new OMX_U8 [mBufferSize]; 200e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (temp == NULL) { 201e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mBufferSize = 0; 202e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorInsufficientResources; 203e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 204e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mFilledLen != 0) { 205e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memcpy(temp, mAccumulateBuffer, mFilledLen); 206e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 207e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (mAccumulateBuffer) { 208e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu delete [] mAccumulateBuffer; 209e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 210e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mAccumulateBuffer = temp; 211e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 212e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if (buffer->nFilledLen != 0) { 213e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memcpy(mAccumulateBuffer + mFilledLen, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen); 214e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 215e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mFilledLen += buffer->nFilledLen; 216e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 217e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 218e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 219e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::FillDecodeBuffer(VideoDecodeBuffer *p) { 220e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->data = mAccumulateBuffer; 221e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->size = mFilledLen; 222e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->timeStamp = mTimeStamp; 223e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->flag = HAS_COMPLETE_FRAME; 224e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 225e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mFilledLen = 0; 226e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 227e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 228e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 229e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::BuildHandlerList(void) { 230e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMXVideoDecoderBase::BuildHandlerList(); 231e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); 232e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCDecodeSettings, GetParamIntelAVCDecodeSettings, SetParamIntelAVCDecodeSettings); 2336bc8d027bb46c0638d26b3f755350b84f6325de3wfeng AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoAVCProfileLevel, SetParamVideoAVCProfileLevel); 234e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 235e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 236e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 237e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamVideoAvc(OMX_PTR pStructure) { 238e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_ERRORTYPE ret; 239e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 240e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_TYPE_HEADER(p); 241e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_PORT_INDEX(p, INPORT_INDEX); 242e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 243e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memcpy(p, &mParamAvc, sizeof(*p)); 244e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 245e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 246e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 247e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamVideoAvc(OMX_PTR pStructure) { 248e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_ERRORTYPE ret; 249e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 250e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_TYPE_HEADER(p); 251e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_PORT_INDEX(p, INPORT_INDEX); 252e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_SET_PARAM_STATE(); 253e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 254e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // TODO: do we need to check if port is enabled? 255e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // TODO: see SetPortAvcParam implementation - Can we make simple copy???? 256e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu memcpy(&mParamAvc, p, sizeof(mParamAvc)); 257f775da472a8f0a626b0615eb283d614e0893f816Weian Chen 258e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 259e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 260e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 2610541f11be2f78b558476772f1f877e140f9d844bywanOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamIntelAVCDecodeSettings(OMX_PTR) { 262e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNotImplemented; 263e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 264e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 265e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy QiuOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamIntelAVCDecodeSettings(OMX_PTR pStructure) { 266e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu LOGW("SetParamIntelAVCDecodeSettings"); 267e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 268e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_ERRORTYPE ret; 269e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *p = (OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *)pStructure; 270e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 271e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_TYPE_HEADER(p); 272e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_PORT_INDEX(p, INPORT_INDEX); 273e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu CHECK_SET_PARAM_STATE(); 274e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 275e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu if(p->nMaxNumberOfReferenceFrame == 0) { 276e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu // TODO: check if we just return in this case. 277e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu p->nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME; 278e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu } 2790541f11be2f78b558476772f1f877e140f9d844bywan LOGI("Maximum width = %u, height = %u, dpb = %u", p->nMaxWidth, p->nMaxHeight, p->nMaxNumberOfReferenceFrame); 280e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu mDecodeSettings = *p; 281e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 282e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu return OMX_ErrorNone; 283e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu} 284e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 2856bc8d027bb46c0638d26b3f755350b84f6325de3wfengOMX_ERRORTYPE OMXVideoDecoderAVC::GetParamVideoAVCProfileLevel(OMX_PTR pStructure) { 2866bc8d027bb46c0638d26b3f755350b84f6325de3wfeng OMX_ERRORTYPE ret; 2876bc8d027bb46c0638d26b3f755350b84f6325de3wfeng OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; 2886bc8d027bb46c0638d26b3f755350b84f6325de3wfeng CHECK_TYPE_HEADER(p); 2896bc8d027bb46c0638d26b3f755350b84f6325de3wfeng CHECK_PORT_INDEX(p, INPORT_INDEX); 2906bc8d027bb46c0638d26b3f755350b84f6325de3wfeng 29154272c0e474f97ac0269706170eb9161b36a9170wgu struct ProfileLevelTable { 29254272c0e474f97ac0269706170eb9161b36a9170wgu OMX_U32 profile; 29354272c0e474f97ac0269706170eb9161b36a9170wgu OMX_U32 level; 29454272c0e474f97ac0269706170eb9161b36a9170wgu } plTable[] = { 295d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42}, 296d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42}, 297d8c394df484c6fda8009b7c5d51166e271d3d2bdGu, Wangyi {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42} 29854272c0e474f97ac0269706170eb9161b36a9170wgu }; 29954272c0e474f97ac0269706170eb9161b36a9170wgu 30054272c0e474f97ac0269706170eb9161b36a9170wgu OMX_U32 count = sizeof(plTable)/sizeof(ProfileLevelTable); 30154272c0e474f97ac0269706170eb9161b36a9170wgu CHECK_ENUMERATION_RANGE(p->nProfileIndex,count); 30254272c0e474f97ac0269706170eb9161b36a9170wgu 30354272c0e474f97ac0269706170eb9161b36a9170wgu p->eProfile = plTable[p->nProfileIndex].profile; 30454272c0e474f97ac0269706170eb9161b36a9170wgu p->eLevel = plTable[p->nProfileIndex].level; 3056bc8d027bb46c0638d26b3f755350b84f6325de3wfeng 3066bc8d027bb46c0638d26b3f755350b84f6325de3wfeng return OMX_ErrorNone; 3076bc8d027bb46c0638d26b3f755350b84f6325de3wfeng} 3086bc8d027bb46c0638d26b3f755350b84f6325de3wfeng 3090541f11be2f78b558476772f1f877e140f9d844bywanOMX_ERRORTYPE OMXVideoDecoderAVC::SetParamVideoAVCProfileLevel(OMX_PTR) { 3106bc8d027bb46c0638d26b3f755350b84f6325de3wfeng LOGW("SetParamVideoAVCProfileLevel is not supported."); 3116bc8d027bb46c0638d26b3f755350b84f6325de3wfeng return OMX_ErrorUnsupportedSetting; 3126bc8d027bb46c0638d26b3f755350b84f6325de3wfeng} 313e7ace334fb7c64f7b32aa3746e5a11bcefa60bfbAndy Qiu 3140541f11be2f78b558476772f1f877e140f9d844bywanOMX_COLOR_FORMATTYPE OMXVideoDecoderAVC::GetOutputColorFormat(int width) 31573cebb604e43c066d2d31eb145f82fc3080db532wfeng{ 31673cebb604e43c066d2d31eb145f82fc3080db532wfeng#ifdef USE_GEN_HW 31773cebb604e43c066d2d31eb145f82fc3080db532wfeng return OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled; 31873cebb604e43c066d2d31eb145f82fc3080db532wfeng#else 3190541f11be2f78b558476772f1f877e140f9d844bywan return OMXVideoDecoderBase::GetOutputColorFormat(width); 32073cebb604e43c066d2d31eb145f82fc3080db532wfeng#endif 32173cebb604e43c066d2d31eb145f82fc3080db532wfeng} 32273cebb604e43c066d2d31eb145f82fc3080db532wfeng 32303118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi ChenOMX_ERRORTYPE OMXVideoDecoderAVC::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *p) { 32403118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen OMX_ERRORTYPE ret; 32503118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen CHECK_TYPE_HEADER(p); 32603118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen CHECK_PORT_INDEX(p, OUTPORT_INDEX); 32703118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen 32803118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen p->nBufferCountActual = MAX_OUTPORT_BUFFER_COUNT; 32903118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen return OMXVideoDecoderBase::SetMaxOutputBufferCount(p); 33003118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen} 33103118b9de04779e0aca0da6fe6fe5b0b0704a11cTianmi Chen 33211c1c17fed35585f9256031ee70db1c6c18d0219Yuanjun HuangDECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC", "video_decoder.avc", OMXVideoDecoderAVC); 333