1 /*
2 * Copyright (c) 2012 Intel Corporation. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TIME 0
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "OMXVideoDecoderVP9Hybrid"
20 #include <wrs_omxil_core/log.h>
21 #include "OMXVideoDecoderVP9Hybrid.h"
22
23 #include <system/window.h>
24 #include <hardware/hardware.h>
25 #include <hardware/gralloc.h>
26 #include <system/graphics.h>
27
28 static const char* VP9_MIME_TYPE = "video/x-vnd.on2.vp9";
29
OMXVideoDecoderVP9Hybrid()30 OMXVideoDecoderVP9Hybrid::OMXVideoDecoderVP9Hybrid() {
31 LOGV("OMXVideoDecoderVP9Hybrid is constructed.");
32 mNativeBufferCount = OUTPORT_NATIVE_BUFFER_COUNT;
33 BuildHandlerList();
34 mLibHandle = NULL;
35 mOpenDecoder = NULL;
36 mInitDecoder = NULL;
37 mCloseDecoder = NULL;
38 mSingalRenderDone = NULL;
39 mDecoderDecode = NULL;
40 mCheckBufferAvailable = NULL;
41 mGetOutput = NULL;
42 mGetRawDataOutput = NULL;
43 mGetFrameResolution = NULL;
44 mDeinitDecoder = NULL;
45 mLastTimeStamp = 0;
46 mWorkingMode = RAWDATA_MODE;
47 mDecodedImageWidth = 0;
48 mDecodedImageHeight = 0;
49 mDecodedImageNewWidth = 0;
50 mDecodedImageNewHeight = 0;
51 }
52
~OMXVideoDecoderVP9Hybrid()53 OMXVideoDecoderVP9Hybrid::~OMXVideoDecoderVP9Hybrid() {
54 LOGV("OMXVideoDecoderVP9Hybrid is destructed.");
55 }
56
InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE * paramPortDefinitionInput)57 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::InitInputPortFormatSpecific(
58 OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) {
59 // OMX_PARAM_PORTDEFINITIONTYPE
60 paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT;
61 paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT;
62 paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE;
63 paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)VP9_MIME_TYPE;
64 paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
65 return OMX_ErrorNone;
66 }
67
ProcessorInit(void)68 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorInit(void) {
69 uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
70 uint32_t i, bufferCount;
71 bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
72 uint32_t bufferSize, bufferStride, bufferHeight, bufferWidth;
73 if (!gralloc_mode) {
74 bufferSize = 1920 * 1088 * 1.5;
75 bufferStride = 1920;
76 bufferWidth = 1920;
77 bufferHeight = 1088;
78 bufferCount = 12;
79 } else {
80 bufferSize = mGraphicBufferParam.graphicBufferStride *
81 mGraphicBufferParam.graphicBufferHeight * 1.5;
82 bufferStride = mGraphicBufferParam.graphicBufferStride;
83 bufferCount = mOMXBufferHeaderTypePtrNum;
84 bufferHeight = mGraphicBufferParam.graphicBufferHeight;
85 bufferWidth = mGraphicBufferParam.graphicBufferWidth;
86
87 for (i = 0; i < bufferCount; i++ ) {
88 OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
89 buff[i] = (uint32_t)(buf_hdr->pBuffer);
90 }
91 }
92
93 mLibHandle = dlopen("libDecoderVP9Hybrid.so", RTLD_NOW);
94 if (mLibHandle == NULL) {
95 LOGE("dlopen libDecoderVP9Hybrid.so fail\n");
96 return OMX_ErrorBadParameter;
97 } else {
98 LOGI("dlopen libDecoderVP9Hybrid.so successfully\n");
99 }
100 mOpenDecoder = (OpenFunc)dlsym(mLibHandle, "Decoder_Open");
101 mCloseDecoder = (CloseFunc)dlsym(mLibHandle, "Decoder_Close");
102 mInitDecoder = (InitFunc)dlsym(mLibHandle, "Decoder_Init");
103 mSingalRenderDone = (SingalRenderDoneFunc)dlsym(mLibHandle, "Decoder_SingalRenderDone");
104 mDecoderDecode = (DecodeFunc)dlsym(mLibHandle, "Decoder_Decode");
105 mCheckBufferAvailable = (IsBufferAvailableFunc)dlsym(mLibHandle, "Decoder_IsBufferAvailable");
106 mGetOutput = (GetOutputFunc)dlsym(mLibHandle, "Decoder_GetOutput");
107 mGetRawDataOutput = (GetRawDataOutputFunc)dlsym(mLibHandle, "Decoder_GetRawDataOutput");
108 mGetFrameResolution = (GetFrameResolutionFunc)dlsym(mLibHandle, "Decoder_GetFrameResolution");
109 mDeinitDecoder = (DeinitFunc)dlsym(mLibHandle, "Decoder_Deinit");
110 if (mOpenDecoder == NULL || mCloseDecoder == NULL
111 || mInitDecoder == NULL || mSingalRenderDone == NULL
112 || mDecoderDecode == NULL || mCheckBufferAvailable == NULL
113 || mGetOutput == NULL || mGetRawDataOutput == NULL
114 || mGetFrameResolution == NULL || mDeinitDecoder == NULL) {
115 return OMX_ErrorBadParameter;
116 }
117
118 if (mOpenDecoder(&mCtx,&mHybridCtx) == false) {
119 LOGE("open hybrid Decoder fail\n");
120 return OMX_ErrorBadParameter;
121 }
122
123 mInitDecoder(mHybridCtx,bufferSize,bufferStride,bufferWidth, bufferHeight,bufferCount,gralloc_mode, buff);
124 return OMX_ErrorNone;
125 }
126
ProcessorReset(void)127 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorReset(void)
128 {
129 uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
130 uint32_t i, bufferCount;
131 bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
132 uint32_t bufferSize, bufferStride, bufferHeight, bufferWidth;
133 if (!gralloc_mode) {
134 bufferSize = mDecodedImageWidth * mDecodedImageHeight * 1.5;
135 bufferStride = mDecodedImageWidth;
136 bufferWidth = mDecodedImageWidth;
137 bufferHeight = mDecodedImageHeight;
138 bufferCount = 12;
139 } else {
140 bufferSize = mGraphicBufferParam.graphicBufferStride *
141 mGraphicBufferParam.graphicBufferHeight * 1.5;
142 bufferStride = mGraphicBufferParam.graphicBufferStride;
143 bufferWidth = mGraphicBufferParam.graphicBufferWidth;
144 bufferCount = mOMXBufferHeaderTypePtrNum;
145 bufferHeight = mGraphicBufferParam.graphicBufferHeight;
146
147 for (i = 0; i < bufferCount; i++ ) {
148 OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
149 buff[i] = (uint32_t)(buf_hdr->pBuffer);
150 }
151 }
152 mInitDecoder(mHybridCtx,bufferSize,bufferStride,bufferWidth,bufferHeight,bufferCount,gralloc_mode, buff);
153
154 return OMX_ErrorNone;
155 }
156
isReallocateNeeded(const uint8_t * data,uint32_t data_sz)157 bool OMXVideoDecoderVP9Hybrid::isReallocateNeeded(const uint8_t * data,uint32_t data_sz)
158 {
159 bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
160 uint32_t width, height;
161 bool ret = true;
162 if (gralloc_mode) {
163 ret = mGetFrameResolution(data,data_sz, &width, &height);
164 if (ret) {
165 ret = width > mGraphicBufferParam.graphicBufferWidth
166 || height > mGraphicBufferParam.graphicBufferHeight;
167 if (ret) {
168 mDecodedImageNewWidth = width;
169 mDecodedImageNewHeight = height;
170 return true;
171 }
172 }
173 }
174 return ret;
175 }
176
ProcessorDeinit(void)177 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorDeinit(void) {
178 mCloseDecoder(mCtx,mHybridCtx);
179 mOMXBufferHeaderTypePtrNum = 0;
180 if (mLibHandle != NULL) {
181 dlclose(mLibHandle);
182 mLibHandle = NULL;
183 }
184 return OMX_ErrorNone;
185 }
186
ProcessorStop(void)187 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorStop(void) {
188 return OMXComponentCodecBase::ProcessorStop();
189 }
190
ProcessorFlush(OMX_U32 portIndex)191 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorFlush(OMX_U32 portIndex) {
192 if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
193 // end the last frame
194 unsigned int width, height;
195 mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
196 mGetOutput(mCtx,mHybridCtx, &width, &height);
197 mLastTimeStamp = 0;
198 }
199 return OMX_ErrorNone;
200 }
201
ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE * buffer)202 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer) {
203 unsigned int handle = (unsigned int)buffer->pBuffer;
204 unsigned int i = 0;
205
206 if (buffer->nOutputPortIndex == OUTPORT_INDEX){
207 mSingalRenderDone(mHybridCtx,handle);
208 }
209 return OMX_ErrorNone;
210 }
211
ProcessorProcess(OMX_BUFFERHEADERTYPE *** pBuffers,buffer_retain_t * retains,OMX_U32)212 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorProcess(
213 OMX_BUFFERHEADERTYPE ***pBuffers,
214 buffer_retain_t *retains,
215 OMX_U32)
216 {
217 OMX_ERRORTYPE ret;
218 OMX_BUFFERHEADERTYPE *inBuffer = *pBuffers[INPORT_INDEX];
219 OMX_BUFFERHEADERTYPE *outBuffer = *pBuffers[OUTPORT_INDEX];
220 bool eos = (inBuffer->nFlags & OMX_BUFFERFLAG_EOS)? true:false;
221 OMX_BOOL isResolutionChange = OMX_FALSE;
222
223 eos = eos && (inBuffer->nFilledLen == 0);
224
225 if (inBuffer->pBuffer == NULL) {
226 LOGE("Buffer to decode is empty.");
227 return OMX_ErrorBadParameter;
228 }
229
230 if (inBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
231 LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag.");
232 }
233
234 if (inBuffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) {
235 LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag.");
236 }
237
238 #if LOG_TIME == 1
239 struct timeval tv_start, tv_end;
240 int32_t time_ms;
241 gettimeofday(&tv_start,NULL);
242 #endif
243 int res = mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen, eos);
244 if (res != 0) {
245 if (res == -2) {
246 if (isReallocateNeeded(inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen)) {
247 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
248 HandleFormatChange();
249 return OMX_ErrorNone;
250 }
251 // drain the last frame, keep the current input buffer
252 res = mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
253 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
254 } else {
255 LOGE("on2 decoder failed to decode frame.");
256 return OMX_ErrorBadParameter;
257 }
258 }
259
260 #if LOG_TIME == 1
261 gettimeofday(&tv_end,NULL);
262 time_ms = (int32_t)(tv_end.tv_sec - tv_start.tv_sec) * 1000 + (int32_t)(tv_end.tv_usec - tv_start.tv_usec)/1000;
263 LOGI("vpx_codec_decode: %d ms", time_ms);
264 #endif
265
266 ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX],
267 &retains[OUTPORT_INDEX],
268 eos? OMX_BUFFERFLAG_EOS:0,
269 &isResolutionChange);
270
271 if (ret == OMX_ErrorNone) {
272 (*pBuffers[OUTPORT_INDEX])->nTimeStamp = mLastTimeStamp;
273 }
274 mLastTimeStamp = inBuffer->nTimeStamp;
275
276 if (isResolutionChange == OMX_TRUE) {
277 HandleFormatChange();
278 }
279 bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
280 bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
281 // if output port is not eos, retain the input buffer
282 // until all the output buffers are drained.
283 if (inputEoS && !outputEoS && retains[INPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) {
284 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
285 // the input buffer is retained for draining purpose.
286 // Set nFilledLen to 0 so buffer will not be decoded again.
287 (*pBuffers[INPORT_INDEX])->nFilledLen = 0;
288 }
289
290 if (ret == OMX_ErrorNotReady) {
291 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
292 ret = OMX_ErrorNone;
293 }
294
295 return ret;
296 }
297
ALIGN(int x,int y)298 static int ALIGN(int x, int y) {
299 // y must be a power of 2.
300 return (x + y - 1) & ~(y - 1);
301 }
302
FillRenderBuffer(OMX_BUFFERHEADERTYPE ** pBuffer,buffer_retain_t * retain,OMX_U32 inportBufferFlags,OMX_BOOL * isResolutionChange)303 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,
304 buffer_retain_t *retain,
305 OMX_U32 inportBufferFlags,
306 OMX_BOOL *isResolutionChange)
307 {
308 OMX_BUFFERHEADERTYPE *buffer = *pBuffer;
309 OMX_BUFFERHEADERTYPE *buffer_orign = buffer;
310
311 OMX_ERRORTYPE ret = OMX_ErrorNone;
312
313 int fb_index;
314 if (mWorkingMode == RAWDATA_MODE) {
315 const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput
316 = this->ports[OUTPORT_INDEX]->GetPortDefinition();
317 int32_t stride = paramPortDefinitionOutput->format.video.nStride;
318 int32_t height = paramPortDefinitionOutput->format.video.nFrameHeight;
319 int32_t width = paramPortDefinitionOutput->format.video.nFrameWidth;
320 unsigned char *dst = buffer->pBuffer;
321 fb_index = mGetRawDataOutput(mCtx,mHybridCtx,dst,height,stride);
322 if (fb_index == -1) {
323 if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
324 // eos frame is non-shown frame
325 buffer->nFlags = OMX_BUFFERFLAG_EOS;
326 buffer->nOffset = 0;
327 buffer->nFilledLen = 0;
328 return OMX_ErrorNone;
329 }
330 LOGV("vpx_codec_get_frame return NULL.");
331 return OMX_ErrorNotReady;
332 }
333 buffer->nOffset = 0;
334 buffer->nFilledLen = stride*height*3/2;
335 if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
336 buffer->nFlags = OMX_BUFFERFLAG_EOS;
337 }
338 return OMX_ErrorNone;
339 }
340
341 fb_index = mGetOutput(mCtx,mHybridCtx, &mDecodedImageNewWidth, &mDecodedImageNewHeight);
342 if (fb_index == -1) {
343 if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
344 // eos frame is no-shown frame
345 buffer->nFlags = OMX_BUFFERFLAG_EOS;
346 buffer->nOffset = 0;
347 buffer->nFilledLen = 0;
348 return OMX_ErrorNone;
349 }
350 LOGV("vpx_codec_get_frame return NULL.");
351 return OMX_ErrorNotReady;
352 }
353 if (mDecodedImageHeight == 0 && mDecodedImageWidth == 0) {
354 mDecodedImageWidth = mDecodedImageNewWidth;
355 mDecodedImageHeight = mDecodedImageNewHeight;
356 *isResolutionChange = OMX_TRUE;
357 }
358 if ((mDecodedImageNewWidth != mDecodedImageWidth)
359 || (mDecodedImageNewHeight!= mDecodedImageHeight)) {
360 *isResolutionChange = OMX_TRUE;
361 }
362
363 buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[fb_index];
364 buffer->nOffset = 0;
365 buffer->nFilledLen = sizeof(OMX_U8*);
366 if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
367 buffer->nFlags = OMX_BUFFERFLAG_EOS;
368 }
369
370 if (buffer_orign != buffer) {
371 *retain = BUFFER_RETAIN_OVERRIDDEN;
372 }
373
374 ret = OMX_ErrorNone;
375
376 return ret;
377
378 }
379
PrepareConfigBuffer(VideoConfigBuffer *)380 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::PrepareConfigBuffer(VideoConfigBuffer *) {
381 return OMX_ErrorNone;
382 }
383
PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *,buffer_retain_t *,VideoDecodeBuffer *)384 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *,
385 buffer_retain_t *,
386 VideoDecodeBuffer *) {
387 return OMX_ErrorNone;
388 }
389
BuildHandlerList(void)390 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::BuildHandlerList(void) {
391 OMXVideoDecoderBase::BuildHandlerList();
392 return OMX_ErrorNone;
393 }
394
GetParamVideoVp9(OMX_PTR)395 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetParamVideoVp9(OMX_PTR) {
396 return OMX_ErrorNone;
397 }
398
SetParamVideoVp9(OMX_PTR)399 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetParamVideoVp9(OMX_PTR) {
400 return OMX_ErrorNone;
401 }
402
HandleFormatChange(void)403 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::HandleFormatChange(void)
404 {
405 ALOGI("handle format change from %dx%d to %dx%d",
406 mDecodedImageWidth,mDecodedImageHeight,mDecodedImageNewWidth,mDecodedImageNewHeight);
407 mDecodedImageWidth = mDecodedImageNewWidth;
408 mDecodedImageHeight = mDecodedImageNewHeight;
409 // Sync port definition as it may change.
410 OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput;
411
412 memcpy(¶mPortDefinitionInput,
413 this->ports[INPORT_INDEX]->GetPortDefinition(),
414 sizeof(paramPortDefinitionInput));
415
416 memcpy(¶mPortDefinitionOutput,
417 this->ports[OUTPORT_INDEX]->GetPortDefinition(),
418 sizeof(paramPortDefinitionOutput));
419
420 unsigned int width = mDecodedImageWidth;
421 unsigned int height = mDecodedImageHeight;
422 unsigned int stride = mDecodedImageWidth;
423 unsigned int sliceHeight = mDecodedImageHeight;
424
425 unsigned int widthCropped = mDecodedImageWidth;
426 unsigned int heightCropped = mDecodedImageHeight;
427 unsigned int strideCropped = widthCropped;
428 unsigned int sliceHeightCropped = heightCropped;
429
430 if (widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
431 heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
432 if (mWorkingMode == RAWDATA_MODE) {
433 LOGW("Change of portsetting is not reported as size is not changed.");
434 return OMX_ErrorNone;
435 }
436 }
437
438 paramPortDefinitionInput.format.video.nFrameWidth = width;
439 paramPortDefinitionInput.format.video.nFrameHeight = height;
440 paramPortDefinitionInput.format.video.nStride = stride;
441 paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
442
443 if (mWorkingMode == RAWDATA_MODE) {
444 paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped;
445 paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped;
446 paramPortDefinitionOutput.format.video.nStride = strideCropped;
447 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped;
448 } else if (mWorkingMode == GRAPHICBUFFER_MODE) {
449 // when the width and height ES parse are not larger than allocated graphic buffer in outport,
450 // there is no need to reallocate graphic buffer,just report the crop info to omx client
451 if (width <= mGraphicBufferParam.graphicBufferWidth &&
452 height <= mGraphicBufferParam.graphicBufferHeight) {
453 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true);
454 this->ports[OUTPORT_INDEX]->ReportOutputCrop();
455 return OMX_ErrorNone;
456 }
457
458 if (width > mGraphicBufferParam.graphicBufferWidth ||
459 height > mGraphicBufferParam.graphicBufferHeight) {
460 // update the real decoded resolution to outport instead of display resolution
461 // for graphic buffer reallocation
462 // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
463 paramPortDefinitionOutput.format.video.nFrameWidth = width;
464 paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f;
465 paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
466 paramPortDefinitionOutput.format.video.nFrameWidth);
467 paramPortDefinitionOutput.format.video.nStride = stride;
468 paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
469 }
470 }
471
472 paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
473 mOMXBufferHeaderTypePtrNum = 0;
474 memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
475 mDeinitDecoder(mHybridCtx);
476
477 this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true);
478 this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true);
479
480 this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
481 return OMX_ErrorNone;
482 }
483
484
GetOutputColorFormat(int)485 OMX_COLOR_FORMATTYPE OMXVideoDecoderVP9Hybrid::GetOutputColorFormat(int) {
486 LOGV("Output color format is HAL_PIXEL_FORMAT_YV12.");
487 return (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12;
488 }
489
GetDecoderOutputCropSpecific(OMX_PTR pStructure)490 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetDecoderOutputCropSpecific(OMX_PTR pStructure) {
491
492 OMX_ERRORTYPE ret = OMX_ErrorNone;
493 OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)pStructure;
494
495 CHECK_TYPE_HEADER(rectParams);
496
497 if (rectParams->nPortIndex != OUTPORT_INDEX) {
498 return OMX_ErrorUndefined;
499 }
500
501 const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput
502 = this->ports[INPORT_INDEX]->GetPortDefinition();
503
504 rectParams->nLeft = VPX_DECODE_BORDER;
505 rectParams->nTop = VPX_DECODE_BORDER;
506 rectParams->nWidth = paramPortDefinitionInput->format.video.nFrameWidth;
507 rectParams->nHeight = paramPortDefinitionInput->format.video.nFrameHeight;
508
509 return ret;
510 }
511
GetNativeBufferUsageSpecific(OMX_PTR pStructure)512 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::GetNativeBufferUsageSpecific(OMX_PTR pStructure) {
513 OMX_ERRORTYPE ret;
514 android::GetAndroidNativeBufferUsageParams *param =
515 (android::GetAndroidNativeBufferUsageParams*)pStructure;
516 CHECK_TYPE_HEADER(param);
517
518 param->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN
519 | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_EXTERNAL_DISP);
520 return OMX_ErrorNone;
521
522 }
SetNativeBufferModeSpecific(OMX_PTR pStructure)523 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::SetNativeBufferModeSpecific(OMX_PTR pStructure) {
524 OMX_ERRORTYPE ret;
525 android::EnableAndroidNativeBuffersParams *param =
526 (android::EnableAndroidNativeBuffersParams*)pStructure;
527
528 CHECK_TYPE_HEADER(param);
529 CHECK_PORT_INDEX_RANGE(param);
530 CHECK_SET_PARAM_STATE();
531
532 if (!param->enable) {
533 mWorkingMode = RAWDATA_MODE;
534 LOGI("Raw data mode is used");
535 return OMX_ErrorNone;
536 }
537 mWorkingMode = GRAPHICBUFFER_MODE;
538 PortVideo *port = NULL;
539 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
540
541 OMX_PARAM_PORTDEFINITIONTYPE port_def;
542 memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
543 port_def.nBufferCountMin = mNativeBufferCount - 4;
544 port_def.nBufferCountActual = mNativeBufferCount;
545 port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
546 // add borders for libvpx decode need.
547 port_def.format.video.nFrameWidth += VPX_DECODE_BORDER * 2;
548 mDecodedImageWidth = port_def.format.video.nFrameWidth;
549 mDecodedImageHeight = port_def.format.video.nFrameHeight;
550 // make heigth 32bit align
551 port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f;
552 port_def.format.video.eColorFormat = GetOutputColorFormat(port_def.format.video.nFrameWidth);
553 port->SetPortDefinition(&port_def,true);
554
555 return OMX_ErrorNone;
556 }
557
558
IsAllBufferAvailable(void)559 bool OMXVideoDecoderVP9Hybrid::IsAllBufferAvailable(void) {
560 bool b = ComponentBase::IsAllBufferAvailable();
561 if (b == false) {
562 return false;
563 }
564
565 PortVideo *port = NULL;
566 port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
567 const OMX_PARAM_PORTDEFINITIONTYPE* port_def = port->GetPortDefinition();
568 // if output port is disabled, retain the input buffer
569 if (!port_def->bEnabled) {
570 return false;
571 }
572 return mCheckBufferAvailable(mHybridCtx);
573 }
574
575 DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.VP9.hybrid", "video_decoder.vp9", OMXVideoDecoderVP9Hybrid);
576