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