1d05f9a0b79e3a07c9a868261debf4677e86af238ywan/*
2d05f9a0b79e3a07c9a868261debf4677e86af238ywan* Copyright (c) 2012 Intel Corporation.  All rights reserved.
3d05f9a0b79e3a07c9a868261debf4677e86af238ywan*
4d05f9a0b79e3a07c9a868261debf4677e86af238ywan* Licensed under the Apache License, Version 2.0 (the "License");
5d05f9a0b79e3a07c9a868261debf4677e86af238ywan* you may not use this file except in compliance with the License.
6d05f9a0b79e3a07c9a868261debf4677e86af238ywan* You may obtain a copy of the License at
7d05f9a0b79e3a07c9a868261debf4677e86af238ywan*
8d05f9a0b79e3a07c9a868261debf4677e86af238ywan* http://www.apache.org/licenses/LICENSE-2.0
9d05f9a0b79e3a07c9a868261debf4677e86af238ywan*
10d05f9a0b79e3a07c9a868261debf4677e86af238ywan* Unless required by applicable law or agreed to in writing, software
11d05f9a0b79e3a07c9a868261debf4677e86af238ywan* distributed under the License is distributed on an "AS IS" BASIS,
12d05f9a0b79e3a07c9a868261debf4677e86af238ywan* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d05f9a0b79e3a07c9a868261debf4677e86af238ywan* See the License for the specific language governing permissions and
14d05f9a0b79e3a07c9a868261debf4677e86af238ywan* limitations under the License.
15d05f9a0b79e3a07c9a868261debf4677e86af238ywan*/
16d05f9a0b79e3a07c9a868261debf4677e86af238ywan
17d05f9a0b79e3a07c9a868261debf4677e86af238ywan#define LOG_TIME 0
18d05f9a0b79e3a07c9a868261debf4677e86af238ywan//#define LOG_NDEBUG 0
19d05f9a0b79e3a07c9a868261debf4677e86af238ywan#define LOG_TAG "OMXVideoDecoderVP9Hybrid"
20d05f9a0b79e3a07c9a868261debf4677e86af238ywan#include <wrs_omxil_core/log.h>
21d05f9a0b79e3a07c9a868261debf4677e86af238ywan#include "OMXVideoDecoderVP9Hybrid.h"
22d05f9a0b79e3a07c9a868261debf4677e86af238ywan
23d05f9a0b79e3a07c9a868261debf4677e86af238ywan#include <hardware/hardware.h>
24d05f9a0b79e3a07c9a868261debf4677e86af238ywan#include <hardware/gralloc.h>
25d05f9a0b79e3a07c9a868261debf4677e86af238ywan#include <system/graphics.h>
26d05f9a0b79e3a07c9a868261debf4677e86af238ywan
277caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan#include <hal_public.h>
287caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan
2968942cfbb4d52185ea162f336a94d8bab263d366Gu, Wangyi#define VP9_YV12_ALIGN (128-1)
30d05f9a0b79e3a07c9a868261debf4677e86af238ywanstatic const char* VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
31d05f9a0b79e3a07c9a868261debf4677e86af238ywan
32d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMXVideoDecoderVP9Hybrid::OMXVideoDecoderVP9Hybrid() {
33d05f9a0b79e3a07c9a868261debf4677e86af238ywan    LOGV("OMXVideoDecoderVP9Hybrid is constructed.");
34d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT;
35d05f9a0b79e3a07c9a868261debf4677e86af238ywan    BuildHandlerList();
36d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mLibHandle = NULL;
37d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mOpenDecoder = NULL;
38d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mInitDecoder = NULL;
39d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mCloseDecoder = NULL;
40d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mSingalRenderDone = NULL;
41d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mDecoderDecode = NULL;
42d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mCheckBufferAvailable = NULL;
43d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mGetOutput = NULL;
4413c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    mGetRawDataOutput = NULL;
45c51d5398ac792d8ddd35d72322038305281b80edywan    mGetFrameResolution = NULL;
46c51d5398ac792d8ddd35d72322038305281b80edywan    mDeinitDecoder = NULL;
476725411e5c835fed1121f4ae9244013183f2ff38ywan    mLastTimeStamp = 0;
4813c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    mWorkingMode = RAWDATA_MODE;
495246619dfe1807934867669347b846166a18977eywan    mDecodedImageWidth = 0;
505246619dfe1807934867669347b846166a18977eywan    mDecodedImageHeight = 0;
515246619dfe1807934867669347b846166a18977eywan    mDecodedImageNewWidth = 0;
525246619dfe1807934867669347b846166a18977eywan    mDecodedImageNewHeight = 0;
53d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
54d05f9a0b79e3a07c9a868261debf4677e86af238ywan
55d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMXVideoDecoderVP9Hybrid::~OMXVideoDecoderVP9Hybrid() {
56d05f9a0b79e3a07c9a868261debf4677e86af238ywan    LOGV("OMXVideoDecoderVP9Hybrid is destructed.");
57d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
58d05f9a0b79e3a07c9a868261debf4677e86af238ywan
59d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::InitInputPortFormatSpecific(
60d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) {
61d05f9a0b79e3a07c9a868261debf4677e86af238ywan    // OMX_PARAM_PORTDEFINITIONTYPE
62d05f9a0b79e3a07c9a868261debf4677e86af238ywan    paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
63d05f9a0b79e3a07c9a868261debf4677e86af238ywan    paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
64d05f9a0b79e3a07c9a868261debf4677e86af238ywan    paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE;
65d05f9a0b79e3a07c9a868261debf4677e86af238ywan    paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)VP9_MIME_TYPE;
66d05f9a0b79e3a07c9a868261debf4677e86af238ywan    paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
67d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
68d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
69d05f9a0b79e3a07c9a868261debf4677e86af238ywan
70d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorInit(void) {
715246619dfe1807934867669347b846166a18977eywan    uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
725246619dfe1807934867669347b846166a18977eywan    uint32_t i, bufferCount;
7313c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
7440925de5b887baba55f944c62b91ce37a7485a84Austin Hu    uint32_t bufferSize, bufferHStride, bufferHeight, bufferVStride, bufferWidth;
7513c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    if (!gralloc_mode) {
767caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferHStride = 1920;
777caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferVStride = 1088;
7877e0e77a812f416a90713150431db498ad7559e5ywan        bufferWidth = 1920;
7940925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight = 1080;
8013c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        bufferCount = 12;
8113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    } else {
8294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == METADATA_MODE) {
8394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            const OMX_PARAM_PORTDEFINITIONTYPE *def_output = this->ports[OUTPORT_INDEX]->GetPortDefinition();
8494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            if (def_output == NULL) {
8594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                return OMX_ErrorBadParameter;
8694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
8794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            bufferCount = mMetaDataBuffersNum = def_output->nBufferCountActual;
8894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mOMXBufferHeaderTypePtrNum = 0;
8994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
9094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mGraphicBufferParam.graphicBufferColorFormat = def_output->format.video.eColorFormat;
917caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferHStride = (def_output->format.video.nFrameWidth + VP9_YV12_ALIGN) & ~VP9_YV12_ALIGN;
927caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferVStride = (def_output->format.video.nFrameHeight + 0x1f) & ~0x1f;
9394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mGraphicBufferParam.graphicBufferWidth = def_output->format.video.nFrameWidth;
947caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferHeight = def_output->format.video.nFrameHeight;
9594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mDecodedImageWidth = def_output->format.video.nFrameWidth;
9694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mDecodedImageHeight = def_output->format.video.nFrameHeight;
9794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        } else{
9894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            bufferCount = mOMXBufferHeaderTypePtrNum;
9994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
10094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            for (i = 0; i < bufferCount; i++ ) {
10194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
10294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                buff[i] = (uint32_t)(buf_hdr->pBuffer);
10394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
10494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        }
10594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
1067caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferHStride = mGraphicBufferParam.graphicBufferHStride;
1077caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferVStride = mGraphicBufferParam.graphicBufferVStride;
10877e0e77a812f416a90713150431db498ad7559e5ywan        bufferWidth = mGraphicBufferParam.graphicBufferWidth;
10940925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight = mGraphicBufferParam.graphicBufferHeight;
110d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
1117caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan
1127caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    bufferSize = bufferHStride * bufferVStride * 1.5;
1137caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan
114d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mLibHandle = dlopen("libDecoderVP9Hybrid.so", RTLD_NOW);
115d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (mLibHandle == NULL) {
116d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGE("dlopen libDecoderVP9Hybrid.so fail\n");
117d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorBadParameter;
118d05f9a0b79e3a07c9a868261debf4677e86af238ywan    } else {
119d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGI("dlopen libDecoderVP9Hybrid.so successfully\n");
120d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
121d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mOpenDecoder = (OpenFunc)dlsym(mLibHandle, "Decoder_Open");
122d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mCloseDecoder = (CloseFunc)dlsym(mLibHandle, "Decoder_Close");
123d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mInitDecoder = (InitFunc)dlsym(mLibHandle, "Decoder_Init");
124d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mSingalRenderDone = (SingalRenderDoneFunc)dlsym(mLibHandle, "Decoder_SingalRenderDone");
125d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mDecoderDecode = (DecodeFunc)dlsym(mLibHandle, "Decoder_Decode");
126d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mCheckBufferAvailable = (IsBufferAvailableFunc)dlsym(mLibHandle, "Decoder_IsBufferAvailable");
127d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mGetOutput = (GetOutputFunc)dlsym(mLibHandle, "Decoder_GetOutput");
12813c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    mGetRawDataOutput = (GetRawDataOutputFunc)dlsym(mLibHandle, "Decoder_GetRawDataOutput");
129c51d5398ac792d8ddd35d72322038305281b80edywan    mGetFrameResolution = (GetFrameResolutionFunc)dlsym(mLibHandle, "Decoder_GetFrameResolution");
130c51d5398ac792d8ddd35d72322038305281b80edywan    mDeinitDecoder = (DeinitFunc)dlsym(mLibHandle, "Decoder_Deinit");
131d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (mOpenDecoder == NULL || mCloseDecoder == NULL
132d05f9a0b79e3a07c9a868261debf4677e86af238ywan        || mInitDecoder == NULL || mSingalRenderDone == NULL
133d05f9a0b79e3a07c9a868261debf4677e86af238ywan        || mDecoderDecode == NULL || mCheckBufferAvailable == NULL
134c51d5398ac792d8ddd35d72322038305281b80edywan        || mGetOutput == NULL || mGetRawDataOutput == NULL
135c51d5398ac792d8ddd35d72322038305281b80edywan        || mGetFrameResolution == NULL || mDeinitDecoder == NULL) {
136d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorBadParameter;
137d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
138d05f9a0b79e3a07c9a868261debf4677e86af238ywan
139d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (mOpenDecoder(&mCtx,&mHybridCtx) == false) {
140d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGE("open hybrid Decoder fail\n");
141d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorBadParameter;
142d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
143d05f9a0b79e3a07c9a868261debf4677e86af238ywan
1447caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    // FIXME: The proprietary part of the vp9hybrid decoder should be updated
1457caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    //        to take VStride as well as Height. For now it's convenient to
1467caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    //        use VStride as that was effectively what was done before..
1477caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    mInitDecoder(mHybridCtx, bufferSize, bufferHStride, bufferWidth,
14840925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight, bufferCount, gralloc_mode, buff, (uint32_t)mAPMode);
149d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
150d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
151d05f9a0b79e3a07c9a868261debf4677e86af238ywan
152c51d5398ac792d8ddd35d72322038305281b80edywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorReset(void)
153c51d5398ac792d8ddd35d72322038305281b80edywan{
154c51d5398ac792d8ddd35d72322038305281b80edywan    uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
155c51d5398ac792d8ddd35d72322038305281b80edywan    uint32_t i, bufferCount;
156c51d5398ac792d8ddd35d72322038305281b80edywan    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
15740925de5b887baba55f944c62b91ce37a7485a84Austin Hu    uint32_t bufferSize, bufferHStride, bufferHeight, bufferVStride, bufferWidth;
158c51d5398ac792d8ddd35d72322038305281b80edywan    if (!gralloc_mode) {
1597caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferHStride = mDecodedImageWidth;
1607caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferVStride = mDecodedImageHeight;
16177e0e77a812f416a90713150431db498ad7559e5ywan        bufferWidth = mDecodedImageWidth;
16240925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight = mDecodedImageHeight;
1637caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferSize = bufferHStride * bufferVStride * 1.5;
164c51d5398ac792d8ddd35d72322038305281b80edywan        bufferCount = 12;
165c51d5398ac792d8ddd35d72322038305281b80edywan    } else {
16694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == METADATA_MODE) {
16794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            const OMX_PARAM_PORTDEFINITIONTYPE *def_output = this->ports[OUTPORT_INDEX]->GetPortDefinition();
16894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            if (def_output == NULL) {
16994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                return OMX_ErrorBadParameter;
17094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
17194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            bufferCount = mMetaDataBuffersNum = def_output->nBufferCountActual;
17294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mOMXBufferHeaderTypePtrNum = 0;
17394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
17494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mGraphicBufferParam.graphicBufferColorFormat = def_output->format.video.eColorFormat;
1757caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferHStride = (def_output->format.video.nFrameWidth + VP9_YV12_ALIGN) & ~VP9_YV12_ALIGN;
1767caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferVStride = (def_output->format.video.nFrameHeight + 0x1f) & ~0x1f;
17794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mGraphicBufferParam.graphicBufferWidth = def_output->format.video.nFrameWidth;
1787caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            mGraphicBufferParam.graphicBufferHeight = def_output->format.video.nFrameHeight;
17994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        } else{
18094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            bufferCount = mOMXBufferHeaderTypePtrNum;
18194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
18294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            for (i = 0; i < bufferCount; i++ ) {
18394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
18494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                buff[i] = (uint32_t)(buf_hdr->pBuffer);
18594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
18694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        }
1877caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferHStride = mGraphicBufferParam.graphicBufferHStride;
1887caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan        bufferVStride = mGraphicBufferParam.graphicBufferVStride;
18994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        bufferWidth = mGraphicBufferParam.graphicBufferWidth;
19040925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight = mGraphicBufferParam.graphicBufferHeight;
191c51d5398ac792d8ddd35d72322038305281b80edywan    }
192c51d5398ac792d8ddd35d72322038305281b80edywan
1937caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    bufferSize = bufferHStride * bufferVStride * 1.5;
1947caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan
1957caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    // FIXME: The proprietary part of the vp9hybrid decoder should be updated
1967caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    //        to take VStride as well as Height. For now it's convenient to
1977caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    //        use VStride as that was effectively what was done before..
1987caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    mInitDecoder(mHybridCtx, bufferSize, bufferHStride, bufferWidth,
19940925de5b887baba55f944c62b91ce37a7485a84Austin Hu        bufferHeight, bufferCount, gralloc_mode, buff, (uint32_t)mAPMode);
20094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    mFormatChanged = false;
201c51d5398ac792d8ddd35d72322038305281b80edywan    return OMX_ErrorNone;
202c51d5398ac792d8ddd35d72322038305281b80edywan}
203c51d5398ac792d8ddd35d72322038305281b80edywan
204c51d5398ac792d8ddd35d72322038305281b80edywanbool OMXVideoDecoderVP9Hybrid::isReallocateNeeded(const uint8_t * data,uint32_t data_sz)
205c51d5398ac792d8ddd35d72322038305281b80edywan{
206c51d5398ac792d8ddd35d72322038305281b80edywan    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
207c51d5398ac792d8ddd35d72322038305281b80edywan    uint32_t width, height;
208c51d5398ac792d8ddd35d72322038305281b80edywan    bool ret = true;
209c51d5398ac792d8ddd35d72322038305281b80edywan    if (gralloc_mode) {
210c51d5398ac792d8ddd35d72322038305281b80edywan        ret = mGetFrameResolution(data,data_sz, &width, &height);
2116b2c35f759069df850da5c0364cea0657a5cb837Xin Wang        if (width == 0 || height == 0)
2126b2c35f759069df850da5c0364cea0657a5cb837Xin Wang            return false;
2136b2c35f759069df850da5c0364cea0657a5cb837Xin Wang
214c51d5398ac792d8ddd35d72322038305281b80edywan        if (ret) {
21594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            if (mAPMode == METADATA_MODE) {
21694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                ret = (width != mDecodedImageWidth)
21794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    || (height != mDecodedImageHeight);
21894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            } else {
21994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                ret = width > mGraphicBufferParam.graphicBufferWidth
22094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    || height > mGraphicBufferParam.graphicBufferHeight;
22194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
222c51d5398ac792d8ddd35d72322038305281b80edywan            if (ret) {
223c51d5398ac792d8ddd35d72322038305281b80edywan                mDecodedImageNewWidth = width;
224c51d5398ac792d8ddd35d72322038305281b80edywan                mDecodedImageNewHeight = height;
225c51d5398ac792d8ddd35d72322038305281b80edywan                return true;
226c51d5398ac792d8ddd35d72322038305281b80edywan            }
227c51d5398ac792d8ddd35d72322038305281b80edywan        }
228c51d5398ac792d8ddd35d72322038305281b80edywan    }
22994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
230c51d5398ac792d8ddd35d72322038305281b80edywan    return ret;
231c51d5398ac792d8ddd35d72322038305281b80edywan}
232c51d5398ac792d8ddd35d72322038305281b80edywan
233d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorDeinit(void) {
234d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mCloseDecoder(mCtx,mHybridCtx);
235d05f9a0b79e3a07c9a868261debf4677e86af238ywan    mOMXBufferHeaderTypePtrNum = 0;
236d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (mLibHandle != NULL) {
237d05f9a0b79e3a07c9a868261debf4677e86af238ywan        dlclose(mLibHandle);
238d05f9a0b79e3a07c9a868261debf4677e86af238ywan        mLibHandle = NULL;
239d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
240d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
241d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
242d05f9a0b79e3a07c9a868261debf4677e86af238ywan
243d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorStop(void) {
244d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMXComponentCodecBase::ProcessorStop();
245d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
246d05f9a0b79e3a07c9a868261debf4677e86af238ywan
24713c7df7e879f64e0055bbcc61dbe0d472ac8d43bywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorFlush(OMX_U32 portIndex) {
24813c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
2495246619dfe1807934867669347b846166a18977eywan        // end the last frame
250c45012b443298ff3073d34164fa65a38d3a5fd20ywan        unsigned int width, height;
25113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
252c45012b443298ff3073d34164fa65a38d3a5fd20ywan        mGetOutput(mCtx,mHybridCtx, &width, &height);
25313c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    }
254d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
255d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
256d05f9a0b79e3a07c9a868261debf4677e86af238ywan
257d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) {
258d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (buffer->nOutputPortIndex == OUTPORT_INDEX){
25994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        unsigned int handle;
26094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == METADATA_MODE) {
26194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            bool found = false;
26294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            if (mOMXBufferHeaderTypePtrNum < mMetaDataBuffersNum) {
26394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
26494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    if (mOMXBufferHeaderTypePtrArray[i] == buffer) {
26594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                        found = true;
26694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                        break;
26794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    }
26894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                }
26994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                if (!found) {
27094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum] = buffer;
27194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    mOMXBufferHeaderTypePtrNum++;
27294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                }
27394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            } else {
27494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                found = true;
27594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            }
27694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
27794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            android::VideoGrallocMetadata *metadata = (android::VideoGrallocMetadata *)(buffer->pBuffer);
27894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            handle = (unsigned int)metadata->pHandle;
27994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mSingalRenderDone(mHybridCtx, handle, !found);
28094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        } else {
28194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            handle = (unsigned int)buffer->pBuffer;
28294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            mSingalRenderDone(mHybridCtx, handle, false);
28394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        }
284d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
285d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
286d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
287d05f9a0b79e3a07c9a868261debf4677e86af238ywan
288d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorProcess(
289d05f9a0b79e3a07c9a868261debf4677e86af238ywan        OMX_BUFFERHEADERTYPE ***pBuffers,
290d05f9a0b79e3a07c9a868261debf4677e86af238ywan        buffer_retain_t *retains,
291d05f9a0b79e3a07c9a868261debf4677e86af238ywan        OMX_U32)
292d05f9a0b79e3a07c9a868261debf4677e86af238ywan{
293d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_ERRORTYPE ret;
294d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_BUFFERHEADERTYPE *inBuffer = *pBuffers[INPORT_INDEX];
295d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_BUFFERHEADERTYPE *outBuffer = *pBuffers[OUTPORT_INDEX];
2965246619dfe1807934867669347b846166a18977eywan    OMX_BOOL isResolutionChange = OMX_FALSE;
297e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    bool eos = (inBuffer->nFlags & OMX_BUFFERFLAG_EOS)? true : false;
2986725411e5c835fed1121f4ae9244013183f2ff38ywan    eos = eos && (inBuffer->nFilledLen == 0);
299e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    static unsigned char *firstFrame = NULL;
300e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    static uint32_t firstFrameSize = 0;
301d05f9a0b79e3a07c9a868261debf4677e86af238ywan
302d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (inBuffer->pBuffer == NULL) {
303d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGE("Buffer to decode is empty.");
304d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorBadParameter;
305d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
306d05f9a0b79e3a07c9a868261debf4677e86af238ywan
307d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (inBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
308d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag.");
309d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
310d05f9a0b79e3a07c9a868261debf4677e86af238ywan
311d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (inBuffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) {
312d05f9a0b79e3a07c9a868261debf4677e86af238ywan        LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag.");
313d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
314d05f9a0b79e3a07c9a868261debf4677e86af238ywan
315e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    if (firstFrameSize == 0 && inBuffer->nFilledLen != 0 && inBuffer->nTimeStamp != 0) {
316e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        if (firstFrame != NULL) {
317e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            free(firstFrame);
318e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            firstFrame = NULL;
319e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        }
320e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
321e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        firstFrame = (unsigned char *)malloc(inBuffer->nFilledLen);
322e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        memcpy(firstFrame, inBuffer->pBuffer + inBuffer->nOffset, inBuffer->nFilledLen);
323e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        firstFrameSize = inBuffer->nFilledLen;
324e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    }
325e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
326e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    if ((mWorkingMode == GRAPHICBUFFER_MODE) && (mAPMode == METADATA_MODE) && (!mFormatChanged)) {
327e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        bool mRet = mGetFrameResolution(inBuffer->pBuffer + inBuffer->nOffset, inBuffer->nFilledLen,
328e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            &mDecodedImageNewWidth,&mDecodedImageNewHeight);
329e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
330e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang        if (mRet && ((mDecodedImageNewWidth != 0) && (mDecodedImageNewHeight != 0)) &&
331e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            ((mDecodedImageWidth != 0) && (mDecodedImageHeight != 0)) &&
332e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            ((mDecodedImageNewWidth != mDecodedImageWidth || mDecodedImageNewHeight != mDecodedImageHeight))) {
333e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            if (mLastTimeStamp == 0) {
334e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
335e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                HandleFormatChange();
336e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                return OMX_ErrorNone;
337e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            } else {
338e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                // Detected format change in time.
339e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                // drain the last frame, keep the current input buffer
340e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                mDecoderDecode(mCtx, mHybridCtx, firstFrame, firstFrameSize, false);
341e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
342e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
343e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                mFormatChanged = true;
344e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
345e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX],
346e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                    eos ? OMX_BUFFERFLAG_EOS : 0, &isResolutionChange);
347e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
348e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                if (ret == OMX_ErrorNone)
349e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                    (*pBuffers[OUTPORT_INDEX])->nTimeStamp = mLastTimeStamp;
350e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
351e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                mLastTimeStamp = inBuffer->nTimeStamp;
352e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
353e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                free(firstFrame);
354e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                firstFrame = NULL;
355e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                firstFrameSize = 0;
356e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang                return ret;
357e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang            }
358ec2cc1a8775b1e613d527de22d423e12b5c56194Austin Hu        } else if (!mRet && (mDecodedImageNewWidth == 0 || mDecodedImageNewHeight == 0)) {
359ec2cc1a8775b1e613d527de22d423e12b5c56194Austin Hu            retains[INPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
360ec2cc1a8775b1e613d527de22d423e12b5c56194Austin Hu            return OMX_ErrorBadParameter;
361ec2cc1a8775b1e613d527de22d423e12b5c56194Austin Hu        }
362e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang    }
363e8e99de020ad4508f1db4d9fb3178a5f7a4fa974Xin Wang
364d05f9a0b79e3a07c9a868261debf4677e86af238ywan#if LOG_TIME == 1
365d05f9a0b79e3a07c9a868261debf4677e86af238ywan    struct timeval tv_start, tv_end;
366d05f9a0b79e3a07c9a868261debf4677e86af238ywan    int32_t time_ms;
367d05f9a0b79e3a07c9a868261debf4677e86af238ywan    gettimeofday(&tv_start,NULL);
368d05f9a0b79e3a07c9a868261debf4677e86af238ywan#endif
369c51d5398ac792d8ddd35d72322038305281b80edywan    int res = mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen, eos);
370c51d5398ac792d8ddd35d72322038305281b80edywan    if (res != 0) {
371c51d5398ac792d8ddd35d72322038305281b80edywan        if (res == -2) {
372c51d5398ac792d8ddd35d72322038305281b80edywan            if (isReallocateNeeded(inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen)) {
37394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                if (mAPMode == METADATA_MODE) {
37494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    mFormatChanged = true;
37594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                } else {
37694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
37794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    HandleFormatChange();
37894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                    return OMX_ErrorNone;
37994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi                }
380c51d5398ac792d8ddd35d72322038305281b80edywan            }
381c51d5398ac792d8ddd35d72322038305281b80edywan            // drain the last frame, keep the current input buffer
382c51d5398ac792d8ddd35d72322038305281b80edywan            res = mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
383c51d5398ac792d8ddd35d72322038305281b80edywan            retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
384c98025c07f77d5090fcb40a194d1966ede6c2ea7Austin Hu        } else if (res == -3) {
385c98025c07f77d5090fcb40a194d1966ede6c2ea7Austin Hu            LOGW("on2 decoder skipped to decode the frame.");
386c98025c07f77d5090fcb40a194d1966ede6c2ea7Austin Hu            (*pBuffers[OUTPORT_INDEX])->nOffset = 0;
387c98025c07f77d5090fcb40a194d1966ede6c2ea7Austin Hu            (*pBuffers[OUTPORT_INDEX])->nFilledLen = 0;
388c98025c07f77d5090fcb40a194d1966ede6c2ea7Austin Hu            return OMX_ErrorNone;
389c51d5398ac792d8ddd35d72322038305281b80edywan        } else {
390c51d5398ac792d8ddd35d72322038305281b80edywan            LOGE("on2 decoder failed to decode frame.");
391c51d5398ac792d8ddd35d72322038305281b80edywan            return OMX_ErrorBadParameter;
392c51d5398ac792d8ddd35d72322038305281b80edywan        }
393d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
394d05f9a0b79e3a07c9a868261debf4677e86af238ywan
395d05f9a0b79e3a07c9a868261debf4677e86af238ywan#if LOG_TIME == 1
396d05f9a0b79e3a07c9a868261debf4677e86af238ywan    gettimeofday(&tv_end,NULL);
397d05f9a0b79e3a07c9a868261debf4677e86af238ywan    time_ms = (int32_t)(tv_end.tv_sec - tv_start.tv_sec) * 1000 + (int32_t)(tv_end.tv_usec - tv_start.tv_usec)/1000;
398d05f9a0b79e3a07c9a868261debf4677e86af238ywan    LOGI("vpx_codec_decode: %d ms", time_ms);
399d05f9a0b79e3a07c9a868261debf4677e86af238ywan#endif
400d05f9a0b79e3a07c9a868261debf4677e86af238ywan
401d05f9a0b79e3a07c9a868261debf4677e86af238ywan    ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX],
402d05f9a0b79e3a07c9a868261debf4677e86af238ywan                           &retains[OUTPORT_INDEX],
4035246619dfe1807934867669347b846166a18977eywan                           eos? OMX_BUFFERFLAG_EOS:0,
4045246619dfe1807934867669347b846166a18977eywan                           &isResolutionChange);
405d05f9a0b79e3a07c9a868261debf4677e86af238ywan
406d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (ret == OMX_ErrorNone) {
4076725411e5c835fed1121f4ae9244013183f2ff38ywan        (*pBuffers[OUTPORT_INDEX])->nTimeStamp = mLastTimeStamp;
408d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
4096725411e5c835fed1121f4ae9244013183f2ff38ywan    mLastTimeStamp = inBuffer->nTimeStamp;
4105246619dfe1807934867669347b846166a18977eywan
4115246619dfe1807934867669347b846166a18977eywan    if (isResolutionChange == OMX_TRUE) {
4125246619dfe1807934867669347b846166a18977eywan        HandleFormatChange();
4135246619dfe1807934867669347b846166a18977eywan    }
414d05f9a0b79e3a07c9a868261debf4677e86af238ywan    bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
415d05f9a0b79e3a07c9a868261debf4677e86af238ywan    bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
416d05f9a0b79e3a07c9a868261debf4677e86af238ywan    // if output port is not eos, retain the input buffer
417d05f9a0b79e3a07c9a868261debf4677e86af238ywan    // until all the output buffers are drained.
4183b7c847ac11fe6d547346fc47b932ae0534425ccywan    if (inputEoS && !outputEoS && retains[INPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) {
419d05f9a0b79e3a07c9a868261debf4677e86af238ywan        retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
420d05f9a0b79e3a07c9a868261debf4677e86af238ywan        // the input buffer is retained for draining purpose.
421d05f9a0b79e3a07c9a868261debf4677e86af238ywan        // Set nFilledLen to 0 so buffer will not be decoded again.
422d05f9a0b79e3a07c9a868261debf4677e86af238ywan        (*pBuffers[INPORT_INDEX])->nFilledLen = 0;
423d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
424d05f9a0b79e3a07c9a868261debf4677e86af238ywan
425d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (ret == OMX_ErrorNotReady) {
426d05f9a0b79e3a07c9a868261debf4677e86af238ywan        retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
427d05f9a0b79e3a07c9a868261debf4677e86af238ywan        ret = OMX_ErrorNone;
428d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
429d05f9a0b79e3a07c9a868261debf4677e86af238ywan
430d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return ret;
431d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
432d05f9a0b79e3a07c9a868261debf4677e86af238ywan
433d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,
434d05f9a0b79e3a07c9a868261debf4677e86af238ywan                                                      buffer_retain_t *retain,
4355246619dfe1807934867669347b846166a18977eywan                                                      OMX_U32 inportBufferFlags,
4365246619dfe1807934867669347b846166a18977eywan                                                      OMX_BOOL *isResolutionChange)
437d05f9a0b79e3a07c9a868261debf4677e86af238ywan{
438d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_BUFFERHEADERTYPE *buffer = *pBuffer;
439d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_BUFFERHEADERTYPE *buffer_orign = buffer;
440d05f9a0b79e3a07c9a868261debf4677e86af238ywan
441d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_ERRORTYPE ret = OMX_ErrorNone;
442d05f9a0b79e3a07c9a868261debf4677e86af238ywan
44313c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    int fb_index;
44413c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    if (mWorkingMode == RAWDATA_MODE) {
44513c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput
44613c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan                       = this->ports[OUTPORT_INDEX]->GetPortDefinition();
44713c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        int32_t stride = paramPortDefinitionOutput->format.video.nStride;
44813c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        int32_t height =  paramPortDefinitionOutput->format.video.nFrameHeight;
44913c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        int32_t width = paramPortDefinitionOutput->format.video.nFrameWidth;
45013c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        unsigned char *dst = buffer->pBuffer;
45113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        fb_index = mGetRawDataOutput(mCtx,mHybridCtx,dst,height,stride);
45213c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        if (fb_index == -1) {
453d7a24953f38460360b0cbfc14145b4067f9ed02bywan            if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
454d7a24953f38460360b0cbfc14145b4067f9ed02bywan                // eos frame is non-shown frame
455d7a24953f38460360b0cbfc14145b4067f9ed02bywan                buffer->nFlags = OMX_BUFFERFLAG_EOS;
456d7a24953f38460360b0cbfc14145b4067f9ed02bywan                buffer->nOffset = 0;
457d7a24953f38460360b0cbfc14145b4067f9ed02bywan                buffer->nFilledLen = 0;
458d7a24953f38460360b0cbfc14145b4067f9ed02bywan                return OMX_ErrorNone;
459d7a24953f38460360b0cbfc14145b4067f9ed02bywan            }
4605246619dfe1807934867669347b846166a18977eywan            LOGV("vpx_codec_get_frame return NULL.");
46113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan            return OMX_ErrorNotReady;
46213c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        }
46313c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        buffer->nOffset = 0;
46413c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        buffer->nFilledLen = stride*height*3/2;
46513c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
46613c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan            buffer->nFlags = OMX_BUFFERFLAG_EOS;
46713c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        }
46813c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        return OMX_ErrorNone;
469d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
47013c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan
47194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    if (mFormatChanged && mAPMode == METADATA_MODE) {
47294dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        fb_index = mGetOutput(mCtx,mHybridCtx, &mDecodedImageWidth, &mDecodedImageHeight);
47394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    } else {
47494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        fb_index = mGetOutput(mCtx,mHybridCtx, &mDecodedImageNewWidth, &mDecodedImageNewHeight);
47594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    }
476d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (fb_index == -1) {
47794dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mFormatChanged && mAPMode == METADATA_MODE) {
47894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            *isResolutionChange = OMX_TRUE;
47994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            return OMX_ErrorNone;
48094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    }
48194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
482d7a24953f38460360b0cbfc14145b4067f9ed02bywan        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
483d7a24953f38460360b0cbfc14145b4067f9ed02bywan            // eos frame is no-shown frame
484d7a24953f38460360b0cbfc14145b4067f9ed02bywan            buffer->nFlags = OMX_BUFFERFLAG_EOS;
485d7a24953f38460360b0cbfc14145b4067f9ed02bywan            buffer->nOffset = 0;
486d7a24953f38460360b0cbfc14145b4067f9ed02bywan            buffer->nFilledLen = 0;
487d7a24953f38460360b0cbfc14145b4067f9ed02bywan            return OMX_ErrorNone;
488d7a24953f38460360b0cbfc14145b4067f9ed02bywan        }
4895246619dfe1807934867669347b846166a18977eywan        LOGV("vpx_codec_get_frame return NULL.");
490d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorNotReady;
491d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
4925246619dfe1807934867669347b846166a18977eywan    if (mDecodedImageHeight == 0 && mDecodedImageWidth == 0) {
4935246619dfe1807934867669347b846166a18977eywan        mDecodedImageWidth = mDecodedImageNewWidth;
4945246619dfe1807934867669347b846166a18977eywan        mDecodedImageHeight = mDecodedImageNewHeight;
49594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == LEGACY_MODE)
49694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            *isResolutionChange = OMX_TRUE;
4975246619dfe1807934867669347b846166a18977eywan    }
49894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi
49994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    if (mAPMode == LEGACY_MODE) {
5005246619dfe1807934867669347b846166a18977eywan    if ((mDecodedImageNewWidth != mDecodedImageWidth)
50194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        || (mDecodedImageNewHeight!= mDecodedImageHeight))
5025246619dfe1807934867669347b846166a18977eywan        *isResolutionChange = OMX_TRUE;
50394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    } else {
50494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mFormatChanged && ((mDecodedImageNewWidth != mDecodedImageWidth)
50594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            || (mDecodedImageNewHeight!= mDecodedImageHeight)))
50694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            *isResolutionChange = OMX_TRUE;
5075246619dfe1807934867669347b846166a18977eywan    }
508d05f9a0b79e3a07c9a868261debf4677e86af238ywan    buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[fb_index];
509d05f9a0b79e3a07c9a868261debf4677e86af238ywan    buffer->nOffset = 0;
510d05f9a0b79e3a07c9a868261debf4677e86af238ywan    buffer->nFilledLen = sizeof(OMX_U8*);
511d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
512d05f9a0b79e3a07c9a868261debf4677e86af238ywan        buffer->nFlags = OMX_BUFFERFLAG_EOS;
513d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
514d05f9a0b79e3a07c9a868261debf4677e86af238ywan
515d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (buffer_orign != buffer) {
516d05f9a0b79e3a07c9a868261debf4677e86af238ywan        *retain = BUFFER_RETAIN_OVERRIDDEN;
517d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
518d05f9a0b79e3a07c9a868261debf4677e86af238ywan
519d05f9a0b79e3a07c9a868261debf4677e86af238ywan    ret = OMX_ErrorNone;
520d05f9a0b79e3a07c9a868261debf4677e86af238ywan
521d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return ret;
522d05f9a0b79e3a07c9a868261debf4677e86af238ywan
523d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
524d05f9a0b79e3a07c9a868261debf4677e86af238ywan
525d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::PrepareConfigBuffer(VideoConfigBuffer *) {
526d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
527d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
528d05f9a0b79e3a07c9a868261debf4677e86af238ywan
529d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *,
530d05f9a0b79e3a07c9a868261debf4677e86af238ywan                                                         buffer_retain_t *,
531d05f9a0b79e3a07c9a868261debf4677e86af238ywan                                                         VideoDecodeBuffer *) {
532d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
533d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
534d05f9a0b79e3a07c9a868261debf4677e86af238ywan
535d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::BuildHandlerList(void) {
536d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMXVideoDecoderBase::BuildHandlerList();
537d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
538d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
539d05f9a0b79e3a07c9a868261debf4677e86af238ywan
540d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetParamVideoVp9(OMX_PTR) {
541d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
542d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
543d05f9a0b79e3a07c9a868261debf4677e86af238ywan
544d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetParamVideoVp9(OMX_PTR) {
545d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
546d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
547d05f9a0b79e3a07c9a868261debf4677e86af238ywan
5485246619dfe1807934867669347b846166a18977eywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::HandleFormatChange(void)
5495246619dfe1807934867669347b846166a18977eywan{
5507caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    ALOGE("handle format change from %dx%d to %dx%d",
551c51d5398ac792d8ddd35d72322038305281b80edywan        mDecodedImageWidth,mDecodedImageHeight,mDecodedImageNewWidth,mDecodedImageNewHeight);
5525246619dfe1807934867669347b846166a18977eywan    mDecodedImageWidth = mDecodedImageNewWidth;
5535246619dfe1807934867669347b846166a18977eywan    mDecodedImageHeight = mDecodedImageNewHeight;
5545246619dfe1807934867669347b846166a18977eywan    // Sync port definition as it may change.
5555246619dfe1807934867669347b846166a18977eywan    OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput;
5565246619dfe1807934867669347b846166a18977eywan
5575246619dfe1807934867669347b846166a18977eywan    memcpy(&paramPortDefinitionInput,
5585246619dfe1807934867669347b846166a18977eywan        this->ports[INPORT_INDEX]->GetPortDefinition(),
5595246619dfe1807934867669347b846166a18977eywan        sizeof(paramPortDefinitionInput));
5605246619dfe1807934867669347b846166a18977eywan
5615246619dfe1807934867669347b846166a18977eywan    memcpy(&paramPortDefinitionOutput,
5625246619dfe1807934867669347b846166a18977eywan        this->ports[OUTPORT_INDEX]->GetPortDefinition(),
5635246619dfe1807934867669347b846166a18977eywan        sizeof(paramPortDefinitionOutput));
5645246619dfe1807934867669347b846166a18977eywan
5655246619dfe1807934867669347b846166a18977eywan    unsigned int width = mDecodedImageWidth;
5665246619dfe1807934867669347b846166a18977eywan    unsigned int height = mDecodedImageHeight;
5675246619dfe1807934867669347b846166a18977eywan    unsigned int stride = mDecodedImageWidth;
5685246619dfe1807934867669347b846166a18977eywan    unsigned int sliceHeight = mDecodedImageHeight;
5695246619dfe1807934867669347b846166a18977eywan
5705246619dfe1807934867669347b846166a18977eywan    unsigned int widthCropped = mDecodedImageWidth;
5715246619dfe1807934867669347b846166a18977eywan    unsigned int heightCropped = mDecodedImageHeight;
5725246619dfe1807934867669347b846166a18977eywan    unsigned int strideCropped = widthCropped;
5735246619dfe1807934867669347b846166a18977eywan    unsigned int sliceHeightCropped = heightCropped;
5745246619dfe1807934867669347b846166a18977eywan
5755246619dfe1807934867669347b846166a18977eywan    if (widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
5765246619dfe1807934867669347b846166a18977eywan        heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
5775246619dfe1807934867669347b846166a18977eywan        if (mWorkingMode == RAWDATA_MODE) {
5785246619dfe1807934867669347b846166a18977eywan            LOGW("Change of portsetting is not reported as size is not changed.");
5795246619dfe1807934867669347b846166a18977eywan            return OMX_ErrorNone;
5805246619dfe1807934867669347b846166a18977eywan        }
5815246619dfe1807934867669347b846166a18977eywan    }
5825246619dfe1807934867669347b846166a18977eywan
58394dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    if (mAPMode == METADATA_MODE) {
58494dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi       paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount;
58594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi       paramPortDefinitionOutput.nBufferCountMin = mNativeBufferCount - 4;
58694dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    }
5875246619dfe1807934867669347b846166a18977eywan    paramPortDefinitionInput.format.video.nFrameWidth = width;
5885246619dfe1807934867669347b846166a18977eywan    paramPortDefinitionInput.format.video.nFrameHeight = height;
5895246619dfe1807934867669347b846166a18977eywan    paramPortDefinitionInput.format.video.nStride = stride;
5905246619dfe1807934867669347b846166a18977eywan    paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
5915246619dfe1807934867669347b846166a18977eywan
5925246619dfe1807934867669347b846166a18977eywan    if (mWorkingMode == RAWDATA_MODE) {
5935246619dfe1807934867669347b846166a18977eywan        paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped;
5945246619dfe1807934867669347b846166a18977eywan        paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped;
5955246619dfe1807934867669347b846166a18977eywan        paramPortDefinitionOutput.format.video.nStride = strideCropped;
5965246619dfe1807934867669347b846166a18977eywan        paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped;
5975246619dfe1807934867669347b846166a18977eywan    } else if (mWorkingMode == GRAPHICBUFFER_MODE) {
5985246619dfe1807934867669347b846166a18977eywan        // when the width and height ES parse are not larger than allocated graphic buffer in outport,
5995246619dfe1807934867669347b846166a18977eywan        // there is no need to reallocate graphic buffer,just report the crop info to omx client
60094dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == LEGACY_MODE &&
60194dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            width <= mGraphicBufferParam.graphicBufferWidth &&
6025246619dfe1807934867669347b846166a18977eywan            height <= mGraphicBufferParam.graphicBufferHeight) {
6035246619dfe1807934867669347b846166a18977eywan            this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
6045246619dfe1807934867669347b846166a18977eywan            this->ports[OUTPORT_INDEX]->ReportOutputCrop();
6055246619dfe1807934867669347b846166a18977eywan            return OMX_ErrorNone;
6065246619dfe1807934867669347b846166a18977eywan        }
6075246619dfe1807934867669347b846166a18977eywan
60894dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi        if (mAPMode == METADATA_MODE ||
60994dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi            width > mGraphicBufferParam.graphicBufferWidth ||
6105246619dfe1807934867669347b846166a18977eywan            height > mGraphicBufferParam.graphicBufferHeight) {
6115246619dfe1807934867669347b846166a18977eywan            // update the real decoded resolution to outport instead of display resolution
6125246619dfe1807934867669347b846166a18977eywan            // for graphic buffer reallocation
6135246619dfe1807934867669347b846166a18977eywan            // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
6145246619dfe1807934867669347b846166a18977eywan            paramPortDefinitionOutput.format.video.nFrameWidth = width;
6157caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan            paramPortDefinitionOutput.format.video.nFrameHeight = height;
6165246619dfe1807934867669347b846166a18977eywan            paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
6175246619dfe1807934867669347b846166a18977eywan                    paramPortDefinitionOutput.format.video.nFrameWidth);
6185246619dfe1807934867669347b846166a18977eywan            paramPortDefinitionOutput.format.video.nStride = stride;
6195246619dfe1807934867669347b846166a18977eywan            paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
6205246619dfe1807934867669347b846166a18977eywan       }
6215246619dfe1807934867669347b846166a18977eywan    }
6225246619dfe1807934867669347b846166a18977eywan
6235246619dfe1807934867669347b846166a18977eywan    paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
6245246619dfe1807934867669347b846166a18977eywan    mOMXBufferHeaderTypePtrNum = 0;
62594dc18063f6f0f60d99feaa0ffb1fc103d49c2c8Gu, Wangyi    mMetaDataBuffersNum = 0;
6265246619dfe1807934867669347b846166a18977eywan    memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
627c51d5398ac792d8ddd35d72322038305281b80edywan    mDeinitDecoder(mHybridCtx);
6285246619dfe1807934867669347b846166a18977eywan
6295246619dfe1807934867669347b846166a18977eywan    this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
6305246619dfe1807934867669347b846166a18977eywan    this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
6315246619dfe1807934867669347b846166a18977eywan
6325246619dfe1807934867669347b846166a18977eywan    this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
6335246619dfe1807934867669347b846166a18977eywan    return OMX_ErrorNone;
6345246619dfe1807934867669347b846166a18977eywan}
6355246619dfe1807934867669347b846166a18977eywan
6365246619dfe1807934867669347b846166a18977eywan
637d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_COLOR_FORMATTYPE OMXVideoDecoderVP9Hybrid::GetOutputColorFormat(int) {
638b7296e7f47467d3689c182b7c0c94d623a41f187Austin Hu    LOGV("Output color format is HAL_PIXEL_FORMAT_INTEL_YV12.");
639b7296e7f47467d3689c182b7c0c94d623a41f187Austin Hu    return (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_INTEL_YV12;
640d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
641d05f9a0b79e3a07c9a868261debf4677e86af238ywan
642d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetDecoderOutputCropSpecific(OMX_PTR pStructure) {
643d05f9a0b79e3a07c9a868261debf4677e86af238ywan
644d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_ERRORTYPE ret = OMX_ErrorNone;
645d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure;
646d05f9a0b79e3a07c9a868261debf4677e86af238ywan
647d05f9a0b79e3a07c9a868261debf4677e86af238ywan    CHECK_TYPE_HEADER(rectParams);
648d05f9a0b79e3a07c9a868261debf4677e86af238ywan
649d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (rectParams->nPortIndex != OUTPORT_INDEX) {
650d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorUndefined;
651d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
652d05f9a0b79e3a07c9a868261debf4677e86af238ywan
653d05f9a0b79e3a07c9a868261debf4677e86af238ywan    const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput
654d05f9a0b79e3a07c9a868261debf4677e86af238ywan                                      = this->ports[INPORT_INDEX]->GetPortDefinition();
655d05f9a0b79e3a07c9a868261debf4677e86af238ywan
656d05f9a0b79e3a07c9a868261debf4677e86af238ywan    rectParams->nLeft = VPX_DECODE_BORDER;
657d05f9a0b79e3a07c9a868261debf4677e86af238ywan    rectParams->nTop = VPX_DECODE_BORDER;
658d05f9a0b79e3a07c9a868261debf4677e86af238ywan    rectParams->nWidth = paramPortDefinitionInput->format.video.nFrameWidth;
659d05f9a0b79e3a07c9a868261debf4677e86af238ywan    rectParams->nHeight = paramPortDefinitionInput->format.video.nFrameHeight;
660d05f9a0b79e3a07c9a868261debf4677e86af238ywan
661d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return ret;
662d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
663d05f9a0b79e3a07c9a868261debf4677e86af238ywan
664d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetNativeBufferUsageSpecific(OMX_PTR pStructure) {
665d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_ERRORTYPE ret;
666d05f9a0b79e3a07c9a868261debf4677e86af238ywan    android::GetAndroidNativeBufferUsageParams *param =
667d05f9a0b79e3a07c9a868261debf4677e86af238ywan        (android::GetAndroidNativeBufferUsageParams*)pStructure;
668d05f9a0b79e3a07c9a868261debf4677e86af238ywan    CHECK_TYPE_HEADER(param);
669d05f9a0b79e3a07c9a868261debf4677e86af238ywan
6704f61fb9367fcc5b11b54fd9e3337c21339dd3c99Dale Stimson    param->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN
671d05f9a0b79e3a07c9a868261debf4677e86af238ywan                     | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_EXTERNAL_DISP);
672d05f9a0b79e3a07c9a868261debf4677e86af238ywan    return OMX_ErrorNone;
673d05f9a0b79e3a07c9a868261debf4677e86af238ywan
674d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
675d05f9a0b79e3a07c9a868261debf4677e86af238ywanOMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetNativeBufferModeSpecific(OMX_PTR pStructure) {
676d05f9a0b79e3a07c9a868261debf4677e86af238ywan    OMX_ERRORTYPE ret;
677d05f9a0b79e3a07c9a868261debf4677e86af238ywan    android::EnableAndroidNativeBuffersParams *param =
678d05f9a0b79e3a07c9a868261debf4677e86af238ywan        (android::EnableAndroidNativeBuffersParams*)pStructure;
679d05f9a0b79e3a07c9a868261debf4677e86af238ywan
680d05f9a0b79e3a07c9a868261debf4677e86af238ywan    CHECK_TYPE_HEADER(param);
681d05f9a0b79e3a07c9a868261debf4677e86af238ywan    CHECK_PORT_INDEX_RANGE(param);
682d05f9a0b79e3a07c9a868261debf4677e86af238ywan    CHECK_SET_PARAM_STATE();
683d05f9a0b79e3a07c9a868261debf4677e86af238ywan
6840003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang    PortVideo *port = NULL;
6850003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang    port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
6860003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang    OMX_PARAM_PORTDEFINITIONTYPE port_def;
6870003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang    memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
6880003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang
689d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (!param->enable) {
690d05f9a0b79e3a07c9a868261debf4677e86af238ywan        mWorkingMode = RAWDATA_MODE;
69113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan        LOGI("Raw data mode is used");
6920003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        // If it is fallback from native mode the color format has been
6930003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        // already set to INTEL format.
6940003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        // We need to set back the default color format and Native stuff.
6950003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
6960003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        port_def.format.video.pNativeRender = NULL;
6970003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        port_def.format.video.pNativeWindow = NULL;
6980003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang        port->SetPortDefinition(&port_def,true);
699d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return OMX_ErrorNone;
700d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
701d05f9a0b79e3a07c9a868261debf4677e86af238ywan
7020003e4db29ee2b7cfc7546a7e847303b4b8fb81eXin Wang    mWorkingMode = GRAPHICBUFFER_MODE;
7035246619dfe1807934867669347b846166a18977eywan    port_def.nBufferCountMin = mNativeBufferCount - 4;
704d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port_def.nBufferCountActual = mNativeBufferCount;
705d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
706d05f9a0b79e3a07c9a868261debf4677e86af238ywan    // add borders for libvpx decode need.
707d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port_def.format.video.nFrameWidth += VPX_DECODE_BORDER * 2;
7087caaf88cf45abd06d6c8d99b40bf5cb8c0fbc0ffAlistair Strachan    port_def.format.video.nFrameHeight += VPX_DECODE_BORDER * 2;
709c51d5398ac792d8ddd35d72322038305281b80edywan    mDecodedImageWidth = port_def.format.video.nFrameWidth;
710c51d5398ac792d8ddd35d72322038305281b80edywan    mDecodedImageHeight = port_def.format.video.nFrameHeight;
711d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port_def.format.video.eColorFormat = GetOutputColorFormat(port_def.format.video.nFrameWidth);
712d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port->SetPortDefinition(&port_def,true);
713d05f9a0b79e3a07c9a868261debf4677e86af238ywan
714d05f9a0b79e3a07c9a868261debf4677e86af238ywan     return OMX_ErrorNone;
715d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
716d05f9a0b79e3a07c9a868261debf4677e86af238ywan
717d05f9a0b79e3a07c9a868261debf4677e86af238ywan
718d05f9a0b79e3a07c9a868261debf4677e86af238ywanbool OMXVideoDecoderVP9Hybrid::IsAllBufferAvailable(void) {
719d05f9a0b79e3a07c9a868261debf4677e86af238ywan    bool b = ComponentBase::IsAllBufferAvailable();
720d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (b == false) {
721d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return false;
722d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
723d05f9a0b79e3a07c9a868261debf4677e86af238ywan
724d05f9a0b79e3a07c9a868261debf4677e86af238ywan    PortVideo *port = NULL;
725d05f9a0b79e3a07c9a868261debf4677e86af238ywan    port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
726d05f9a0b79e3a07c9a868261debf4677e86af238ywan    const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition();
727d05f9a0b79e3a07c9a868261debf4677e86af238ywan     // if output port is disabled, retain the input buffer
728d05f9a0b79e3a07c9a868261debf4677e86af238ywan    if (!port_def->bEnabled) {
729d05f9a0b79e3a07c9a868261debf4677e86af238ywan        return false;
730d05f9a0b79e3a07c9a868261debf4677e86af238ywan    }
73113c7df7e879f64e0055bbcc61dbe0d472ac8d43bywan    return mCheckBufferAvailable(mHybridCtx);
732d05f9a0b79e3a07c9a868261debf4677e86af238ywan}
733d05f9a0b79e3a07c9a868261debf4677e86af238ywan
73411c1c17fed35585f9256031ee70db1c6c18d0219Yuanjun HuangDECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.VP9.hybrid", "video_decoder.vp9", OMXVideoDecoderVP9Hybrid);
735