1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/*
2233d2500723e5594f3e7c70896ffeeef32b9c950ywan* Copyright (c) 2012 Intel Corporation.  All rights reserved.
3233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
4233d2500723e5594f3e7c70896ffeeef32b9c950ywan* Licensed under the Apache License, Version 2.0 (the "License");
5233d2500723e5594f3e7c70896ffeeef32b9c950ywan* you may not use this file except in compliance with the License.
6233d2500723e5594f3e7c70896ffeeef32b9c950ywan* You may obtain a copy of the License at
7233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
8233d2500723e5594f3e7c70896ffeeef32b9c950ywan* http://www.apache.org/licenses/LICENSE-2.0
9233d2500723e5594f3e7c70896ffeeef32b9c950ywan*
10233d2500723e5594f3e7c70896ffeeef32b9c950ywan* Unless required by applicable law or agreed to in writing, software
11233d2500723e5594f3e7c70896ffeeef32b9c950ywan* distributed under the License is distributed on an "AS IS" BASIS,
12233d2500723e5594f3e7c70896ffeeef32b9c950ywan* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13233d2500723e5594f3e7c70896ffeeef32b9c950ywan* See the License for the specific language governing permissions and
14233d2500723e5594f3e7c70896ffeeef32b9c950ywan* limitations under the License.
15233d2500723e5594f3e7c70896ffeeef32b9c950ywan*/
16233d2500723e5594f3e7c70896ffeeef32b9c950ywan
17233d2500723e5594f3e7c70896ffeeef32b9c950ywan
18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LOG_NDEBUG 0
19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LOG_TAG "OMXVideoDecoderVP9HWR"
20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <wrs_omxil_core/log.h>
21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "OMXVideoDecoderVP9HWR.h"
22233d2500723e5594f3e7c70896ffeeef32b9c950ywan
23233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <system/window.h>
24233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <HardwareAPI.h>
25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <hardware/hardware.h>
26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <hardware/gralloc.h>
27233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <system/graphics.h>
28233d2500723e5594f3e7c70896ffeeef32b9c950ywan
29233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic const char* VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
30233d2500723e5594f3e7c70896ffeeef32b9c950ywan
31233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int GetCPUCoreCount()
32233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
33233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int cpuCoreCount = 1;
34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#if defined(_SC_NPROCESSORS_ONLN)
35233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
36233d2500723e5594f3e7c70896ffeeef32b9c950ywan#else
37233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // _SC_NPROC_ONLN must be defined...
38233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cpuCoreCount = sysconf(_SC_NPROC_ONLN);
39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
40233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (cpuCoreCount < 1) {
41233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGW("Get CPU Core Count error.");
42233d2500723e5594f3e7c70896ffeeef32b9c950ywan        cpuCoreCount = 1;
43233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
44233d2500723e5594f3e7c70896ffeeef32b9c950ywan    LOGV("Number of CPU cores: %d", cpuCoreCount);
45233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return cpuCoreCount;
46233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
47233d2500723e5594f3e7c70896ffeeef32b9c950ywan
48233d2500723e5594f3e7c70896ffeeef32b9c950ywan
49233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMXVideoDecoderVP9HWR::OMXVideoDecoderVP9HWR()
50233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
51233d2500723e5594f3e7c70896ffeeef32b9c950ywan    LOGV("OMXVideoDecoderVP9HWR is constructed.");
52233d2500723e5594f3e7c70896ffeeef32b9c950ywan
53233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mNumFrameBuffer = 0;
54233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mCtx = NULL;
55233d2500723e5594f3e7c70896ffeeef32b9c950ywan
56233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT;
57233d2500723e5594f3e7c70896ffeeef32b9c950ywan    extUtilBufferCount = 0;
58233d2500723e5594f3e7c70896ffeeef32b9c950ywan    extMappedNativeBufferCount = 0;
59233d2500723e5594f3e7c70896ffeeef32b9c950ywan    BuildHandlerList();
60233d2500723e5594f3e7c70896ffeeef32b9c950ywan
61233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageWidth = 0;
62233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageHeight = 0;
63233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageNewWidth = 0;
64233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageNewHeight = 0;
65233d2500723e5594f3e7c70896ffeeef32b9c950ywan
66233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef DECODE_WITH_GRALLOC_BUFFER
67233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // setup va
68233d2500723e5594f3e7c70896ffeeef32b9c950ywan    VAStatus vaStatus = VA_STATUS_SUCCESS;
69233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDisplay = new Display;
70233d2500723e5594f3e7c70896ffeeef32b9c950ywan    *mDisplay = ANDROID_DISPLAY_HANDLE;
71233d2500723e5594f3e7c70896ffeeef32b9c950ywan
72233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mVADisplay = vaGetDisplay(mDisplay);
73233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mVADisplay == NULL) {
74233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("vaGetDisplay failed.");
75233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
76233d2500723e5594f3e7c70896ffeeef32b9c950ywan
77233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int majorVersion, minorVersion;
78233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
79233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vaStatus != VA_STATUS_SUCCESS) {
80233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("vaInitialize failed.");
81233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
82233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGV("va majorVersion=%d, minorVersion=%d", majorVersion, minorVersion);
83233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
84233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
85233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
86233d2500723e5594f3e7c70896ffeeef32b9c950ywan
87233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMXVideoDecoderVP9HWR::~OMXVideoDecoderVP9HWR()
88233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
89233d2500723e5594f3e7c70896ffeeef32b9c950ywan    LOGV("OMXVideoDecoderVP9HWR is destructed.");
90233d2500723e5594f3e7c70896ffeeef32b9c950ywan
91233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int i = 0;
92233d2500723e5594f3e7c70896ffeeef32b9c950ywan
93233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mVADisplay) {
94233d2500723e5594f3e7c70896ffeeef32b9c950ywan        vaTerminate(mVADisplay);
95233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mVADisplay = NULL;
96233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
97233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
98233d2500723e5594f3e7c70896ffeeef32b9c950ywan
99233d2500723e5594f3e7c70896ffeeef32b9c950ywan
100233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Callback func for vpx decoder to get decode buffer
101233d2500723e5594f3e7c70896ffeeef32b9c950ywan// Now we map from the vaSurface to deploy gralloc buffer
102233d2500723e5594f3e7c70896ffeeef32b9c950ywan// as decode buffer
103233d2500723e5594f3e7c70896ffeeef32b9c950ywanint getVP9FrameBuffer(void *user_priv,
104233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          unsigned int new_size,
105233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          vpx_codec_frame_buffer_t *fb)
106233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
107aa97fcc905746a68487a0122736c2d373bb81f4eywan    OMXVideoDecoderVP9HWR * p = (OMXVideoDecoderVP9HWR *)user_priv;
108233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (fb == NULL) {
109233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return -1;
110233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
111233d2500723e5594f3e7c70896ffeeef32b9c950ywan
112233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // TODO: Adaptive playback case needs to reconsider
113aa97fcc905746a68487a0122736c2d373bb81f4eywan    if (p->extNativeBufferSize < new_size) {
114233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("Provided frame buffer size < requesting min size.");
115233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return -1;
116233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
117233d2500723e5594f3e7c70896ffeeef32b9c950ywan
118233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
119aa97fcc905746a68487a0122736c2d373bb81f4eywan    for (i = 0; i < p->extMappedNativeBufferCount; i++ ) {
120aa97fcc905746a68487a0122736c2d373bb81f4eywan        if ((p->extMIDs[i]->m_render_done == true) &&
121aa97fcc905746a68487a0122736c2d373bb81f4eywan            (p->extMIDs[i]->m_released == true)) {
122aa97fcc905746a68487a0122736c2d373bb81f4eywan            fb->data = p->extMIDs[i]->m_usrAddr;
123aa97fcc905746a68487a0122736c2d373bb81f4eywan            fb->size = p->extNativeBufferSize;
124aa97fcc905746a68487a0122736c2d373bb81f4eywan            fb->fb_stride = p->extActualBufferStride;
125aa97fcc905746a68487a0122736c2d373bb81f4eywan            fb->fb_height_stride = p->extActualBufferHeightStride;
126233d2500723e5594f3e7c70896ffeeef32b9c950ywan            fb->fb_index = i;
127aa97fcc905746a68487a0122736c2d373bb81f4eywan            p->extMIDs[i]->m_released = false;
128233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
129233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
130233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
131233d2500723e5594f3e7c70896ffeeef32b9c950ywan
132aa97fcc905746a68487a0122736c2d373bb81f4eywan    if (i == p->extMappedNativeBufferCount) {
133233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("No available frame buffer in pool.");
134233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return -1;
135233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
136233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
137233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
138233d2500723e5594f3e7c70896ffeeef32b9c950ywan
139233d2500723e5594f3e7c70896ffeeef32b9c950ywan// call back function from libvpx to inform frame buffer
140233d2500723e5594f3e7c70896ffeeef32b9c950ywan// not used anymore.
141233d2500723e5594f3e7c70896ffeeef32b9c950ywanint releaseVP9FrameBuffer(void *user_priv, vpx_codec_frame_buffer_t *fb)
142233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
143233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int i;
144aa97fcc905746a68487a0122736c2d373bb81f4eywan    OMXVideoDecoderVP9HWR * p = (OMXVideoDecoderVP9HWR *)user_priv;
145233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (fb == NULL) {
146233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return -1;
147233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
148aa97fcc905746a68487a0122736c2d373bb81f4eywan    for (i = 0; i < p->extMappedNativeBufferCount; i++ ) {
149aa97fcc905746a68487a0122736c2d373bb81f4eywan        if (fb->data == p->extMIDs[i]->m_usrAddr) {
150aa97fcc905746a68487a0122736c2d373bb81f4eywan            p->extMIDs[i]->m_released = true;
151233d2500723e5594f3e7c70896ffeeef32b9c950ywan            break;
152233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
153233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
154233d2500723e5594f3e7c70896ffeeef32b9c950ywan
155aa97fcc905746a68487a0122736c2d373bb81f4eywan    if (i == p->extMappedNativeBufferCount) {
156233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("Not found matching frame buffer in pool, libvpx's wrong?");
157233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return -1;
158233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
159233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return 0;
160233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
161233d2500723e5594f3e7c70896ffeeef32b9c950ywan
162233d2500723e5594f3e7c70896ffeeef32b9c950ywan
163233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::initDecoder()
164233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
165233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mCtx = new vpx_codec_ctx_t;
166233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_codec_err_t vpx_err;
167233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_codec_dec_cfg_t cfg;
168233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t));
169233d2500723e5594f3e7c70896ffeeef32b9c950ywan    cfg.threads = GetCPUCoreCount();
170233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if ((vpx_err = vpx_codec_dec_init(
171233d2500723e5594f3e7c70896ffeeef32b9c950ywan                (vpx_codec_ctx_t *)mCtx,
172233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 &vpx_codec_vp9_dx_algo,
173233d2500723e5594f3e7c70896ffeeef32b9c950ywan                 &cfg, 0))) {
174233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("on2 decoder failed to initialize. (%d)", vpx_err);
175233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorNotReady;
176233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
177233d2500723e5594f3e7c70896ffeeef32b9c950ywan
178233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mNumFrameBuffer = OUTPORT_NATIVE_BUFFER_COUNT;
179233d2500723e5594f3e7c70896ffeeef32b9c950ywan
180233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vpx_codec_set_frame_buffer_functions((vpx_codec_ctx_t *)mCtx,
181233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    getVP9FrameBuffer,
182233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    releaseVP9FrameBuffer,
183aa97fcc905746a68487a0122736c2d373bb81f4eywan                                    this)) {
184233d2500723e5594f3e7c70896ffeeef32b9c950ywan      LOGE("Failed to configure external frame buffers");
185233d2500723e5594f3e7c70896ffeeef32b9c950ywan      return OMX_ErrorNotReady;
186233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
187233d2500723e5594f3e7c70896ffeeef32b9c950ywan
188233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
189233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
190233d2500723e5594f3e7c70896ffeeef32b9c950ywan
191233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::destroyDecoder()
192233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
193233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_codec_destroy((vpx_codec_ctx_t *)mCtx);
194233d2500723e5594f3e7c70896ffeeef32b9c950ywan    delete (vpx_codec_ctx_t *)mCtx;
195233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mCtx = NULL;
196233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
197233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
198233d2500723e5594f3e7c70896ffeeef32b9c950ywan
199233d2500723e5594f3e7c70896ffeeef32b9c950ywan
200233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::InitInputPortFormatSpecific(
201233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput)
202233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
203233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
204233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
205233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE;
206233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)VP9_MIME_TYPE;
207233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
208233d2500723e5594f3e7c70896ffeeef32b9c950ywan
209233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
210233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
211233d2500723e5594f3e7c70896ffeeef32b9c950ywan
212233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorInit(void)
213233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
214233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int i = 0;
215233d2500723e5594f3e7c70896ffeeef32b9c950ywan
216233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < MAX_NATIVE_BUFFER_COUNT; i++) {
217233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i] = (vaapiMemId*)malloc(sizeof(vaapiMemId));
218233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i]->m_usrAddr = NULL;
219233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i]->m_surface = new VASurfaceID;
220233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
221233d2500723e5594f3e7c70896ffeeef32b9c950ywan
222233d2500723e5594f3e7c70896ffeeef32b9c950ywan    initDecoder();
223233d2500723e5594f3e7c70896ffeeef32b9c950ywan
224233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (RAWDATA_MODE == mWorkingMode) {
225233d2500723e5594f3e7c70896ffeeef32b9c950ywan        OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
226233d2500723e5594f3e7c70896ffeeef32b9c950ywan
227233d2500723e5594f3e7c70896ffeeef32b9c950ywan        memcpy(&paramPortDefinitionInput,
228233d2500723e5594f3e7c70896ffeeef32b9c950ywan               this->ports[INPORT_INDEX]->GetPortDefinition(),
229233d2500723e5594f3e7c70896ffeeef32b9c950ywan               sizeof(paramPortDefinitionInput));
230233d2500723e5594f3e7c70896ffeeef32b9c950ywan
231233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extNativeBufferSize = INTERNAL_MAX_FRAME_WIDTH *
232233d2500723e5594f3e7c70896ffeeef32b9c950ywan                              INTERNAL_MAX_FRAME_HEIGHT * 1.5;
233233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extActualBufferStride = INTERNAL_MAX_FRAME_WIDTH;
234233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extActualBufferHeightStride = INTERNAL_MAX_FRAME_HEIGHT;
235233d2500723e5594f3e7c70896ffeeef32b9c950ywan
236233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < OUTPORT_ACTUAL_BUFFER_COUNT; i++ ) {
237233d2500723e5594f3e7c70896ffeeef32b9c950ywan            extMIDs[i]->m_usrAddr = (unsigned char*)malloc(sizeof(unsigned char) *
238233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                    extNativeBufferSize);
239233d2500723e5594f3e7c70896ffeeef32b9c950ywan            extMIDs[i]->m_render_done = true;
240233d2500723e5594f3e7c70896ffeeef32b9c950ywan            extMIDs[i]->m_released = true;
241233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
242233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMappedNativeBufferCount = OUTPORT_ACTUAL_BUFFER_COUNT;
243233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorNone;
244233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
245233d2500723e5594f3e7c70896ffeeef32b9c950ywan
246233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef DECODE_WITH_GRALLOC_BUFFER
247233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mOMXBufferHeaderTypePtrNum > MAX_NATIVE_BUFFER_COUNT) {
248233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("Actual OMX outport buffer header type num (%d) > MAX_NATIVE_BUFFER_COUNT (%d)",
249233d2500723e5594f3e7c70896ffeeef32b9c950ywan              mOMXBufferHeaderTypePtrNum, MAX_NATIVE_BUFFER_COUNT);
250233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorOverflow;
251233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
252233d2500723e5594f3e7c70896ffeeef32b9c950ywan
253233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput;
254233d2500723e5594f3e7c70896ffeeef32b9c950ywan
255233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memcpy(&paramPortDefinitionInput,
256233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this->ports[INPORT_INDEX]->GetPortDefinition(),
257233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sizeof(paramPortDefinitionInput));
258233d2500723e5594f3e7c70896ffeeef32b9c950ywan
259233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int surfaceWidth = mGraphicBufferParam.graphicBufferWidth;
260233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int surfaceHeight = mGraphicBufferParam.graphicBufferHeight;
261233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int surfaceStride = mGraphicBufferParam.graphicBufferStride;
262233d2500723e5594f3e7c70896ffeeef32b9c950ywan    extNativeBufferSize = mGraphicBufferParam.graphicBufferStride *
263233d2500723e5594f3e7c70896ffeeef32b9c950ywan                          mGraphicBufferParam.graphicBufferHeight * 1.5;
264233d2500723e5594f3e7c70896ffeeef32b9c950ywan    extActualBufferStride = surfaceStride;
265233d2500723e5594f3e7c70896ffeeef32b9c950ywan    extActualBufferHeightStride = surfaceHeight;
266233d2500723e5594f3e7c70896ffeeef32b9c950ywan
267233d2500723e5594f3e7c70896ffeeef32b9c950ywan    for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
268233d2500723e5594f3e7c70896ffeeef32b9c950ywan        OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
269233d2500723e5594f3e7c70896ffeeef32b9c950ywan
270233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i]->m_key = (unsigned int)(buf_hdr->pBuffer);
271233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i]->m_render_done = false;
272233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[i]->m_released = true;
273233d2500723e5594f3e7c70896ffeeef32b9c950ywan
274233d2500723e5594f3e7c70896ffeeef32b9c950ywan        VAStatus va_res;
275233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned int buffer;
276233d2500723e5594f3e7c70896ffeeef32b9c950ywan        VASurfaceAttrib attribs[2];
277233d2500723e5594f3e7c70896ffeeef32b9c950ywan        VASurfaceAttribExternalBuffers* surfExtBuf = new VASurfaceAttribExternalBuffers;
278233d2500723e5594f3e7c70896ffeeef32b9c950ywan        int32_t format = VA_RT_FORMAT_YUV420;
279233d2500723e5594f3e7c70896ffeeef32b9c950ywan
280233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->buffers= (unsigned long *)&buffer;
281233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->num_buffers = 1;
282233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->pixel_format = VA_FOURCC_NV12;
283233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->width = surfaceWidth;
284233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->height = surfaceHeight;
285233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->data_size = surfaceStride * surfaceHeight * 1.5;
286233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->num_planes = 2;
287233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->pitches[0] = surfaceStride;
288233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->pitches[1] = surfaceStride;
289233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->pitches[2] = 0;
290233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->pitches[3] = 0;
291233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->offsets[0] = 0;
292233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->offsets[1] = surfaceStride * surfaceHeight;
293233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->offsets[2] = 0;
294233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->offsets[3] = 0;
295233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->flags = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
296233d2500723e5594f3e7c70896ffeeef32b9c950ywan
297233d2500723e5594f3e7c70896ffeeef32b9c950ywan        surfExtBuf->buffers[0] = (unsigned int)buf_hdr->pBuffer;
298233d2500723e5594f3e7c70896ffeeef32b9c950ywan
299233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
300233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
301233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[0].value.type = VAGenericValueTypeInteger;
302233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
303233d2500723e5594f3e7c70896ffeeef32b9c950ywan
304233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
305233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
306233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[1].value.type = VAGenericValueTypePointer;
307233d2500723e5594f3e7c70896ffeeef32b9c950ywan        attribs[1].value.value.p = (void *)surfExtBuf;
308233d2500723e5594f3e7c70896ffeeef32b9c950ywan
309233d2500723e5594f3e7c70896ffeeef32b9c950ywan        va_res = vaCreateSurfaces(mVADisplay,
310233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  format,
311233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  surfaceWidth,
312233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  surfaceHeight,
313233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  extMIDs[i]->m_surface,
314233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  1,
315233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  attribs,
316233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                  2);
317233d2500723e5594f3e7c70896ffeeef32b9c950ywan
318233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (va_res != VA_STATUS_SUCCESS) {
319233d2500723e5594f3e7c70896ffeeef32b9c950ywan            LOGE("Failed to create vaSurface!");
320233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorUndefined;
321233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
322233d2500723e5594f3e7c70896ffeeef32b9c950ywan
323233d2500723e5594f3e7c70896ffeeef32b9c950ywan        delete surfExtBuf;
324233d2500723e5594f3e7c70896ffeeef32b9c950ywan
325233d2500723e5594f3e7c70896ffeeef32b9c950ywan        VAImage image;
326233d2500723e5594f3e7c70896ffeeef32b9c950ywan        unsigned char* usrptr;
327233d2500723e5594f3e7c70896ffeeef32b9c950ywan
328233d2500723e5594f3e7c70896ffeeef32b9c950ywan        va_res = vaDeriveImage(mVADisplay, *(extMIDs[i]->m_surface), &image);
329233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (VA_STATUS_SUCCESS == va_res) {
330233d2500723e5594f3e7c70896ffeeef32b9c950ywan            va_res = vaMapBuffer(mVADisplay, image.buf, (void **) &usrptr);
331233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (VA_STATUS_SUCCESS == va_res) {
332233d2500723e5594f3e7c70896ffeeef32b9c950ywan                extMIDs[i]->m_usrAddr = usrptr;
333233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vaUnmapBuffer(mVADisplay, image.buf);
334233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
335233d2500723e5594f3e7c70896ffeeef32b9c950ywan            vaDestroyImage(mVADisplay, image.image_id);
336233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
337233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMappedNativeBufferCount++;
338233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
339233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
340233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
341233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
342233d2500723e5594f3e7c70896ffeeef32b9c950ywan
343233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorDeinit(void)
344233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
345233d2500723e5594f3e7c70896ffeeef32b9c950ywan    destroyDecoder();
346233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int i = 0;
347233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mWorkingMode == GRAPHICBUFFER_MODE) {
348233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
349233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (extMIDs[i]->m_surface != NULL) {
350233d2500723e5594f3e7c70896ffeeef32b9c950ywan                vaDestroySurfaces(mVADisplay, extMIDs[i]->m_surface, 1);
351233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
352233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
353233d2500723e5594f3e7c70896ffeeef32b9c950ywan
354233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (mWorkingMode == RAWDATA_MODE) {
355233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < OUTPORT_ACTUAL_BUFFER_COUNT; i++ ) {
356233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (extMIDs[i]->m_usrAddr != NULL) {
357233d2500723e5594f3e7c70896ffeeef32b9c950ywan                free(extMIDs[i]->m_usrAddr);
358233d2500723e5594f3e7c70896ffeeef32b9c950ywan                extMIDs[i]->m_usrAddr = NULL;
359233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
360233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
361233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
362beb8f2079e8c43739ed356319caba47a7717e74aywan    mOMXBufferHeaderTypePtrNum = 0;
363beb8f2079e8c43739ed356319caba47a7717e74aywan    memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
364beb8f2079e8c43739ed356319caba47a7717e74aywan    for (i = 0; i < MAX_NATIVE_BUFFER_COUNT; i++) {
365beb8f2079e8c43739ed356319caba47a7717e74aywan        delete extMIDs[i]->m_surface;
366beb8f2079e8c43739ed356319caba47a7717e74aywan        free(extMIDs[i]);
367beb8f2079e8c43739ed356319caba47a7717e74aywan    }
368233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMXComponentCodecBase::ProcessorDeinit();
369233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
370233d2500723e5594f3e7c70896ffeeef32b9c950ywan
371233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorStop(void)
372233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
373233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMXComponentCodecBase::ProcessorStop();
374233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
375233d2500723e5594f3e7c70896ffeeef32b9c950ywan
376233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorFlush(OMX_U32)
377233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
378233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
379233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
380233d2500723e5594f3e7c70896ffeeef32b9c950ywan
381233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer)
382233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
383233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int handle = (unsigned int)buffer->pBuffer;
384233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int i = 0;
385233d2500723e5594f3e7c70896ffeeef32b9c950ywan
386233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (buffer->nOutputPortIndex == OUTPORT_INDEX){
387233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
388233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (handle == extMIDs[i]->m_key) {
389233d2500723e5594f3e7c70896ffeeef32b9c950ywan                extMIDs[i]->m_render_done = true;
390233d2500723e5594f3e7c70896ffeeef32b9c950ywan                break;
391233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
392233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
393233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
394233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
395233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
396233d2500723e5594f3e7c70896ffeeef32b9c950ywan
397233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorProcess(
398233d2500723e5594f3e7c70896ffeeef32b9c950ywan        OMX_BUFFERHEADERTYPE ***pBuffers,
399233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer_retain_t *retains,
400233d2500723e5594f3e7c70896ffeeef32b9c950ywan        OMX_U32)
401233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
402233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_ERRORTYPE ret;
403233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_BUFFERHEADERTYPE *inBuffer = *pBuffers[INPORT_INDEX];
404233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_BUFFERHEADERTYPE *outBuffer = *pBuffers[OUTPORT_INDEX];
405233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_BOOL isResolutionChange = OMX_FALSE;
406233d2500723e5594f3e7c70896ffeeef32b9c950ywan
407233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (inBuffer->pBuffer == NULL) {
408233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("Buffer to decode is empty.");
409233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorBadParameter;
410233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
411233d2500723e5594f3e7c70896ffeeef32b9c950ywan
412233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (inBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
413233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag.");
414233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
415233d2500723e5594f3e7c70896ffeeef32b9c950ywan
416233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (inBuffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) {
417233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag.");
418233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
419233d2500723e5594f3e7c70896ffeeef32b9c950ywan
420233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (inBuffer->nFlags & OMX_BUFFERFLAG_EOS) {
421233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (inBuffer->nFilledLen == 0) {
422233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (*pBuffers[OUTPORT_INDEX])->nFilledLen = 0;
423233d2500723e5594f3e7c70896ffeeef32b9c950ywan            (*pBuffers[OUTPORT_INDEX])->nFlags = OMX_BUFFERFLAG_EOS;
424233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorNone;
425233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
426233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
427233d2500723e5594f3e7c70896ffeeef32b9c950ywan
428233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (vpx_codec_decode((vpx_codec_ctx_t *)mCtx,
429233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         inBuffer->pBuffer + inBuffer->nOffset,
430233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         inBuffer->nFilledLen,
431233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         NULL,
432233d2500723e5594f3e7c70896ffeeef32b9c950ywan                         0)) {
433233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("on2 decoder failed to decode frame.");
434233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorBadParameter;
435233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
436233d2500723e5594f3e7c70896ffeeef32b9c950ywan
437233d2500723e5594f3e7c70896ffeeef32b9c950ywan    ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX],
438233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &retains[OUTPORT_INDEX],
439233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           ((*pBuffers[INPORT_INDEX]))->nFlags,
440233d2500723e5594f3e7c70896ffeeef32b9c950ywan                           &isResolutionChange);
441233d2500723e5594f3e7c70896ffeeef32b9c950ywan
442233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ret == OMX_ErrorNone) {
443233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (*pBuffers[OUTPORT_INDEX])->nTimeStamp = inBuffer->nTimeStamp;
444233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
445233d2500723e5594f3e7c70896ffeeef32b9c950ywan
446233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (isResolutionChange) {
447233d2500723e5594f3e7c70896ffeeef32b9c950ywan        HandleFormatChange();
448233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
449233d2500723e5594f3e7c70896ffeeef32b9c950ywan
450233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
451233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
452233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // if output port is not eos, retain the input buffer
453233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // until all the output buffers are drained.
454233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (inputEoS && !outputEoS) {
455233d2500723e5594f3e7c70896ffeeef32b9c950ywan        retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
456233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // the input buffer is retained for draining purpose.
457233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // Set nFilledLen to 0 so buffer will not be decoded again.
458233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (*pBuffers[INPORT_INDEX])->nFilledLen = 0;
459233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
460233d2500723e5594f3e7c70896ffeeef32b9c950ywan
461233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (ret == OMX_ErrorNotReady) {
462233d2500723e5594f3e7c70896ffeeef32b9c950ywan        retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
463233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ret = OMX_ErrorNone;
464233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
465233d2500723e5594f3e7c70896ffeeef32b9c950ywan
466233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return ret;
467233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
468233d2500723e5594f3e7c70896ffeeef32b9c950ywan
469233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::ProcessorReset(void)
470233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
471233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
472233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
473233d2500723e5594f3e7c70896ffeeef32b9c950ywan
474233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int ALIGN(int x, int y)
475233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
476233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // y must be a power of 2.
477233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return (x + y - 1) & ~(y - 1);
478233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
479233d2500723e5594f3e7c70896ffeeef32b9c950ywan
480233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::HandleFormatChange(void)
481233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
482233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageWidth = mDecodedImageNewWidth;
483233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mDecodedImageHeight = mDecodedImageNewHeight;
484233d2500723e5594f3e7c70896ffeeef32b9c950ywan
485233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // Sync port definition as it may change.
486233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput;
487233d2500723e5594f3e7c70896ffeeef32b9c950ywan
488233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memcpy(&paramPortDefinitionInput,
489233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this->ports[INPORT_INDEX]->GetPortDefinition(),
490233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sizeof(paramPortDefinitionInput));
491233d2500723e5594f3e7c70896ffeeef32b9c950ywan
492233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memcpy(&paramPortDefinitionOutput,
493233d2500723e5594f3e7c70896ffeeef32b9c950ywan        this->ports[OUTPORT_INDEX]->GetPortDefinition(),
494233d2500723e5594f3e7c70896ffeeef32b9c950ywan        sizeof(paramPortDefinitionOutput));
495233d2500723e5594f3e7c70896ffeeef32b9c950ywan
496233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t width = mDecodedImageWidth;
497233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t height = mDecodedImageHeight;
498233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t stride = mDecodedImageWidth;
499233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t sliceHeight = mDecodedImageHeight;
500233d2500723e5594f3e7c70896ffeeef32b9c950ywan
501233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t widthCropped = mDecodedImageWidth;
502233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t heightCropped = mDecodedImageHeight;
503233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t strideCropped = widthCropped;
504233d2500723e5594f3e7c70896ffeeef32b9c950ywan    uint32_t sliceHeightCropped = heightCropped;
505233d2500723e5594f3e7c70896ffeeef32b9c950ywan
506233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
507233d2500723e5594f3e7c70896ffeeef32b9c950ywan        heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
508233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (mWorkingMode == RAWDATA_MODE) {
509233d2500723e5594f3e7c70896ffeeef32b9c950ywan            LOGW("Change of portsetting is not reported as size is not changed.");
510233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorNone;
511233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
512233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
513233d2500723e5594f3e7c70896ffeeef32b9c950ywan
514233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput.format.video.nFrameWidth = width;
515233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput.format.video.nFrameHeight = height;
516233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput.format.video.nStride = stride;
517233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
518233d2500723e5594f3e7c70896ffeeef32b9c950ywan
519233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mWorkingMode == RAWDATA_MODE) {
520233d2500723e5594f3e7c70896ffeeef32b9c950ywan        paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped;
521233d2500723e5594f3e7c70896ffeeef32b9c950ywan        paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped;
522233d2500723e5594f3e7c70896ffeeef32b9c950ywan        paramPortDefinitionOutput.format.video.nStride = strideCropped;
523233d2500723e5594f3e7c70896ffeeef32b9c950ywan        paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped;
524233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else if (mWorkingMode == GRAPHICBUFFER_MODE) {
525233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // when the width and height ES parse are not larger than allocated graphic buffer in outport,
526233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // there is no need to reallocate graphic buffer,just report the crop info to omx client
527233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (width <= mGraphicBufferParam.graphicBufferWidth &&
528233d2500723e5594f3e7c70896ffeeef32b9c950ywan            height <= mGraphicBufferParam.graphicBufferHeight) {
529233d2500723e5594f3e7c70896ffeeef32b9c950ywan            this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
530233d2500723e5594f3e7c70896ffeeef32b9c950ywan            this->ports[OUTPORT_INDEX]->ReportOutputCrop();
531233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorNone;
532233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
533233d2500723e5594f3e7c70896ffeeef32b9c950ywan
534233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (width > mGraphicBufferParam.graphicBufferWidth ||
535233d2500723e5594f3e7c70896ffeeef32b9c950ywan            height > mGraphicBufferParam.graphicBufferHeight) {
536233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // update the real decoded resolution to outport instead of display resolution
537233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // for graphic buffer reallocation
538233d2500723e5594f3e7c70896ffeeef32b9c950ywan            // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
539233d2500723e5594f3e7c70896ffeeef32b9c950ywan            paramPortDefinitionOutput.format.video.nFrameWidth = width;
540233d2500723e5594f3e7c70896ffeeef32b9c950ywan            paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f;
541233d2500723e5594f3e7c70896ffeeef32b9c950ywan            paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
542233d2500723e5594f3e7c70896ffeeef32b9c950ywan                    paramPortDefinitionOutput.format.video.nFrameWidth);
543233d2500723e5594f3e7c70896ffeeef32b9c950ywan            paramPortDefinitionOutput.format.video.nStride = stride;
544233d2500723e5594f3e7c70896ffeeef32b9c950ywan            paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
545233d2500723e5594f3e7c70896ffeeef32b9c950ywan       }
546233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
547233d2500723e5594f3e7c70896ffeeef32b9c950ywan
548233d2500723e5594f3e7c70896ffeeef32b9c950ywan    paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
549233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mOMXBufferHeaderTypePtrNum = 0;
550233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
551233d2500723e5594f3e7c70896ffeeef32b9c950ywan
552233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
553233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
554233d2500723e5594f3e7c70896ffeeef32b9c950ywan
555233d2500723e5594f3e7c70896ffeeef32b9c950ywan    this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
556233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
557233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
558233d2500723e5594f3e7c70896ffeeef32b9c950ywan
559233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,
560233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                      buffer_retain_t *retain,
561233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                      OMX_U32 inportBufferFlags,
562233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                      OMX_BOOL *isResolutionChange)
563233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
564233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_BUFFERHEADERTYPE *buffer = *pBuffer;
565233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_BUFFERHEADERTYPE *buffer_orign = buffer;
566233d2500723e5594f3e7c70896ffeeef32b9c950ywan
567233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_ERRORTYPE ret = OMX_ErrorNone;
568233d2500723e5594f3e7c70896ffeeef32b9c950ywan
569233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_codec_iter_t iter = NULL;
570233d2500723e5594f3e7c70896ffeeef32b9c950ywan    vpx_image_t *img = NULL;
571233d2500723e5594f3e7c70896ffeeef32b9c950ywan    img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
572233d2500723e5594f3e7c70896ffeeef32b9c950ywan
573233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (img != NULL) {
574233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((mDecodedImageWidth == 0) && (mDecodedImageHeight == 0)) { // init value
575233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mDecodedImageWidth = img->d_w;
576233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mDecodedImageHeight = img->d_h;
577233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
578233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((mDecodedImageWidth != img->d_w) && (mDecodedImageHeight != img->d_h)) {
579233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mDecodedImageNewWidth = img->d_w;
580233d2500723e5594f3e7c70896ffeeef32b9c950ywan            mDecodedImageNewHeight = img->d_h;
581233d2500723e5594f3e7c70896ffeeef32b9c950ywan            *isResolutionChange = OMX_TRUE;
582233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
583233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
584233d2500723e5594f3e7c70896ffeeef32b9c950ywan
585233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (mWorkingMode == RAWDATA_MODE) {
586233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (img == NULL) {
587233d2500723e5594f3e7c70896ffeeef32b9c950ywan            LOGE("vpx_codec_get_frame return NULL.");
588233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorNotReady;
589233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
590233d2500723e5594f3e7c70896ffeeef32b9c950ywan
591233d2500723e5594f3e7c70896ffeeef32b9c950ywan        // in Raw data mode, this flag should be always true
592233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[img->fb_index]->m_render_done = true;
593233d2500723e5594f3e7c70896ffeeef32b9c950ywan
594233d2500723e5594f3e7c70896ffeeef32b9c950ywan        void *dst = buffer->pBuffer;
595233d2500723e5594f3e7c70896ffeeef32b9c950ywan        uint8_t *dst_y = (uint8_t *)dst;
596233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput
597233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      = this->ports[INPORT_INDEX]->GetPortDefinition();
598233d2500723e5594f3e7c70896ffeeef32b9c950ywan
599233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t inBufferWidth = paramPortDefinitionInput->format.video.nFrameWidth;
600233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t inBufferHeight = paramPortDefinitionInput->format.video.nFrameHeight;
601233d2500723e5594f3e7c70896ffeeef32b9c950ywan
602233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput
603233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      = this->ports[OUTPORT_INDEX]->GetPortDefinition();
604233d2500723e5594f3e7c70896ffeeef32b9c950ywan
605233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t dst_y_size = paramPortDefinitionOutput->format.video.nStride *
606233d2500723e5594f3e7c70896ffeeef32b9c950ywan                            paramPortDefinitionOutput->format.video.nFrameHeight;
607233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t dst_c_stride = ALIGN(paramPortDefinitionOutput->format.video.nStride / 2, 16);
608233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t dst_c_size = dst_c_stride * paramPortDefinitionOutput->format.video.nFrameHeight / 2;
609233d2500723e5594f3e7c70896ffeeef32b9c950ywan        uint8_t *dst_v = dst_y + dst_y_size;
610233d2500723e5594f3e7c70896ffeeef32b9c950ywan        uint8_t *dst_u = dst_v + dst_c_size;
611233d2500723e5594f3e7c70896ffeeef32b9c950ywan
612233d2500723e5594f3e7c70896ffeeef32b9c950ywan        //test border
613233d2500723e5594f3e7c70896ffeeef32b9c950ywan        dst_y += VPX_DECODE_BORDER * paramPortDefinitionOutput->format.video.nStride + VPX_DECODE_BORDER;
614233d2500723e5594f3e7c70896ffeeef32b9c950ywan        dst_v += (VPX_DECODE_BORDER/2) * dst_c_stride + (VPX_DECODE_BORDER/2);
615233d2500723e5594f3e7c70896ffeeef32b9c950ywan        dst_u += (VPX_DECODE_BORDER/2) * dst_c_stride + (VPX_DECODE_BORDER/2);
616233d2500723e5594f3e7c70896ffeeef32b9c950ywan
617233d2500723e5594f3e7c70896ffeeef32b9c950ywan        const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y];
618233d2500723e5594f3e7c70896ffeeef32b9c950ywan
619233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (size_t i = 0; i < img->d_h; ++i) {
620233d2500723e5594f3e7c70896ffeeef32b9c950ywan            memcpy(dst_y, srcLine, img->d_w);
621233d2500723e5594f3e7c70896ffeeef32b9c950ywan
622233d2500723e5594f3e7c70896ffeeef32b9c950ywan            srcLine += img->stride[PLANE_Y];
623233d2500723e5594f3e7c70896ffeeef32b9c950ywan            dst_y += paramPortDefinitionOutput->format.video.nStride;
624233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
625233d2500723e5594f3e7c70896ffeeef32b9c950ywan
626233d2500723e5594f3e7c70896ffeeef32b9c950ywan        srcLine = (const uint8_t *)img->planes[PLANE_U];
627233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (size_t i = 0; i < img->d_h / 2; ++i) {
628233d2500723e5594f3e7c70896ffeeef32b9c950ywan            memcpy(dst_u, srcLine, img->d_w / 2);
629233d2500723e5594f3e7c70896ffeeef32b9c950ywan
630233d2500723e5594f3e7c70896ffeeef32b9c950ywan            srcLine += img->stride[PLANE_U];
631233d2500723e5594f3e7c70896ffeeef32b9c950ywan            dst_u += dst_c_stride;
632233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
633233d2500723e5594f3e7c70896ffeeef32b9c950ywan
634233d2500723e5594f3e7c70896ffeeef32b9c950ywan        srcLine = (const uint8_t *)img->planes[PLANE_V];
635233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (size_t i = 0; i < img->d_h / 2; ++i) {
636233d2500723e5594f3e7c70896ffeeef32b9c950ywan            memcpy(dst_v, srcLine, img->d_w / 2);
637233d2500723e5594f3e7c70896ffeeef32b9c950ywan
638233d2500723e5594f3e7c70896ffeeef32b9c950ywan            srcLine += img->stride[PLANE_V];
639233d2500723e5594f3e7c70896ffeeef32b9c950ywan            dst_v += dst_c_stride;
640233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
641233d2500723e5594f3e7c70896ffeeef32b9c950ywan
642233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer->nOffset = 0;
643233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer->nFilledLen = dst_y_size + dst_c_size * 2;
644233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
645233d2500723e5594f3e7c70896ffeeef32b9c950ywan            buffer->nFlags = OMX_BUFFERFLAG_EOS;
646233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
647233d2500723e5594f3e7c70896ffeeef32b9c950ywan
648233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (buffer_orign != buffer) {
649233d2500723e5594f3e7c70896ffeeef32b9c950ywan            *retain = BUFFER_RETAIN_OVERRIDDEN;
650233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
651233d2500723e5594f3e7c70896ffeeef32b9c950ywan        ret = OMX_ErrorNone;
652233d2500723e5594f3e7c70896ffeeef32b9c950ywan
653233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return ret;
654233d2500723e5594f3e7c70896ffeeef32b9c950ywan
655233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
656233d2500723e5594f3e7c70896ffeeef32b9c950ywan
657233d2500723e5594f3e7c70896ffeeef32b9c950ywan#ifdef DECODE_WITH_GRALLOC_BUFFER
658233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (NULL != img) {
659233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[img->fb_index];
660233d2500723e5594f3e7c70896ffeeef32b9c950ywan
661233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if ((unsigned int)(buffer->pBuffer) != extMIDs[img->fb_index]->m_key) {
662233d2500723e5594f3e7c70896ffeeef32b9c950ywan            LOGE("There is gralloc handle mismatching between pool\
663233d2500723e5594f3e7c70896ffeeef32b9c950ywan                  and mOMXBufferHeaderTypePtrArray.");
664233d2500723e5594f3e7c70896ffeeef32b9c950ywan            return OMX_ErrorNotReady;
665233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
666233d2500723e5594f3e7c70896ffeeef32b9c950ywan
667233d2500723e5594f3e7c70896ffeeef32b9c950ywan        extMIDs[img->fb_index]->m_render_done = false;
668233d2500723e5594f3e7c70896ffeeef32b9c950ywan
669233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer->nOffset = 0;
670233d2500723e5594f3e7c70896ffeeef32b9c950ywan
671233d2500723e5594f3e7c70896ffeeef32b9c950ywan        size_t dst_y_size = img->d_w * img->d_h;
672233d2500723e5594f3e7c70896ffeeef32b9c950ywan
673233d2500723e5594f3e7c70896ffeeef32b9c950ywan        buffer->nFilledLen = dst_y_size * 1.5; // suport only 4:2:0 for now
674233d2500723e5594f3e7c70896ffeeef32b9c950ywan
675233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
676233d2500723e5594f3e7c70896ffeeef32b9c950ywan            buffer->nFlags = OMX_BUFFERFLAG_EOS;
677233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
678233d2500723e5594f3e7c70896ffeeef32b9c950ywan
679233d2500723e5594f3e7c70896ffeeef32b9c950ywan        if (buffer_orign != buffer) {
680233d2500723e5594f3e7c70896ffeeef32b9c950ywan            *retain = BUFFER_RETAIN_OVERRIDDEN;
681233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
682233d2500723e5594f3e7c70896ffeeef32b9c950ywan
683233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorNone;
684233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else {
685233d2500723e5594f3e7c70896ffeeef32b9c950ywan        LOGE("vpx_codec_get_frame return NULL.");
686233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorNotReady;
687233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
688233d2500723e5594f3e7c70896ffeeef32b9c950ywan#endif
689233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
690233d2500723e5594f3e7c70896ffeeef32b9c950ywan
691233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::PrepareConfigBuffer(VideoConfigBuffer *)
692233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
693233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
694233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
695233d2500723e5594f3e7c70896ffeeef32b9c950ywan
696233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *,
697233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                         buffer_retain_t *,
698233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                                         VideoDecodeBuffer *)
699233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
700233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
701233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
702233d2500723e5594f3e7c70896ffeeef32b9c950ywan
703233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::BuildHandlerList(void)
704233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
705233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMXVideoDecoderBase::BuildHandlerList();
706233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
707233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
708233d2500723e5594f3e7c70896ffeeef32b9c950ywan
709233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::GetParamVideoVp9(OMX_PTR)
710233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
711233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
712233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
713233d2500723e5594f3e7c70896ffeeef32b9c950ywan
714233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::SetParamVideoVp9(OMX_PTR)
715233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
716233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
717233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
718233d2500723e5594f3e7c70896ffeeef32b9c950ywan
719233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_COLOR_FORMATTYPE OMXVideoDecoderVP9HWR::GetOutputColorFormat(int)
720233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
721233d2500723e5594f3e7c70896ffeeef32b9c950ywan    LOGV("Output color format is OMX_INTEL_COLOR_FormatHalYV12.");
722233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12;
723233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
724233d2500723e5594f3e7c70896ffeeef32b9c950ywan
725233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::GetDecoderOutputCropSpecific(OMX_PTR pStructure)
726233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
727233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_ERRORTYPE ret = OMX_ErrorNone;
728233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure;
729233d2500723e5594f3e7c70896ffeeef32b9c950ywan
730233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CHECK_TYPE_HEADER(rectParams);
731233d2500723e5594f3e7c70896ffeeef32b9c950ywan
732233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (rectParams->nPortIndex != OUTPORT_INDEX) {
733233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorUndefined;
734233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
735233d2500723e5594f3e7c70896ffeeef32b9c950ywan
736233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput
737233d2500723e5594f3e7c70896ffeeef32b9c950ywan                                      = this->ports[INPORT_INDEX]->GetPortDefinition();
738233d2500723e5594f3e7c70896ffeeef32b9c950ywan
739233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rectParams->nLeft = VPX_DECODE_BORDER;
740233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rectParams->nTop = VPX_DECODE_BORDER;
741233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rectParams->nWidth = paramPortDefinitionInput->format.video.nFrameWidth;
742233d2500723e5594f3e7c70896ffeeef32b9c950ywan    rectParams->nHeight = paramPortDefinitionInput->format.video.nFrameHeight;
743233d2500723e5594f3e7c70896ffeeef32b9c950ywan
744233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return ret;
745233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
746233d2500723e5594f3e7c70896ffeeef32b9c950ywan
747233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::GetNativeBufferUsageSpecific(OMX_PTR pStructure)
748233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
749233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_ERRORTYPE ret;
750233d2500723e5594f3e7c70896ffeeef32b9c950ywan    android::GetAndroidNativeBufferUsageParams *param =
751233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (android::GetAndroidNativeBufferUsageParams*)pStructure;
752233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CHECK_TYPE_HEADER(param);
753233d2500723e5594f3e7c70896ffeeef32b9c950ywan
754233d2500723e5594f3e7c70896ffeeef32b9c950ywan    param->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER \
755233d2500723e5594f3e7c70896ffeeef32b9c950ywan                     | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_EXTERNAL_DISP);
756233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return OMX_ErrorNone;
757233d2500723e5594f3e7c70896ffeeef32b9c950ywan
758233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
759233d2500723e5594f3e7c70896ffeeef32b9c950ywan
760233d2500723e5594f3e7c70896ffeeef32b9c950ywanOMX_ERRORTYPE OMXVideoDecoderVP9HWR::SetNativeBufferModeSpecific(OMX_PTR pStructure)
761233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
762233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_ERRORTYPE ret;
763233d2500723e5594f3e7c70896ffeeef32b9c950ywan    EnableAndroidNativeBuffersParams *param =
764233d2500723e5594f3e7c70896ffeeef32b9c950ywan        (EnableAndroidNativeBuffersParams*)pStructure;
765233d2500723e5594f3e7c70896ffeeef32b9c950ywan
766233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CHECK_TYPE_HEADER(param);
767233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CHECK_PORT_INDEX_RANGE(param);
768233d2500723e5594f3e7c70896ffeeef32b9c950ywan    CHECK_SET_PARAM_STATE();
769233d2500723e5594f3e7c70896ffeeef32b9c950ywan
770233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!param->enable) {
771233d2500723e5594f3e7c70896ffeeef32b9c950ywan        mWorkingMode = RAWDATA_MODE;
772233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return OMX_ErrorNone;
773233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
774233d2500723e5594f3e7c70896ffeeef32b9c950ywan    mWorkingMode = GRAPHICBUFFER_MODE;
775233d2500723e5594f3e7c70896ffeeef32b9c950ywan    PortVideo *port = NULL;
776233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
777233d2500723e5594f3e7c70896ffeeef32b9c950ywan
778233d2500723e5594f3e7c70896ffeeef32b9c950ywan
779233d2500723e5594f3e7c70896ffeeef32b9c950ywan    OMX_PARAM_PORTDEFINITIONTYPE port_def;
780233d2500723e5594f3e7c70896ffeeef32b9c950ywan    memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
781233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.nBufferCountMin = mNativeBufferCount;
782233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.nBufferCountActual = mNativeBufferCount;
783233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
784233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.eColorFormat = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar;
785233d2500723e5594f3e7c70896ffeeef32b9c950ywan
786233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // add borders for libvpx decode need.
787233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.nFrameHeight += VPX_DECODE_BORDER * 2;
788233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.nFrameWidth += VPX_DECODE_BORDER * 2;
789233d2500723e5594f3e7c70896ffeeef32b9c950ywan    // make heigth 32bit align
790233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f;
791233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port_def.format.video.eColorFormat = GetOutputColorFormat(
792233d2500723e5594f3e7c70896ffeeef32b9c950ywan                        port_def.format.video.nFrameWidth);
793233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port->SetPortDefinition(&port_def,true);
794233d2500723e5594f3e7c70896ffeeef32b9c950ywan
795233d2500723e5594f3e7c70896ffeeef32b9c950ywan     return OMX_ErrorNone;
796233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
797233d2500723e5594f3e7c70896ffeeef32b9c950ywan
798233d2500723e5594f3e7c70896ffeeef32b9c950ywan
799233d2500723e5594f3e7c70896ffeeef32b9c950ywanbool OMXVideoDecoderVP9HWR::IsAllBufferAvailable(void)
800233d2500723e5594f3e7c70896ffeeef32b9c950ywan{
801233d2500723e5594f3e7c70896ffeeef32b9c950ywan    bool b = ComponentBase::IsAllBufferAvailable();
802233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (b == false) {
803233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return false;
804233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
805233d2500723e5594f3e7c70896ffeeef32b9c950ywan
806233d2500723e5594f3e7c70896ffeeef32b9c950ywan    PortVideo *port = NULL;
807233d2500723e5594f3e7c70896ffeeef32b9c950ywan    port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
808233d2500723e5594f3e7c70896ffeeef32b9c950ywan    const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition();
809233d2500723e5594f3e7c70896ffeeef32b9c950ywan     // if output port is disabled, retain the input buffer
810233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (!port_def->bEnabled) {
811233d2500723e5594f3e7c70896ffeeef32b9c950ywan        return false;
812233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
813233d2500723e5594f3e7c70896ffeeef32b9c950ywan
814233d2500723e5594f3e7c70896ffeeef32b9c950ywan    unsigned int i = 0;
815233d2500723e5594f3e7c70896ffeeef32b9c950ywan    int found = 0;
816233d2500723e5594f3e7c70896ffeeef32b9c950ywan
817233d2500723e5594f3e7c70896ffeeef32b9c950ywan    if (RAWDATA_MODE == mWorkingMode) {
818233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < OUTPORT_ACTUAL_BUFFER_COUNT; i++) {
819233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if (extMIDs[i]->m_released == true) {
820233d2500723e5594f3e7c70896ffeeef32b9c950ywan               found ++;
821233d2500723e5594f3e7c70896ffeeef32b9c950ywan               if (found > 1) { //libvpx sometimes needs 2 buffer when calling decode once.
822233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   return true;
823233d2500723e5594f3e7c70896ffeeef32b9c950ywan               }
824233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
825233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
826233d2500723e5594f3e7c70896ffeeef32b9c950ywan    } else { // graphic buffer mode
827233d2500723e5594f3e7c70896ffeeef32b9c950ywan        for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++) {
828233d2500723e5594f3e7c70896ffeeef32b9c950ywan            if ((extMIDs[i]->m_render_done == true) && (extMIDs[i]->m_released == true)) {
829233d2500723e5594f3e7c70896ffeeef32b9c950ywan               found ++;
830233d2500723e5594f3e7c70896ffeeef32b9c950ywan               if (found > 1) { //libvpx sometimes needs 2 buffer when calling decode once.
831233d2500723e5594f3e7c70896ffeeef32b9c950ywan                   return true;
832233d2500723e5594f3e7c70896ffeeef32b9c950ywan               }
833233d2500723e5594f3e7c70896ffeeef32b9c950ywan            }
834233d2500723e5594f3e7c70896ffeeef32b9c950ywan        }
835233d2500723e5594f3e7c70896ffeeef32b9c950ywan    }
836233d2500723e5594f3e7c70896ffeeef32b9c950ywan
837233d2500723e5594f3e7c70896ffeeef32b9c950ywan    b = false;
838233d2500723e5594f3e7c70896ffeeef32b9c950ywan
839233d2500723e5594f3e7c70896ffeeef32b9c950ywan    return b;
840233d2500723e5594f3e7c70896ffeeef32b9c950ywan}
841233d2500723e5594f3e7c70896ffeeef32b9c950ywan
842233d2500723e5594f3e7c70896ffeeef32b9c950ywanDECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.VP9.hwr", "video_decoder.vp9", OMXVideoDecoderVP9HWR);
843233d2500723e5594f3e7c70896ffeeef32b9c950ywan
844