• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&paramPortDefinitionInput,
413         this->ports[INPORT_INDEX]->GetPortDefinition(),
414         sizeof(paramPortDefinitionInput));
415 
416     memcpy(&paramPortDefinitionOutput,
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(&paramPortDefinitionInput, 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(&paramPortDefinitionInput, true);
478     this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, 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