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