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