import exynos 7570 bsp
[GitHub/LineageOS/android_hardware_samsung_slsi_openmax.git] / component / video / dec / vp9 / Exynos_OMX_Vp9dec.c
1 /*
2 *
3 * Copyright 2014 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * @file Exynos_OMX_Vp9dec.c
20 * @brief
21 * @author Taehwan Kim (t_h.kim@samsung.com)
22 * SeungBeom Kim (sbcrux.kim@samsung.com)
23 * @version 2.0.0
24 * @history
25 * 2014.07.24 : Create
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OMX_Basecomponent.h"
34 #include "Exynos_OMX_Baseport.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OMX_VdecControl.h"
37 #include "Exynos_OSAL_ETC.h"
38 #include "Exynos_OSAL_Semaphore.h"
39 #include "Exynos_OSAL_Thread.h"
40 #include "library_register.h"
41 #include "Exynos_OMX_Vp9dec.h"
42 #include "ExynosVideoApi.h"
43 #include "Exynos_OSAL_SharedMemory.h"
44 #include "Exynos_OSAL_Event.h"
45
46 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
47 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
48 #include "csc.h"
49
50 #undef EXYNOS_LOG_TAG
51 #define EXYNOS_LOG_TAG "EXYNOS_VP9_DEC"
52 //#define EXYNOS_LOG_OFF
53 #include "Exynos_OSAL_Log.h"
54
55 #define VP9_DEC_NUM_OF_EXTRA_BUFFERS 7
56
57 //#define FULL_FRAME_SEARCH /* Full frame search not support*/
58
59 #if 0 /* unused code */
60 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
61 {
62 OMX_ERRORTYPE ret = OMX_ErrorNone;
63
64 EXIT:
65 return ret;
66 }
67 #endif
68
69 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
70 {
71 OMX_ERRORTYPE ret = OMX_ErrorNone;
72 ExynosVideoBuffer *pCodecBuffer = NULL;
73
74 if (codecBuffer == NULL) {
75 ret = OMX_ErrorBadParameter;
76 goto EXIT;
77 }
78
79 pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
80
81 if (addr != NULL) {
82 addr[0] = pCodecBuffer->planes[0].addr;
83 addr[1] = pCodecBuffer->planes[1].addr;
84 addr[2] = pCodecBuffer->planes[2].addr;
85 }
86
87 if (size != NULL) {
88 size[0] = pCodecBuffer->planes[0].allocSize;
89 size[1] = pCodecBuffer->planes[1].allocSize;
90 size[2] = pCodecBuffer->planes[2].allocSize;
91 }
92
93 EXIT:
94 return ret;
95 }
96
97 #if 0 /* unused code */
98 static int Check_VP9_Frame(
99 OMX_U8 *pInputStream,
100 OMX_U32 buffSize,
101 OMX_U32 flag,
102 OMX_BOOL bPreviousFrameEOF,
103 OMX_BOOL *pbEndOfFrame)
104 {
105 /* Uncompressed data Chunk comprises a common
106 (for key frames and interframes) 3-byte frame tag that
107 contains four fields
108 - 1-bit frame type (0 - key frame, 1 - inter frame)
109 - 3-bit version number (0 - 3 are defined as four different
110 profiles with different decoding complexity)
111 - 1-bit show_frame flag ( 0 - current frame not for display,
112 1 - current frame is for dispaly)
113 - 19-bit field - size of the first data partition in bytes
114
115 Key Frames : frame tag followed by 7 bytes of uncompressed
116 data
117 3-bytes : Start code (byte 0: 0x9d,byte 1: 0x01,byte 2: 0x2a)
118 Next 4-bytes: Width & height, Horizontal and vertical scale information
119 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits)
120 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits)
121 */
122 int width, height;
123 int horizSscale, vertScale;
124
125 FunctionIn();
126
127 *pbEndOfFrame = OMX_TRUE;
128
129 /*Check for Key frame*/
130 if (!(pInputStream[0] & 0x01)){
131 /* Key Frame Start code*/
132 if (pInputStream[3] != 0x9d || pInputStream[4] != 0x01 || pInputStream[5]!=0x2a) {
133 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, " VP9 Key Frame Start Code not Found");
134 *pbEndOfFrame = OMX_FALSE;
135 }
136 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, " VP9 Found Key Frame Start Code");
137 width = (pInputStream[6] | (pInputStream[7] << 8)) & 0x3fff;
138 horizSscale = pInputStream[7] >> 6;
139 height = (pInputStream[8] | (pInputStream[9] << 8)) & 0x3fff;
140 vertScale = pInputStream[9] >> 6;
141 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "width = %d, height = %d, horizSscale = %d, vertScale = %d", width, height, horizSscale, vertScale);
142 }
143
144 FunctionOut();
145 return (int)buffSize;
146 }
147 #endif
148
149 OMX_BOOL Check_VP9_StartCode(
150 OMX_U8 *pInputStream,
151 OMX_U32 streamSize)
152 {
153 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "buffer: %p, streamSize: %d", pInputStream, streamSize);
154 if (streamSize < 3) {
155 return OMX_FALSE;
156 }
157
158 return OMX_TRUE;
159 }
160
161 OMX_BOOL CheckFormatHWSupport(
162 EXYNOS_OMX_BASECOMPONENT *pExynosComponent,
163 OMX_COLOR_FORMATTYPE eColorFormat)
164 {
165 OMX_BOOL ret = OMX_FALSE;
166 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
167 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
168 EXYNOS_OMX_BASEPORT *pOutputPort = NULL;
169 ExynosVideoColorFormatType eVideoFormat = VIDEO_CODING_UNKNOWN;
170 int i;
171
172 FunctionIn();
173
174 if (pExynosComponent == NULL)
175 goto EXIT;
176
177 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
178 if (pVideoDec == NULL)
179 goto EXIT;
180
181 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
182 if (pVp9Dec == NULL)
183 goto EXIT;
184 pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
185
186 eVideoFormat = (ExynosVideoColorFormatType)Exynos_OSAL_OMX2VideoFormat(eColorFormat, pOutputPort->ePlaneType);
187
188 for (i = 0; i < VIDEO_COLORFORMAT_MAX; i++) {
189 if (pVp9Dec->hMFCVp9Handle.videoInstInfo.supportFormat[i] == VIDEO_COLORFORMAT_UNKNOWN)
190 break;
191
192 if (pVp9Dec->hMFCVp9Handle.videoInstInfo.supportFormat[i] == eVideoFormat) {
193 ret = OMX_TRUE;
194 break;
195 }
196 }
197
198 EXIT:
199 return ret;
200 }
201
202 OMX_ERRORTYPE VP9CodecOpen(EXYNOS_VP9DEC_HANDLE *pVp9Dec, ExynosVideoInstInfo *pVideoInstInfo)
203 {
204 OMX_ERRORTYPE ret = OMX_ErrorNone;
205 ExynosVideoDecOps *pDecOps = NULL;
206 ExynosVideoDecBufferOps *pInbufOps = NULL;
207 ExynosVideoDecBufferOps *pOutbufOps = NULL;
208
209 FunctionIn();
210
211 if (pVp9Dec == NULL) {
212 ret = OMX_ErrorBadParameter;
213 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
214 goto EXIT;
215 }
216
217 /* alloc ops structure */
218 pDecOps = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
219 pInbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
220 pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
221
222 if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
223 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
224 ret = OMX_ErrorInsufficientResources;
225 goto EXIT;
226 }
227
228 pVp9Dec->hMFCVp9Handle.pDecOps = pDecOps;
229 pVp9Dec->hMFCVp9Handle.pInbufOps = pInbufOps;
230 pVp9Dec->hMFCVp9Handle.pOutbufOps = pOutbufOps;
231
232 /* function pointer mapping */
233 pDecOps->nSize = sizeof(ExynosVideoDecOps);
234 pInbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
235 pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
236
237 Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
238
239 /* check mandatory functions for decoder ops */
240 if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
241 (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
242 (pDecOps->Get_FrameTag == NULL)) {
243 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
244 ret = OMX_ErrorInsufficientResources;
245 goto EXIT;
246 }
247
248 /* check mandatory functions for buffer ops */
249 if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
250 (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
251 (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
252 (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
253 (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
254 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
255 ret = OMX_ErrorInsufficientResources;
256 goto EXIT;
257 }
258
259 /* alloc context, open, querycap */
260 #ifdef USE_DMA_BUF
261 pVideoInstInfo->nMemoryType = V4L2_MEMORY_DMABUF;
262 #else
263 pVideoInstInfo->nMemoryType = V4L2_MEMORY_USERPTR;
264 #endif
265 pVp9Dec->hMFCVp9Handle.hMFCHandle = pVp9Dec->hMFCVp9Handle.pDecOps->Init(pVideoInstInfo);
266 if (pVp9Dec->hMFCVp9Handle.hMFCHandle == NULL) {
267 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
268 ret = OMX_ErrorInsufficientResources;
269 goto EXIT;
270 }
271
272 ret = OMX_ErrorNone;
273
274 EXIT:
275 if (ret != OMX_ErrorNone) {
276 if (pDecOps != NULL) {
277 Exynos_OSAL_Free(pDecOps);
278 pVp9Dec->hMFCVp9Handle.pDecOps = NULL;
279 }
280 if (pInbufOps != NULL) {
281 Exynos_OSAL_Free(pInbufOps);
282 pVp9Dec->hMFCVp9Handle.pInbufOps = NULL;
283 }
284 if (pOutbufOps != NULL) {
285 Exynos_OSAL_Free(pOutbufOps);
286 pVp9Dec->hMFCVp9Handle.pOutbufOps = NULL;
287 }
288 }
289
290 FunctionOut();
291
292 return ret;
293 }
294
295 OMX_ERRORTYPE VP9CodecClose(EXYNOS_VP9DEC_HANDLE *pVp9Dec)
296 {
297 OMX_ERRORTYPE ret = OMX_ErrorNone;
298 void *hMFCHandle = NULL;
299 ExynosVideoDecOps *pDecOps = NULL;
300 ExynosVideoDecBufferOps *pInbufOps = NULL;
301 ExynosVideoDecBufferOps *pOutbufOps = NULL;
302
303 FunctionIn();
304
305 if (pVp9Dec == NULL) {
306 ret = OMX_ErrorBadParameter;
307 goto EXIT;
308 }
309
310 hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
311 pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
312 pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
313 pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
314
315 if (hMFCHandle != NULL) {
316 pDecOps->Finalize(hMFCHandle);
317 pVp9Dec->hMFCVp9Handle.hMFCHandle = NULL;
318 }
319
320 /* Unregister function pointers */
321 Exynos_Video_Unregister_Decoder(pDecOps, pInbufOps, pOutbufOps);
322
323 if (pOutbufOps != NULL) {
324 Exynos_OSAL_Free(pOutbufOps);
325 pVp9Dec->hMFCVp9Handle.pOutbufOps = NULL;
326 }
327 if (pInbufOps != NULL) {
328 Exynos_OSAL_Free(pInbufOps);
329 pVp9Dec->hMFCVp9Handle.pInbufOps = NULL;
330 }
331 if (pDecOps != NULL) {
332 Exynos_OSAL_Free(pDecOps);
333 pVp9Dec->hMFCVp9Handle.pDecOps = NULL;
334 }
335
336 ret = OMX_ErrorNone;
337
338 EXIT:
339 FunctionOut();
340
341 return ret;
342 }
343
344 OMX_ERRORTYPE VP9CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
345 {
346 OMX_ERRORTYPE ret = OMX_ErrorNone;
347 void *hMFCHandle = NULL;
348 ExynosVideoDecOps *pDecOps = NULL;
349 ExynosVideoDecBufferOps *pInbufOps = NULL;
350 ExynosVideoDecBufferOps *pOutbufOps = NULL;
351 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
352 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
353
354 FunctionIn();
355
356 if (pOMXComponent == NULL) {
357 ret = OMX_ErrorBadParameter;
358 goto EXIT;
359 }
360
361 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
362 if (pVideoDec == NULL) {
363 ret = OMX_ErrorBadParameter;
364 goto EXIT;
365 }
366
367 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
368 if (pVp9Dec == NULL) {
369 ret = OMX_ErrorBadParameter;
370 goto EXIT;
371 }
372
373 hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
374 pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
375 pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
376 pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
377
378 if (nPortIndex == INPUT_PORT_INDEX)
379 pInbufOps->Run(hMFCHandle);
380 else if (nPortIndex == OUTPUT_PORT_INDEX)
381 pOutbufOps->Run(hMFCHandle);
382
383 ret = OMX_ErrorNone;
384
385 EXIT:
386 FunctionOut();
387
388 return ret;
389 }
390
391 OMX_ERRORTYPE VP9CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
392 {
393 OMX_ERRORTYPE ret = OMX_ErrorNone;
394 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
395 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
396 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
397 void *hMFCHandle = NULL;
398 ExynosVideoDecOps *pDecOps = NULL;
399 ExynosVideoDecBufferOps *pInbufOps = NULL;
400 ExynosVideoDecBufferOps *pOutbufOps = NULL;
401
402 FunctionIn();
403
404 if (pOMXComponent == NULL) {
405 ret = OMX_ErrorBadParameter;
406 goto EXIT;
407 }
408
409 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
410 if (pExynosComponent == NULL) {
411 ret = OMX_ErrorBadParameter;
412 goto EXIT;
413 }
414
415 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
416 if (pVideoDec == NULL) {
417 ret = OMX_ErrorBadParameter;
418 goto EXIT;
419 }
420
421 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
422 if (pVp9Dec == NULL) {
423 ret = OMX_ErrorBadParameter;
424 goto EXIT;
425 }
426
427 hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
428 pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
429 pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
430 pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
431
432 if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL)) {
433 pInbufOps->Stop(hMFCHandle);
434 } else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL)) {
435 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
436
437 pOutbufOps->Stop(hMFCHandle);
438
439 if ((pOutputPort->bufferProcessType & BUFFER_SHARE) &&
440 (pOutputPort->bDynamicDPBMode == OMX_TRUE))
441 pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
442 }
443
444 ret = OMX_ErrorNone;
445
446 EXIT:
447 FunctionOut();
448
449 return ret;
450 }
451
452 OMX_ERRORTYPE VP9CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
453 {
454 OMX_ERRORTYPE ret = OMX_ErrorNone;
455 void *hMFCHandle = NULL;
456 ExynosVideoDecOps *pDecOps = NULL;
457 ExynosVideoDecBufferOps *pInbufOps = NULL;
458 ExynosVideoDecBufferOps *pOutbufOps = NULL;
459 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
460 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
461
462 FunctionIn();
463
464 if (pOMXComponent == NULL) {
465 ret = OMX_ErrorBadParameter;
466 goto EXIT;
467 }
468
469 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
470 if (pVideoDec == NULL) {
471 ret = OMX_ErrorBadParameter;
472 goto EXIT;
473 }
474 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
475 if (pVp9Dec == NULL) {
476 ret = OMX_ErrorBadParameter;
477 goto EXIT;
478 }
479
480 hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
481 pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
482 pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
483 pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
484
485 if (nPortIndex == INPUT_PORT_INDEX) {
486 if (pVp9Dec->bSourceStart == OMX_FALSE) {
487 Exynos_OSAL_SignalSet(pVp9Dec->hSourceStartEvent);
488 Exynos_OSAL_SleepMillisec(0);
489 }
490 }
491
492 if (nPortIndex == OUTPUT_PORT_INDEX) {
493 if (pVp9Dec->bDestinationStart == OMX_FALSE) {
494 Exynos_OSAL_SignalSet(pVp9Dec->hDestinationStartEvent);
495 Exynos_OSAL_SleepMillisec(0);
496 }
497 }
498
499 ret = OMX_ErrorNone;
500
501 EXIT:
502 FunctionOut();
503
504 return ret;
505 }
506
507 OMX_ERRORTYPE VP9CodecRegistCodecBuffers(
508 OMX_COMPONENTTYPE *pOMXComponent,
509 OMX_U32 nPortIndex,
510 int nBufferCnt)
511 {
512 OMX_ERRORTYPE ret = OMX_ErrorNone;
513 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
514 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
515 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
516 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
517 CODEC_DEC_BUFFER **ppCodecBuffer = NULL;
518 ExynosVideoDecBufferOps *pBufOps = NULL;
519 ExynosVideoPlane *pPlanes = NULL;
520
521 int nPlaneCnt = 0;
522 int i, j;
523
524 FunctionIn();
525
526 if (nPortIndex == INPUT_PORT_INDEX) {
527 ppCodecBuffer = &(pVideoDec->pMFCDecInputBuffer[0]);
528 pBufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
529 } else {
530 ppCodecBuffer = &(pVideoDec->pMFCDecOutputBuffer[0]);
531 pBufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
532 }
533
534 nPlaneCnt = Exynos_GetPlaneFromPort(&pExynosComponent->pExynosPort[nPortIndex]);
535 pPlanes = (ExynosVideoPlane *)Exynos_OSAL_Malloc(sizeof(ExynosVideoPlane) * nPlaneCnt);
536 if (pPlanes == NULL) {
537 ret = OMX_ErrorInsufficientResources;
538 goto EXIT;
539 }
540
541 /* Register buffer */
542 for (i = 0; i < nBufferCnt; i++) {
543 for (j = 0; j < nPlaneCnt; j++) {
544 pPlanes[j].addr = ppCodecBuffer[i]->pVirAddr[j];
545 pPlanes[j].fd = ppCodecBuffer[i]->fd[j];
546 pPlanes[j].allocSize = ppCodecBuffer[i]->bufferSize[j];
547 }
548
549 if (pBufOps->Register(hMFCHandle, pPlanes, nPlaneCnt) != VIDEO_ERROR_NONE) {
550 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "PORT[%d]: Failed to Register buffer", nPortIndex);
551 ret = OMX_ErrorInsufficientResources;
552 Exynos_OSAL_Free(pPlanes);
553 goto EXIT;
554 }
555 }
556
557 Exynos_OSAL_Free(pPlanes);
558
559 ret = OMX_ErrorNone;
560
561 EXIT:
562 FunctionOut();
563
564 return ret;
565 }
566
567 OMX_ERRORTYPE Vp9CodecReconfigAllBuffers(
568 OMX_COMPONENTTYPE *pOMXComponent,
569 OMX_U32 nPortIndex)
570 {
571 OMX_ERRORTYPE ret = OMX_ErrorNone;
572 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
573 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
574 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[nPortIndex];
575 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
576 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
577 ExynosVideoDecBufferOps *pBufferOps = NULL;
578
579 FunctionIn();
580
581 if ((nPortIndex == INPUT_PORT_INDEX) &&
582 (pVp9Dec->bSourceStart == OMX_TRUE)) {
583 ret = OMX_ErrorNotImplemented;
584 goto EXIT;
585 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
586 (pVp9Dec->bDestinationStart == OMX_TRUE)) {
587 pBufferOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
588
589 if (pExynosPort->bufferProcessType & BUFFER_COPY) {
590 /**********************************/
591 /* Codec Buffer Free & Unregister */
592 /**********************************/
593 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
594 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
595 pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
596 pBufferOps->Cleanup_Buffer(hMFCHandle);
597
598 /******************************************************/
599 /* V4L2 Destnation Setup for DPB Buffer Number Change */
600 /******************************************************/
601 ret = VP9CodecDstSetup(pOMXComponent);
602 if (ret != OMX_ErrorNone) {
603 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
604 goto EXIT;
605 }
606
607 pVideoDec->bReconfigDPB = OMX_FALSE;
608 } else if (pExynosPort->bufferProcessType & BUFFER_SHARE) {
609 /**********************************/
610 /* Codec Buffer Unregister */
611 /**********************************/
612 pBufferOps->Clear_RegisteredBuffer(hMFCHandle);
613 pBufferOps->Cleanup_Buffer(hMFCHandle);
614 }
615
616 Exynos_ResolutionUpdate(pOMXComponent);
617 } else {
618 ret = OMX_ErrorBadParameter;
619 goto EXIT;
620 }
621
622 EXIT:
623 FunctionOut();
624
625 return ret;
626 }
627
628 OMX_ERRORTYPE VP9CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
629 {
630 OMX_ERRORTYPE ret = OMX_ErrorNone;
631 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
632 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
633 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
634 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
635 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
636 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
637 int i, nOutbufs;
638
639 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
640 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
641 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
642
643 FunctionIn();
644
645 if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
646 ret = OMX_ErrorBadPortIndex;
647 goto EXIT;
648 }
649
650 if ((nPortIndex == INPUT_PORT_INDEX) &&
651 (pVp9Dec->bSourceStart == OMX_TRUE)) {
652 Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
653
654 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
655 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
656 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
657
658 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
659 }
660
661 pInbufOps->Clear_Queue(hMFCHandle);
662 } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
663 (pVp9Dec->bDestinationStart == OMX_TRUE)) {
664 Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
665
666 for (i = 0; i < pVp9Dec->hMFCVp9Handle.maxDPBNum; i++) {
667 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]);
668 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]);
669
670 Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, pVideoDec->pMFCDecOutputBuffer[i]);
671 }
672 pOutbufOps->Clear_Queue(hMFCHandle);
673 }
674
675 EXIT:
676 FunctionOut();
677
678 return ret;
679 }
680
681 OMX_ERRORTYPE Vp9CodecCheckResolution(OMX_COMPONENTTYPE *pOMXComponent)
682 {
683 OMX_ERRORTYPE ret = OMX_ErrorNone;
684 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
685 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
686 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
687 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
688 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
689 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
690 EXYNOS_OMX_EXCEPTION_STATE eOutputExcepState = pOutputPort->exceptionFlag;
691
692 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
693 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
694 ExynosVideoGeometry codecOutbufConf;
695
696 OMX_CONFIG_RECTTYPE *pCropRectangle = &(pOutputPort->cropRectangle);
697 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = &(pInputPort->portDefinition);
698 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = &(pOutputPort->portDefinition);
699
700 int maxDPBNum = 0;
701
702 FunctionIn();
703
704 /* get geometry */
705 Exynos_OSAL_Memset(&codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
706 if (pOutbufOps->Get_Geometry(hMFCHandle, &codecOutbufConf) != VIDEO_ERROR_NONE) {
707 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry");
708 ret = OMX_ErrorHardware;
709 goto EXIT;
710 }
711
712 /* get dpb count */
713 maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
714 if (pVideoDec->bThumbnailMode == OMX_FALSE)
715 maxDPBNum += EXTRA_DPB_NUM;
716
717 if ((codecOutbufConf.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
718 (codecOutbufConf.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight) ||
719 (codecOutbufConf.nStride != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nStride) ||
720 #if 0 // TODO: check posibility
721 (codecOutbufConf.eColorFormat != pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat) ||
722 (codecOutbufConf.eFilledDataType != pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType) ||
723 (codecOutbufConf.bInterlaced != pVp9Dec->hMFCVp9Handle.codecOutbufConf.bInterlaced) ||
724 #endif
725 (maxDPBNum != pVp9Dec->hMFCVp9Handle.maxDPBNum)) {
726 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: W(%d), H(%d) -> W(%d), H(%d)",
727 pExynosComponent, __FUNCTION__,
728 codecOutbufConf.nFrameWidth,
729 codecOutbufConf.nFrameHeight,
730 pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth,
731 pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight);
732 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] DRC: DPB(%d), FORMAT(0x%x), TYPE(0x%x) -> DPB(%d), FORMAT(0x%x), TYPE(0x%x)",
733 pExynosComponent, __FUNCTION__,
734 maxDPBNum, codecOutbufConf.eColorFormat, codecOutbufConf.eFilledDataType,
735 pVp9Dec->hMFCVp9Handle.maxDPBNum,
736 pVp9Dec->hMFCVp9Handle.codecOutbufConf.eColorFormat,
737 pVp9Dec->hMFCVp9Handle.codecOutbufConf.eFilledDataType);
738
739 pInputPortDefinition->format.video.nFrameWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
740 pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
741 pInputPortDefinition->format.video.nStride = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
742 pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
743
744 if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
745 pOutputPortDefinition->nBufferCountActual = pVp9Dec->hMFCVp9Handle.maxDPBNum;
746 pOutputPortDefinition->nBufferCountMin = pVp9Dec->hMFCVp9Handle.maxDPBNum;
747 }
748
749 Exynos_UpdateFrameSize(pOMXComponent);
750
751 if (eOutputExcepState == GENERAL_STATE) {
752 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
753
754 /** Send Port Settings changed call back **/
755 (*(pExynosComponent->pCallbacks->EventHandler))
756 (pOMXComponent,
757 pExynosComponent->callbackData,
758 OMX_EventPortSettingsChanged, /* The command was completed */
759 OMX_DirOutput, /* This is the port index */
760 0,
761 NULL);
762 }
763 }
764
765 if ((codecOutbufConf.cropRect.nTop != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nTop) ||
766 (codecOutbufConf.cropRect.nLeft != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nLeft) ||
767 (codecOutbufConf.cropRect.nWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth) ||
768 (codecOutbufConf.cropRect.nHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight)) {
769 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CROP: W(%d), H(%d) -> W(%d), H(%d)",
770 pExynosComponent, __FUNCTION__,
771 codecOutbufConf.cropRect.nWidth,
772 codecOutbufConf.cropRect.nHeight,
773 pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth,
774 pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight);
775
776 pCropRectangle->nTop = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nTop;
777 pCropRectangle->nLeft = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nLeft;
778 pCropRectangle->nWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth;
779 pCropRectangle->nHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight;
780
781 /** Send crop info call back **/
782 (*(pExynosComponent->pCallbacks->EventHandler))
783 (pOMXComponent,
784 pExynosComponent->callbackData,
785 OMX_EventPortSettingsChanged, /* The command was completed */
786 OMX_DirOutput, /* This is the port index */
787 OMX_IndexConfigCommonOutputCrop,
788 NULL);
789 }
790
791 Exynos_OSAL_Memcpy(&pVp9Dec->hMFCVp9Handle.codecOutbufConf, &codecOutbufConf, sizeof(codecOutbufConf));
792 pVp9Dec->hMFCVp9Handle.maxDPBNum = maxDPBNum;
793
794 ret = OMX_ErrorNone;
795
796 EXIT:
797 FunctionOut();
798
799 return ret;
800 }
801
802 OMX_ERRORTYPE Vp9CodecUpdateResolution(OMX_COMPONENTTYPE *pOMXComponent)
803 {
804 OMX_ERRORTYPE ret = OMX_ErrorNone;
805 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
806 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
807 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
808 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
809 EXYNOS_OMX_BASEPORT *pInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
810 EXYNOS_OMX_BASEPORT *pOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
811 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
812 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
813
814 OMX_CONFIG_RECTTYPE *pCropRectangle = NULL;
815 OMX_PARAM_PORTDEFINITIONTYPE *pInputPortDefinition = NULL;
816 OMX_PARAM_PORTDEFINITIONTYPE *pOutputPortDefinition = NULL;
817
818 FunctionIn();
819
820 /* get geometry for output */
821 Exynos_OSAL_Memset(&pVp9Dec->hMFCVp9Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
822 if (pOutbufOps->Get_Geometry(hMFCHandle, &pVp9Dec->hMFCVp9Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
823 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
824 ret = OMX_ErrorCorruptedHeader;
825 goto EXIT;
826 }
827
828 /* get dpb count */
829 pVp9Dec->hMFCVp9Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
830 #if 0 /* no needs EXTRA_DPB, it was confirmed codec team */
831 if (pVideoDec->bThumbnailMode == OMX_FALSE)
832 pVp9Dec->hMFCVp9Handle.maxDPBNum += EXTRA_DPB_NUM;
833 #endif
834 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Vp9CodecSetup maxDPBNum: %d", pExynosComponent, __FUNCTION__, pVp9Dec->hMFCVp9Handle.maxDPBNum);
835
836 pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_TRUE;
837
838 if (pVideoDec->bReconfigDPB != OMX_TRUE) {
839 pCropRectangle = &(pOutputPort->cropRectangle);
840 pInputPortDefinition = &(pInputPort->portDefinition);
841 pOutputPortDefinition = &(pOutputPort->portDefinition);
842 } else {
843 pCropRectangle = &(pOutputPort->newCropRectangle);
844 pInputPortDefinition = &(pInputPort->newPortDefinition);
845 pOutputPortDefinition = &(pOutputPort->newPortDefinition);
846 }
847
848 pCropRectangle->nTop = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nTop;
849 pCropRectangle->nLeft = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nLeft;
850 pCropRectangle->nWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth;
851 pCropRectangle->nHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight;
852
853 if (pOutputPort->bufferProcessType & BUFFER_COPY) {
854 if ((pVideoDec->bReconfigDPB) ||
855 (pInputPort->portDefinition.format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
856 (pInputPort->portDefinition.format.video.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight)) {
857 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
858
859 pInputPortDefinition->format.video.nFrameWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
860 pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
861 pInputPortDefinition->format.video.nStride = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
862 pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
863
864 pOutputPortDefinition->nBufferCountActual = pOutputPort->portDefinition.nBufferCountActual;
865 pOutputPortDefinition->nBufferCountMin = pOutputPort->portDefinition.nBufferCountMin;
866
867 if (pVideoDec->bReconfigDPB != OMX_TRUE)
868 Exynos_UpdateFrameSize(pOMXComponent);
869
870 /** Send Port Settings changed call back **/
871 (*(pExynosComponent->pCallbacks->EventHandler))
872 (pOMXComponent,
873 pExynosComponent->callbackData,
874 OMX_EventPortSettingsChanged, /* The command was completed */
875 OMX_DirOutput, /* This is the port index */
876 0,
877 NULL);
878 }
879 } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
880 if ((pVideoDec->bReconfigDPB) ||
881 (pInputPort->portDefinition.format.video.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth) ||
882 (pInputPort->portDefinition.format.video.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight) ||
883 ((OMX_S32)pOutputPort->portDefinition.nBufferCountActual != pVp9Dec->hMFCVp9Handle.maxDPBNum)) {
884 pOutputPort->exceptionFlag = NEED_PORT_DISABLE;
885
886 pInputPortDefinition->format.video.nFrameWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
887 pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
888 pInputPortDefinition->format.video.nStride = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
889 pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
890
891 pOutputPortDefinition->nBufferCountActual = pVp9Dec->hMFCVp9Handle.maxDPBNum;
892 pOutputPortDefinition->nBufferCountMin = pVp9Dec->hMFCVp9Handle.maxDPBNum;
893
894 if (pVideoDec->bReconfigDPB != OMX_TRUE)
895 Exynos_UpdateFrameSize(pOMXComponent);
896
897 /** Send Port Settings changed call back **/
898 (*(pExynosComponent->pCallbacks->EventHandler))
899 (pOMXComponent,
900 pExynosComponent->callbackData,
901 OMX_EventPortSettingsChanged, /* The command was completed */
902 OMX_DirOutput, /* This is the port index */
903 0,
904 NULL);
905 }
906 }
907
908 if ((pVideoDec->bReconfigDPB != OMX_TRUE) &&
909 ((pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nWidth) ||
910 (pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight != pVp9Dec->hMFCVp9Handle.codecOutbufConf.cropRect.nHeight))) {
911 /* Check Crop */
912 pInputPortDefinition->format.video.nFrameWidth = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
913 pInputPortDefinition->format.video.nFrameHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
914 pInputPortDefinition->format.video.nStride = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameWidth;
915 pInputPortDefinition->format.video.nSliceHeight = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nFrameHeight;
916
917 Exynos_UpdateFrameSize(pOMXComponent);
918
919 /** Send crop info call back **/
920 (*(pExynosComponent->pCallbacks->EventHandler))
921 (pOMXComponent,
922 pExynosComponent->callbackData,
923 OMX_EventPortSettingsChanged, /* The command was completed */
924 OMX_DirOutput, /* This is the port index */
925 OMX_IndexConfigCommonOutputCrop,
926 NULL);
927 }
928
929 ret = OMX_ErrorNone;
930
931 EXIT:
932 FunctionOut();
933
934 return ret;
935 }
936
937 OMX_ERRORTYPE VP9CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
938 {
939 OMX_ERRORTYPE ret = OMX_ErrorNone;
940 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
941 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
942 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
943 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
944 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
945 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
946 OMX_COLOR_FORMATTYPE eOutputFormat = pExynosOutputPort->portDefinition.format.video.eColorFormat;
947 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
948
949 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
950 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
951 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
952 ExynosVideoGeometry bufferConf;
953
954 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
955 unsigned int nDataLen[MAX_BUFFER_PLANE] = {oneFrameSize, 0, 0};
956 OMX_U32 nInBufferCnt = 0;
957 OMX_BOOL bSupportFormat = OMX_FALSE;
958 int i;
959
960 FunctionIn();
961
962 if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
963 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Malloc(sizeof(BYPASS_BUFFER_INFO));
964 if (pBufferInfo == NULL) {
965 ret = OMX_ErrorInsufficientResources;
966 goto EXIT;
967 }
968
969 pBufferInfo->nFlags = pSrcInputData->nFlags;
970 pBufferInfo->timeStamp = pSrcInputData->timeStamp;
971 ret = Exynos_OSAL_Queue(&pVp9Dec->bypassBufferInfoQ, (void *)pBufferInfo);
972 Exynos_OSAL_SignalSet(pVp9Dec->hDestinationStartEvent);
973
974 ret = OMX_ErrorNone;
975 goto EXIT;
976 }
977
978 if (pVideoDec->bThumbnailMode == OMX_TRUE)
979 pDecOps->Set_IFrameDecoding(hMFCHandle);
980
981 if ((pDecOps->Enable_DTSMode != NULL) &&
982 (pVideoDec->bDTSMode == OMX_TRUE))
983 pDecOps->Enable_DTSMode(hMFCHandle);
984
985 /* input buffer info */
986 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
987 bufferConf.eCompressionFormat = VIDEO_CODING_VP9;
988 pInbufOps->Set_Shareable(hMFCHandle);
989 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
990 bufferConf.nSizeImage = pExynosInputPort->portDefinition.nBufferSize;
991 } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
992 bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
993 }
994 bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosInputPort);
995 nInBufferCnt = MAX_INPUTBUFFER_NUM_DYNAMIC;
996
997 /* should be done before prepare input buffer */
998 if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
999 ret = OMX_ErrorInsufficientResources;
1000 goto EXIT;
1001 }
1002
1003 /* set input buffer geometry */
1004 if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1005 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
1006 ret = OMX_ErrorInsufficientResources;
1007 goto EXIT;
1008 }
1009
1010 /* setup input buffer */
1011 if (pInbufOps->Setup(hMFCHandle, nInBufferCnt) != VIDEO_ERROR_NONE) {
1012 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
1013 ret = OMX_ErrorInsufficientResources;
1014 goto EXIT;
1015 }
1016
1017 /* set output geometry */
1018 Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1019
1020 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eOutputFormat);
1021 if (bSupportFormat == OMX_TRUE) { /* supported by H/W */
1022 if ((pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport == VIDEO_TRUE) &&
1023 (eOutputFormat != (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12Tiled)) {
1024 /* Needs to eanble DualDPB feature */
1025 if (pDecOps->Enable_DualDPBMode(hMFCHandle) != VIDEO_ERROR_NONE) {
1026 ret = OMX_ErrorHardware;
1027 goto EXIT;
1028 }
1029 }
1030 bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eOutputFormat, pExynosOutputPort->ePlaneType);
1031 Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eOutputFormat, pExynosOutputPort->ePlaneType));
1032 } else {
1033 OMX_COLOR_FORMATTYPE eCheckFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1034 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
1035 if (bSupportFormat != OMX_TRUE) {
1036 eCheckFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1037 bSupportFormat = CheckFormatHWSupport(pExynosComponent, eCheckFormat);
1038 }
1039 if (bSupportFormat == OMX_TRUE) { /* supported by CSC(NV12T/NV12 -> format) */
1040 bufferConf.eColorFormat = Exynos_OSAL_OMX2VideoFormat(eCheckFormat, pExynosOutputPort->ePlaneType);
1041 Exynos_SetPlaneToPort(pExynosOutputPort, Exynos_OSAL_GetPlaneCount(eCheckFormat, pExynosOutputPort->ePlaneType));
1042 } else {
1043 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not support this format (0x%x)", eOutputFormat);
1044 ret = OMX_ErrorNotImplemented;
1045 goto EXIT;
1046 }
1047 }
1048
1049 pVp9Dec->hMFCVp9Handle.MFCOutputColorType = bufferConf.eColorFormat;
1050 bufferConf.nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
1051 if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1052 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1053 ret = OMX_ErrorInsufficientResources;
1054 goto EXIT;
1055 }
1056
1057 /* input buffer enqueue for header parsing */
1058 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] Header Size: %d", pExynosComponent, __FUNCTION__, oneFrameSize);
1059 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
1060 nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
1061 else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
1062 nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1063
1064 /* set buffer process type */
1065 if (pDecOps->Set_BufferProcessType(hMFCHandle, pExynosOutputPort->bufferProcessType) != VIDEO_ERROR_NONE) {
1066 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set buffer process type(not supported)");
1067 }
1068
1069 if (pInbufOps->ExtensionEnqueue(hMFCHandle,
1070 (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
1071 (int *)pSrcInputData->multiPlaneBuffer.fd,
1072 nAllocLen,
1073 nDataLen,
1074 Exynos_GetPlaneFromPort(pExynosInputPort),
1075 pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
1076 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
1077 // ret = OMX_ErrorInsufficientResources;
1078 ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
1079 goto EXIT;
1080 }
1081
1082 /* start header parsing */
1083 if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1084 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
1085 ret = OMX_ErrorCodecInit;
1086 goto EXIT;
1087 }
1088
1089 ret = Vp9CodecUpdateResolution(pOMXComponent);
1090 if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
1091 (pExynosComponent->codecType != HW_VIDEO_DEC_SECURE_CODEC) &&
1092 (oneFrameSize >= 8))
1093 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "CorruptedHeader Info : %02x %02x %02x %02x %02x %02x %02x %02x ...",
1094 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0]) , *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 1),
1095 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 2), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 3),
1096 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 4), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 5),
1097 *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 6), *((OMX_U8 *)pSrcInputData->multiPlaneBuffer.dataBuffer[0] + 7));
1098 if (ret != OMX_ErrorNone) {
1099 VP9CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1100 pInbufOps->Cleanup_Buffer(hMFCHandle);
1101 goto EXIT;
1102 }
1103
1104 Exynos_OSAL_SleepMillisec(0);
1105 ret = OMX_ErrorInputDataDecodeYet;
1106 VP9CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1107
1108 EXIT:
1109 FunctionOut();
1110
1111 return ret;
1112 }
1113
1114 OMX_ERRORTYPE VP9CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
1115 {
1116 OMX_ERRORTYPE ret = OMX_ErrorNone;
1117 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1118 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1119 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
1120 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
1121 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1122 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1123
1124 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
1125 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
1126 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
1127
1128 int i, nOutbufs, nPlaneCnt;
1129
1130 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1131 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1132
1133 FunctionIn();
1134
1135 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
1136 for (i = 0; i < nPlaneCnt; i++)
1137 nAllocLen[i] = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nAlignPlaneSize[i];
1138
1139 if (pExynosOutputPort->bDynamicDPBMode == OMX_TRUE) {
1140 if (pDecOps->Enable_DynamicDPB(hMFCHandle) != VIDEO_ERROR_NONE) {
1141 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enable Dynamic DPB");
1142 ret = OMX_ErrorHardware;
1143 goto EXIT;
1144 }
1145 }
1146
1147 pOutbufOps->Set_Shareable(hMFCHandle);
1148
1149 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1150 /* should be done before prepare output buffer */
1151 if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1152 ret = OMX_ErrorInsufficientResources;
1153 goto EXIT;
1154 }
1155
1156 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
1157 /* get dpb count */
1158 nOutbufs = pVp9Dec->hMFCVp9Handle.maxDPBNum;
1159 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1160 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1161 ret = OMX_ErrorInsufficientResources;
1162 goto EXIT;
1163 }
1164
1165 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
1166 if (ret != OMX_ErrorNone)
1167 goto EXIT;
1168
1169 /* Register output buffer */
1170 ret = VP9CodecRegistCodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs);
1171 if (ret != OMX_ErrorNone)
1172 goto EXIT;
1173
1174 /* Enqueue output buffer */
1175 for (i = 0; i < nOutbufs; i++)
1176 pOutbufOps->Enqueue(hMFCHandle,
1177 (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1178 nDataLen,
1179 nPlaneCnt,
1180 NULL);
1181 } else {
1182 if (pOutbufOps->Setup(hMFCHandle, MAX_OUTPUTBUFFER_NUM_DYNAMIC) != VIDEO_ERROR_NONE) {
1183 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1184 ret = OMX_ErrorInsufficientResources;
1185 goto EXIT;
1186 }
1187
1188 /* get dpb count */
1189 nOutbufs = pVp9Dec->hMFCVp9Handle.maxDPBNum;
1190 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX, nOutbufs, nAllocLen);
1191 if (ret != OMX_ErrorNone)
1192 goto EXIT;
1193
1194 /* without Register output buffer */
1195
1196 /* Enqueue output buffer */
1197 for (i = 0; i < nOutbufs; i++) {
1198 pOutbufOps->ExtensionEnqueue(hMFCHandle,
1199 (void **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1200 (int *)pVideoDec->pMFCDecOutputBuffer[i]->fd,
1201 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize,
1202 nDataLen,
1203 nPlaneCnt,
1204 NULL);
1205 }
1206 }
1207
1208 if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1209 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1210 ret = OMX_ErrorInsufficientResources;
1211 goto EXIT;
1212 }
1213 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1214 #ifdef USE_ANB
1215 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
1216 ExynosVideoPlane planes[MAX_BUFFER_PLANE];
1217 int plane;
1218
1219 Exynos_OSAL_Memset((OMX_PTR)planes, 0, sizeof(ExynosVideoPlane) * MAX_BUFFER_PLANE);
1220
1221 /* get dpb count */
1222 nOutbufs = pExynosOutputPort->portDefinition.nBufferCountActual;
1223 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1224 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1225 ret = OMX_ErrorInsufficientResources;
1226 goto EXIT;
1227 }
1228
1229 if ((pExynosOutputPort->bIsANBEnabled == OMX_TRUE) &&
1230 (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
1231 for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
1232 for (plane = 0; plane < nPlaneCnt; plane++) {
1233 planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
1234 planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
1235 planes[plane].allocSize = nAllocLen[plane];
1236 }
1237
1238 if (pOutbufOps->Register(hMFCHandle, planes, nPlaneCnt) != VIDEO_ERROR_NONE) {
1239 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1240 ret = OMX_ErrorInsufficientResources;
1241 goto EXIT;
1242 }
1243 pOutbufOps->Enqueue(hMFCHandle,
1244 (void **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
1245 nDataLen,
1246 nPlaneCnt,
1247 NULL);
1248 }
1249
1250 if (pOutbufOps->Apply_RegisteredBuffer(hMFCHandle) != VIDEO_ERROR_NONE) {
1251 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Apply output buffer");
1252 ret = OMX_ErrorHardware;
1253 goto EXIT;
1254 }
1255 } else {
1256 /*************/
1257 /* TBD */
1258 /*************/
1259 ret = OMX_ErrorNotImplemented;
1260 goto EXIT;
1261 }
1262 } else {
1263 /* get dpb count */
1264 nOutbufs = MAX_OUTPUTBUFFER_NUM_DYNAMIC;
1265 if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1266 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1267 ret = OMX_ErrorInsufficientResources;
1268 goto EXIT;
1269 }
1270
1271 if ((pExynosOutputPort->bIsANBEnabled == OMX_FALSE) &&
1272 (pExynosOutputPort->bStoreMetaData == OMX_FALSE)) {
1273 /*************/
1274 /* TBD */
1275 /*************/
1276 ret = OMX_ErrorNotImplemented;
1277 goto EXIT;
1278 }
1279 }
1280 #else
1281 /*************/
1282 /* TBD */
1283 /*************/
1284 ret = OMX_ErrorNotImplemented;
1285 goto EXIT;
1286 #endif
1287 }
1288
1289 pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_TRUE;
1290
1291 ret = OMX_ErrorNone;
1292
1293 EXIT:
1294 FunctionOut();
1295
1296 return ret;
1297 }
1298
1299 OMX_ERRORTYPE Exynos_VP9Dec_GetParameter(
1300 OMX_IN OMX_HANDLETYPE hComponent,
1301 OMX_IN OMX_INDEXTYPE nParamIndex,
1302 OMX_INOUT OMX_PTR pComponentParameterStructure)
1303 {
1304 OMX_ERRORTYPE ret = OMX_ErrorNone;
1305 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1306 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1307
1308 FunctionIn();
1309
1310 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1311 ret = OMX_ErrorBadParameter;
1312 goto EXIT;
1313 }
1314 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1315 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1316 if (ret != OMX_ErrorNone) {
1317 goto EXIT;
1318 }
1319 if (pOMXComponent->pComponentPrivate == NULL) {
1320 ret = OMX_ErrorBadParameter;
1321 goto EXIT;
1322 }
1323
1324 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1325 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1326 ret = OMX_ErrorInvalidState;
1327 goto EXIT;
1328 }
1329
1330 switch (nParamIndex) {
1331 case OMX_IndexParamStandardComponentRole:
1332 {
1333 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1334 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1335 if (ret != OMX_ErrorNone) {
1336 goto EXIT;
1337 }
1338
1339 Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
1340 }
1341 break;
1342 case OMX_IndexParamVideoErrorCorrection:
1343 {
1344 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1345 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1346 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
1347
1348 ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1349 if (ret != OMX_ErrorNone) {
1350 goto EXIT;
1351 }
1352
1353 if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1354 ret = OMX_ErrorBadPortIndex;
1355 goto EXIT;
1356 }
1357
1358 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1359 pSrcErrorCorrectionType = &pVp9Dec->errorCorrectionType[INPUT_PORT_INDEX];
1360
1361 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1362 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1363 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1364 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1365 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1366 }
1367 break;
1368 default:
1369 ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1370 break;
1371 }
1372 EXIT:
1373 FunctionOut();
1374
1375 return ret;
1376 }
1377
1378 OMX_ERRORTYPE Exynos_VP9Dec_SetParameter(
1379 OMX_IN OMX_HANDLETYPE hComponent,
1380 OMX_IN OMX_INDEXTYPE nIndex,
1381 OMX_IN OMX_PTR pComponentParameterStructure)
1382 {
1383 OMX_ERRORTYPE ret = OMX_ErrorNone;
1384 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1385 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1386
1387 FunctionIn();
1388
1389 if (hComponent == NULL || pComponentParameterStructure == NULL) {
1390 ret = OMX_ErrorBadParameter;
1391 goto EXIT;
1392 }
1393 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1394 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1395 if (ret != OMX_ErrorNone) {
1396 goto EXIT;
1397 }
1398 if (pOMXComponent->pComponentPrivate == NULL) {
1399 ret = OMX_ErrorBadParameter;
1400 goto EXIT;
1401 }
1402
1403 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1404 if (pExynosComponent->currentState == OMX_StateInvalid ) {
1405 ret = OMX_ErrorInvalidState;
1406 goto EXIT;
1407 }
1408
1409 switch (nIndex) {
1410 case OMX_IndexParamStandardComponentRole:
1411 {
1412 OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1413
1414 ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1415 if (ret != OMX_ErrorNone) {
1416 goto EXIT;
1417 }
1418
1419 if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1420 ret = OMX_ErrorIncorrectStateOperation;
1421 goto EXIT;
1422 }
1423
1424 if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE)) {
1425 pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
1426 } else {
1427 ret = OMX_ErrorBadParameter;
1428 goto EXIT;
1429 }
1430 }
1431 break;
1432 case OMX_IndexParamVideoErrorCorrection:
1433 {
1434 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1435 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1436 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
1437
1438 ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1439 if (ret != OMX_ErrorNone) {
1440 goto EXIT;
1441 }
1442
1443 if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1444 ret = OMX_ErrorBadPortIndex;
1445 goto EXIT;
1446 }
1447
1448 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1449 pDstErrorCorrectionType = &pVp9Dec->errorCorrectionType[INPUT_PORT_INDEX];
1450
1451 pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1452 pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1453 pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1454 pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1455 pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1456 }
1457 break;
1458 default:
1459 ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1460 break;
1461 }
1462 EXIT:
1463 FunctionOut();
1464
1465 return ret;
1466 }
1467
1468 OMX_ERRORTYPE Exynos_VP9Dec_GetConfig(
1469 OMX_HANDLETYPE hComponent,
1470 OMX_INDEXTYPE nIndex,
1471 OMX_PTR pComponentConfigStructure)
1472 {
1473 OMX_ERRORTYPE ret = OMX_ErrorNone;
1474 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1475 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1476
1477 FunctionIn();
1478
1479 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1480 ret = OMX_ErrorBadParameter;
1481 goto EXIT;
1482 }
1483 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1484 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1485 if (ret != OMX_ErrorNone) {
1486 goto EXIT;
1487 }
1488 if (pOMXComponent->pComponentPrivate == NULL) {
1489 ret = OMX_ErrorBadParameter;
1490 goto EXIT;
1491 }
1492 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1493 if (pExynosComponent->currentState == OMX_StateInvalid) {
1494 ret = OMX_ErrorInvalidState;
1495 goto EXIT;
1496 }
1497
1498 switch (nIndex) {
1499 case OMX_IndexConfigCommonOutputCrop:
1500 {
1501 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
1502 OMX_CONFIG_RECTTYPE *pSrcRectType = NULL;
1503 OMX_CONFIG_RECTTYPE *pDstRectType = NULL;
1504
1505 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1506
1507 if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
1508 ret = OMX_ErrorNotReady;
1509 break;
1510 }
1511
1512 pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
1513
1514 if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
1515 (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
1516 ret = OMX_ErrorBadPortIndex;
1517 goto EXIT;
1518 }
1519
1520 EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
1521
1522 pSrcRectType = &(pExynosPort->cropRectangle);
1523
1524 pDstRectType->nTop = pSrcRectType->nTop;
1525 pDstRectType->nLeft = pSrcRectType->nLeft;
1526 pDstRectType->nHeight = pSrcRectType->nHeight;
1527 pDstRectType->nWidth = pSrcRectType->nWidth;
1528 }
1529 break;
1530 default:
1531 ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1532 break;
1533 }
1534
1535 EXIT:
1536 FunctionOut();
1537
1538 return ret;
1539 }
1540
1541 OMX_ERRORTYPE Exynos_VP9Dec_SetConfig(
1542 OMX_HANDLETYPE hComponent,
1543 OMX_INDEXTYPE nIndex,
1544 OMX_PTR pComponentConfigStructure)
1545 {
1546 OMX_ERRORTYPE ret = OMX_ErrorNone;
1547 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1548 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1549
1550 FunctionIn();
1551
1552 if (hComponent == NULL || pComponentConfigStructure == NULL) {
1553 ret = OMX_ErrorBadParameter;
1554 goto EXIT;
1555 }
1556 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1557 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1558 if (ret != OMX_ErrorNone) {
1559 goto EXIT;
1560 }
1561 if (pOMXComponent->pComponentPrivate == NULL) {
1562 ret = OMX_ErrorBadParameter;
1563 goto EXIT;
1564 }
1565 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1566 if (pExynosComponent->currentState == OMX_StateInvalid) {
1567 ret = OMX_ErrorInvalidState;
1568 goto EXIT;
1569 }
1570
1571 switch (nIndex) {
1572 default:
1573 ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1574 break;
1575 }
1576
1577 EXIT:
1578 FunctionOut();
1579
1580 return ret;
1581 }
1582
1583 OMX_ERRORTYPE Exynos_VP9Dec_GetExtensionIndex(
1584 OMX_IN OMX_HANDLETYPE hComponent,
1585 OMX_IN OMX_STRING cParameterName,
1586 OMX_OUT OMX_INDEXTYPE *pIndexType)
1587 {
1588 OMX_ERRORTYPE ret = OMX_ErrorNone;
1589 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1590 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1591
1592 FunctionIn();
1593
1594 if (hComponent == NULL) {
1595 ret = OMX_ErrorBadParameter;
1596 goto EXIT;
1597 }
1598 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1599 ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1600 if (ret != OMX_ErrorNone) {
1601 goto EXIT;
1602 }
1603 if (pOMXComponent->pComponentPrivate == NULL) {
1604 ret = OMX_ErrorBadParameter;
1605 goto EXIT;
1606 }
1607 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1608 if ((cParameterName == NULL) || (pIndexType == NULL)) {
1609 ret = OMX_ErrorBadParameter;
1610 goto EXIT;
1611 }
1612 if (pExynosComponent->currentState == OMX_StateInvalid) {
1613 ret = OMX_ErrorInvalidState;
1614 goto EXIT;
1615 }
1616
1617 ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1618
1619 EXIT:
1620 FunctionOut();
1621
1622 return ret;
1623 }
1624
1625 OMX_ERRORTYPE Exynos_VP9Dec_ComponentRoleEnum(
1626 OMX_HANDLETYPE hComponent,
1627 OMX_U8 *cRole,
1628 OMX_U32 nIndex)
1629 {
1630 OMX_ERRORTYPE ret = OMX_ErrorNone;
1631 OMX_COMPONENTTYPE *pOMXComponent = NULL;
1632 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1633
1634 FunctionIn();
1635
1636 if ((hComponent == NULL) || (cRole == NULL)) {
1637 ret = OMX_ErrorBadParameter;
1638 goto EXIT;
1639 }
1640 if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1641 Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_VP9_DEC_ROLE);
1642 ret = OMX_ErrorNone;
1643 } else {
1644 ret = OMX_ErrorNoMore;
1645 }
1646
1647 EXIT:
1648 FunctionOut();
1649
1650 return ret;
1651 }
1652
1653 /* MFC Init */
1654 OMX_ERRORTYPE Exynos_VP9Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1655 {
1656 OMX_ERRORTYPE ret = OMX_ErrorNone;
1657 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1658 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1659 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1660 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1661 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
1662 OMX_PTR hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
1663
1664 ExynosVideoDecOps *pDecOps = NULL;
1665 ExynosVideoDecBufferOps *pInbufOps = NULL;
1666 ExynosVideoDecBufferOps *pOutbufOps = NULL;
1667 ExynosVideoInstInfo *pVideoInstInfo = &(pVp9Dec->hMFCVp9Handle.videoInstInfo);
1668
1669 CSC_METHOD csc_method = CSC_METHOD_SW;
1670 int i, plane;
1671
1672 FunctionIn();
1673
1674 pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc = OMX_FALSE;
1675 pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst = OMX_FALSE;
1676 pExynosComponent->bUseFlagEOF = OMX_TRUE;
1677 pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1678 pExynosComponent->bBehaviorEOS = OMX_FALSE;
1679 pVideoDec->bDiscardCSDError = OMX_FALSE;
1680
1681 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] CodecOpen W: %d H:%d Bitrate:%d FPS:%d", pExynosComponent, __FUNCTION__,
1682 pExynosInputPort->portDefinition.format.video.nFrameWidth,
1683 pExynosInputPort->portDefinition.format.video.nFrameHeight,
1684 pExynosInputPort->portDefinition.format.video.nBitrate,
1685 pExynosInputPort->portDefinition.format.video.xFramerate);
1686
1687 pVideoInstInfo->nSize = sizeof(ExynosVideoInstInfo);
1688 pVideoInstInfo->nWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
1689 pVideoInstInfo->nHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
1690 pVideoInstInfo->nBitrate = pExynosInputPort->portDefinition.format.video.nBitrate;
1691 pVideoInstInfo->xFramerate = pExynosInputPort->portDefinition.format.video.xFramerate;
1692
1693 /* VP9 Codec Open */
1694 ret = VP9CodecOpen(pVp9Dec, pVideoInstInfo);
1695 if (ret != OMX_ErrorNone) {
1696 goto EXIT;
1697 }
1698
1699 pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
1700 pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
1701 pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
1702
1703 Exynos_SetPlaneToPort(pExynosInputPort, MFC_DEFAULT_INPUT_BUFFER_PLANE);
1704 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1705 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {DEFAULT_MFC_INPUT_BUFFER_SIZE, 0, 0};
1706 Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1707 Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1708 ret = Exynos_Allocate_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX, MFC_INPUT_BUFFER_NUM_MAX, nAllocLen);
1709 if (ret != OMX_ErrorNone)
1710 goto EXIT;
1711
1712 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)
1713 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1714 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1715 /*************/
1716 /* TBD */
1717 /*************/
1718 /* Does not require any actions. */
1719 }
1720
1721 Exynos_SetPlaneToPort(pExynosOutputPort, MFC_DEFAULT_OUTPUT_BUFFER_PLANE);
1722 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1723 Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1724 Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1725 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1726 /*************/
1727 /* TBD */
1728 /*************/
1729 /* Does not require any actions. */
1730 }
1731
1732 pVp9Dec->bSourceStart = OMX_FALSE;
1733 Exynos_OSAL_SignalCreate(&pVp9Dec->hSourceStartEvent);
1734 pVp9Dec->bDestinationStart = OMX_FALSE;
1735 Exynos_OSAL_SignalCreate(&pVp9Dec->hDestinationStartEvent);
1736
1737 INIT_ARRAY_TO_VAL(pExynosComponent->timeStamp, DEFAULT_TIMESTAMP_VAL, MAX_TIMESTAMP);
1738 Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1739 pVp9Dec->hMFCVp9Handle.indexTimestamp = 0;
1740 pVp9Dec->hMFCVp9Handle.outputIndexTimestamp = 0;
1741
1742 pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1743
1744 Exynos_OSAL_QueueCreate(&pVp9Dec->bypassBufferInfoQ, QUEUE_ELEMENTS);
1745
1746 #ifdef USE_CSC_HW
1747 csc_method = CSC_METHOD_HW;
1748 #endif
1749 pVideoDec->csc_handle = csc_init(csc_method);
1750 if (pVideoDec->csc_handle == NULL) {
1751 ret = OMX_ErrorInsufficientResources;
1752 goto EXIT;
1753 }
1754 pVideoDec->csc_set_format = OMX_FALSE;
1755
1756 EXIT:
1757 FunctionOut();
1758
1759 return ret;
1760 }
1761
1762 /* MFC Terminate */
1763 OMX_ERRORTYPE Exynos_VP9Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1764 {
1765 OMX_ERRORTYPE ret = OMX_ErrorNone;
1766 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1767 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1768 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1769 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1770 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1771 OMX_PTR hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
1772
1773 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
1774 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
1775 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
1776
1777 int i, plane;
1778
1779 FunctionIn();
1780
1781 if (pVideoDec->csc_handle != NULL) {
1782 csc_deinit(pVideoDec->csc_handle);
1783 pVideoDec->csc_handle = NULL;
1784 }
1785
1786 Exynos_OSAL_QueueTerminate(&pVp9Dec->bypassBufferInfoQ);
1787
1788 Exynos_OSAL_SignalTerminate(pVp9Dec->hDestinationStartEvent);
1789 pVp9Dec->hDestinationStartEvent = NULL;
1790 pVp9Dec->bDestinationStart = OMX_FALSE;
1791 Exynos_OSAL_SignalTerminate(pVp9Dec->hSourceStartEvent);
1792 pVp9Dec->hSourceStartEvent = NULL;
1793 pVp9Dec->bSourceStart = OMX_FALSE;
1794
1795 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1796 Exynos_Free_CodecBuffers(pOMXComponent, OUTPUT_PORT_INDEX);
1797 Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1798 Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1799 } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1800 /*************/
1801 /* TBD */
1802 /*************/
1803 /* Does not require any actions. */
1804 }
1805
1806 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1807 Exynos_Free_CodecBuffers(pOMXComponent, INPUT_PORT_INDEX);
1808 Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1809 Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1810 } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1811 /*************/
1812 /* TBD */
1813 /*************/
1814 /* Does not require any actions. */
1815 }
1816 VP9CodecClose(pVp9Dec);
1817
1818 Exynos_ResetAllPortConfig(pOMXComponent);
1819
1820 EXIT:
1821 FunctionOut();
1822
1823 return ret;
1824 }
1825
1826 OMX_ERRORTYPE Exynos_VP9Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1827 {
1828 OMX_ERRORTYPE ret = OMX_ErrorNone;
1829 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1830 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1831 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
1832 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
1833 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1834 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1835 OMX_U32 oneFrameSize = pSrcInputData->dataLen;
1836
1837 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
1838 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
1839 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
1840 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1841
1842 OMX_BUFFERHEADERTYPE tempBufferHeader;
1843 void *pPrivate = NULL;
1844
1845 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
1846 unsigned int nDataLen[MAX_BUFFER_PLANE] = {oneFrameSize, 0, 0};
1847 OMX_BOOL bInStartCode = OMX_FALSE;
1848 int i;
1849
1850 FunctionIn();
1851
1852 if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCSrc == OMX_FALSE) {
1853 ret = VP9CodecSrcSetup(pOMXComponent, pSrcInputData);
1854 goto EXIT;
1855 }
1856
1857 if ((pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_FALSE) &&
1858 (pVideoDec->bForceHeaderParsing == OMX_FALSE)) {
1859 ret = VP9CodecDstSetup(pOMXComponent);
1860 if (ret != OMX_ErrorNone) {
1861 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
1862 goto EXIT;
1863 }
1864 }
1865
1866 if (((bInStartCode = Check_VP9_StartCode(pSrcInputData->multiPlaneBuffer.dataBuffer[0], oneFrameSize)) == OMX_TRUE) ||
1867 ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1868 pExynosComponent->timeStamp[pVp9Dec->hMFCVp9Handle.indexTimestamp] = pSrcInputData->timeStamp;
1869 pExynosComponent->nFlags[pVp9Dec->hMFCVp9Handle.indexTimestamp] = pSrcInputData->nFlags;
1870 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x, oneFrameSize: %d", pExynosComponent, __FUNCTION__,
1871 pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pVp9Dec->hMFCVp9Handle.indexTimestamp, pSrcInputData->nFlags, oneFrameSize);
1872 pDecOps->Set_FrameTag(hMFCHandle, pVp9Dec->hMFCVp9Handle.indexTimestamp);
1873 pVp9Dec->hMFCVp9Handle.indexTimestamp++;
1874 pVp9Dec->hMFCVp9Handle.indexTimestamp %= MAX_TIMESTAMP;
1875
1876 if ((pVideoDec->bQosChanged == OMX_TRUE) &&
1877 (pDecOps->Set_QosRatio != NULL)) {
1878 pDecOps->Set_QosRatio(hMFCHandle, pVideoDec->nQosRatio);
1879 pVideoDec->bQosChanged = OMX_FALSE;
1880 }
1881
1882 #ifdef PERFORMANCE_DEBUG
1883 Exynos_OSAL_V4L2CountIncrease(pExynosInputPort->hBufferCount, pSrcInputData->bufferHeader, INPUT_PORT_INDEX);
1884 #endif
1885
1886 /* queue work for input buffer */
1887 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] bufferHeader: 0x%x, dataBuffer: 0x%x", pExynosComponent, __FUNCTION__, pSrcInputData->bufferHeader, pSrcInputData->multiPlaneBuffer.dataBuffer[0]);
1888
1889 if (pExynosInputPort->bufferProcessType & BUFFER_SHARE)
1890 nAllocLen[0] = pSrcInputData->bufferHeader->nAllocLen;
1891 else if (pExynosInputPort->bufferProcessType & BUFFER_COPY)
1892 nAllocLen[0] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1893
1894 if (pExynosInputPort->bufferProcessType == BUFFER_COPY) {
1895 tempBufferHeader.nFlags = pSrcInputData->nFlags;
1896 tempBufferHeader.nTimeStamp = pSrcInputData->timeStamp;
1897 pPrivate = (void *)&tempBufferHeader;
1898 } else {
1899 pPrivate = (void *)pSrcInputData->bufferHeader;
1900 }
1901 codecReturn = pInbufOps->ExtensionEnqueue(hMFCHandle,
1902 (void **)pSrcInputData->multiPlaneBuffer.dataBuffer,
1903 (int *)pSrcInputData->multiPlaneBuffer.fd,
1904 nAllocLen,
1905 nDataLen,
1906 Exynos_GetPlaneFromPort(pExynosInputPort),
1907 pPrivate);
1908 if (codecReturn != VIDEO_ERROR_NONE) {
1909 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1910 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1911 goto EXIT;
1912 }
1913 VP9CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1914 if (pVp9Dec->bSourceStart == OMX_FALSE) {
1915 pVp9Dec->bSourceStart = OMX_TRUE;
1916 Exynos_OSAL_SignalSet(pVp9Dec->hSourceStartEvent);
1917 Exynos_OSAL_SleepMillisec(0);
1918 }
1919 if (pVp9Dec->bDestinationStart == OMX_FALSE) {
1920 pVp9Dec->bDestinationStart = OMX_TRUE;
1921 Exynos_OSAL_SignalSet(pVp9Dec->hDestinationStartEvent);
1922 Exynos_OSAL_SleepMillisec(0);
1923 }
1924 } else if (bInStartCode == OMX_FALSE) {
1925 ret = OMX_ErrorCorruptedFrame;
1926 goto EXIT;
1927 }
1928
1929 ret = OMX_ErrorNone;
1930
1931 EXIT:
1932 FunctionOut();
1933
1934 return ret;
1935 }
1936
1937 OMX_ERRORTYPE Exynos_VP9Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1938 {
1939 OMX_ERRORTYPE ret = OMX_ErrorNone;
1940 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1941 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1942 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1943 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
1944 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1945 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
1946 ExynosVideoDecBufferOps *pInbufOps = pVp9Dec->hMFCVp9Handle.pInbufOps;
1947 ExynosVideoBuffer *pVideoBuffer;
1948 ExynosVideoBuffer videoBuffer;
1949
1950 FunctionIn();
1951
1952 if (pInbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer) == VIDEO_ERROR_NONE)
1953 pVideoBuffer = &videoBuffer;
1954 else
1955 pVideoBuffer = NULL;
1956
1957 pSrcOutputData->dataLen = 0;
1958 pSrcOutputData->usedDataLen = 0;
1959 pSrcOutputData->remainDataLen = 0;
1960 pSrcOutputData->nFlags = 0;
1961 pSrcOutputData->timeStamp = 0;
1962 pSrcOutputData->bufferHeader = NULL;
1963
1964 if (pVideoBuffer == NULL) {
1965 pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = NULL;
1966 pSrcOutputData->allocSize = 0;
1967 pSrcOutputData->pPrivate = NULL;
1968 } else {
1969 pSrcOutputData->multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
1970 pSrcOutputData->multiPlaneBuffer.fd[0] = pVideoBuffer->planes[0].fd;
1971 pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize;
1972
1973 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1974 int i;
1975 for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1976 if (pSrcOutputData->multiPlaneBuffer.dataBuffer[0] ==
1977 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1978 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1979 pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1980 break;
1981 }
1982 }
1983
1984 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1985 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1986 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1987 goto EXIT;
1988 }
1989 }
1990
1991 /* For Share Buffer */
1992 if (pExynosInputPort->bufferProcessType == BUFFER_SHARE)
1993 pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1994
1995 #ifdef PERFORMANCE_DEBUG
1996 Exynos_OSAL_V4L2CountDecrease(pExynosInputPort->hBufferCount, pSrcOutputData->bufferHeader, INPUT_PORT_INDEX);
1997 #endif
1998 }
1999
2000 ret = OMX_ErrorNone;
2001
2002 EXIT:
2003 FunctionOut();
2004
2005 return ret;
2006 }
2007
2008 OMX_ERRORTYPE Exynos_VP9Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2009 {
2010 OMX_ERRORTYPE ret = OMX_ErrorNone;
2011 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2012 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2013 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2014 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
2015 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2016
2017 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
2018 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
2019 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2020
2021 unsigned int nAllocLen[MAX_BUFFER_PLANE] = {0, 0, 0};
2022 unsigned int nDataLen[MAX_BUFFER_PLANE] = {0, 0, 0};
2023 int i, nPlaneCnt;
2024
2025 FunctionIn();
2026
2027 if (pDstInputData->multiPlaneBuffer.dataBuffer[0] == NULL) {
2028 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2029 ret = OMX_ErrorBadParameter;
2030 goto EXIT;
2031 }
2032
2033 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
2034 for (i = 0; i < nPlaneCnt; i++) {
2035 nAllocLen[i] = pVp9Dec->hMFCVp9Handle.codecOutbufConf.nAlignPlaneSize[i];
2036
2037 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] : %d => ADDR[%d]: 0x%x", pExynosComponent, __FUNCTION__, __LINE__, i,
2038 pDstInputData->multiPlaneBuffer.dataBuffer[i]);
2039 }
2040
2041 if ((pVideoDec->bReconfigDPB == OMX_TRUE) &&
2042 (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2043 (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
2044 ret = VP9CodecDstSetup(pOMXComponent);
2045 if (ret != OMX_ErrorNone) {
2046 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed to VP9CodecDstSetup(0x%x)", __func__, __LINE__, ret);
2047 goto EXIT;
2048 }
2049 pVideoDec->bReconfigDPB = OMX_FALSE;
2050 }
2051
2052 #ifdef PERFORMANCE_DEBUG
2053 Exynos_OSAL_V4L2CountIncrease(pExynosOutputPort->hBufferCount, pDstInputData->bufferHeader, OUTPUT_PORT_INDEX);
2054 #endif
2055
2056 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
2057 codecReturn = pOutbufOps->Enqueue(hMFCHandle,
2058 (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
2059 nDataLen,
2060 nPlaneCnt,
2061 pDstInputData->bufferHeader);
2062 } else {
2063 codecReturn = pOutbufOps->ExtensionEnqueue(hMFCHandle,
2064 (void **)pDstInputData->multiPlaneBuffer.dataBuffer,
2065 (int *)pDstInputData->multiPlaneBuffer.fd,
2066 nAllocLen,
2067 nDataLen,
2068 nPlaneCnt,
2069 pDstInputData->bufferHeader);
2070 }
2071
2072 if (codecReturn != VIDEO_ERROR_NONE) {
2073 if (codecReturn != VIDEO_ERROR_WRONGBUFFERSIZE) {
2074 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2075 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2076 }
2077 goto EXIT;
2078 }
2079 VP9CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2080
2081 ret = OMX_ErrorNone;
2082
2083 EXIT:
2084 FunctionOut();
2085
2086 return ret;
2087 }
2088
2089 OMX_ERRORTYPE Exynos_VP9Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2090 {
2091 OMX_ERRORTYPE ret = OMX_ErrorNone;
2092 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2093 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2094 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2095 void *hMFCHandle = pVp9Dec->hMFCVp9Handle.hMFCHandle;
2096 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2097 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2098 DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
2099
2100 ExynosVideoDecOps *pDecOps = pVp9Dec->hMFCVp9Handle.pDecOps;
2101 ExynosVideoDecBufferOps *pOutbufOps = pVp9Dec->hMFCVp9Handle.pOutbufOps;
2102 ExynosVideoBuffer *pVideoBuffer = NULL;
2103 ExynosVideoBuffer videoBuffer;
2104 ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2105 ExynosVideoGeometry *bufferGeometry = NULL;
2106 ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2107
2108 OMX_S32 indexTimestamp = 0;
2109 int plane, nPlaneCnt;
2110
2111 FunctionIn();
2112
2113 if (pVp9Dec->bDestinationStart == OMX_FALSE) {
2114 ret = OMX_ErrorNone;
2115 goto EXIT;
2116 }
2117
2118 while (1) {
2119 if (pExynosOutputPort->bDynamicDPBMode == OMX_FALSE) {
2120 pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2121 if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2122 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2123 ret = OMX_ErrorHardware;
2124 goto EXIT;
2125 }
2126
2127 if (pVideoBuffer == NULL) {
2128 ret = OMX_ErrorNone;
2129 goto EXIT;
2130 }
2131 } else {
2132 Exynos_OSAL_Memset(&videoBuffer, 0, sizeof(ExynosVideoBuffer));
2133
2134 codecReturn = pOutbufOps->ExtensionDequeue(hMFCHandle, &videoBuffer);
2135 if (codecReturn == VIDEO_ERROR_NONE) {
2136 pVideoBuffer = &videoBuffer;
2137 } else if (codecReturn == VIDEO_ERROR_DQBUF_EIO) {
2138 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2139 pVideoBuffer = NULL;
2140 ret = OMX_ErrorHardware;
2141 goto EXIT;
2142 } else {
2143 pVideoBuffer = NULL;
2144 ret = OMX_ErrorNone;
2145 goto EXIT;
2146 }
2147 }
2148
2149 displayStatus = pVideoBuffer->displayStatus;
2150 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus: 0x%x", pExynosComponent, __FUNCTION__, displayStatus);
2151
2152 if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2153 (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2154 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2155 (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2156 (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
2157 (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2158 ret = OMX_ErrorNone;
2159 break;
2160 }
2161 }
2162
2163 if ((pVideoDec->bThumbnailMode == OMX_FALSE) &&
2164 (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL)) {
2165 if (pVideoDec->bReconfigDPB != OMX_TRUE) {
2166 pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2167 pVideoDec->bReconfigDPB = OMX_TRUE;
2168 Vp9CodecUpdateResolution(pOMXComponent);
2169 pVideoDec->csc_set_format = OMX_FALSE;
2170 }
2171 ret = OMX_ErrorNone;
2172 goto EXIT;
2173 }
2174
2175 pVp9Dec->hMFCVp9Handle.outputIndexTimestamp++;
2176 pVp9Dec->hMFCVp9Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2177
2178 pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2179 nPlaneCnt = Exynos_GetPlaneFromPort(pExynosOutputPort);
2180 for (plane = 0; plane < nPlaneCnt; plane++) {
2181 pDstOutputData->multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2182 pDstOutputData->multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2183 pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2184 pDstOutputData->dataLen += pVideoBuffer->planes[plane].dataSize;
2185 }
2186 pDstOutputData->usedDataLen = 0;
2187 pDstOutputData->pPrivate = pVideoBuffer;
2188 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2189 int i = 0;
2190 pDstOutputData->pPrivate = NULL;
2191 for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
2192 if (pDstOutputData->multiPlaneBuffer.dataBuffer[0] ==
2193 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[0]) {
2194 pDstOutputData->pPrivate = pVideoDec->pMFCDecOutputBuffer[i];
2195 break;
2196 }
2197 }
2198
2199 if (pDstOutputData->pPrivate == NULL) {
2200 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2201 ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2202 goto EXIT;
2203 }
2204 }
2205
2206 /* For Share Buffer */
2207 pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2208
2209 pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2210 bufferGeometry = &pVp9Dec->hMFCVp9Handle.codecOutbufConf;
2211 pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2212 pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2213 pBufferInfo->imageStride = bufferGeometry->nStride;
2214 pBufferInfo->ColorFormat = Exynos_OSAL_Video2OMXFormat((int)bufferGeometry->eColorFormat);
2215 Exynos_OSAL_Memcpy(&pBufferInfo->PDSB, &pVideoBuffer->PDSB, sizeof(PrivateDataShareBuffer));
2216
2217 indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2218 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
2219 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2220 if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2221 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2222 if (indexTimestamp == INDEX_AFTER_EOS) {
2223 pDstOutputData->timeStamp = 0x00;
2224 pDstOutputData->nFlags = 0x00;
2225 } else {
2226 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pVp9Dec->hMFCVp9Handle.outputIndexTimestamp];
2227 pDstOutputData->nFlags = pExynosComponent->nFlags[pVp9Dec->hMFCVp9Handle.outputIndexTimestamp];
2228 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] missing out indexTimestamp: %d", pExynosComponent, __FUNCTION__, indexTimestamp);
2229 }
2230 } else {
2231 pDstOutputData->timeStamp = 0x00;
2232 pDstOutputData->nFlags = 0x00;
2233 }
2234 } else {
2235 /* For timestamp correction. if mfc support frametype detect */
2236 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] disp_pic_frame_type: %d", pExynosComponent, __FUNCTION__, pVideoBuffer->frameType);
2237
2238 /* NEED TIMESTAMP REORDER */
2239 if (pVideoDec->bDTSMode == OMX_TRUE) {
2240 if ((pVideoBuffer->frameType & VIDEO_FRAME_I) ||
2241 ((pVideoBuffer->frameType & VIDEO_FRAME_OTHERS) &&
2242 ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) ||
2243 (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE))
2244 pVp9Dec->hMFCVp9Handle.outputIndexTimestamp = indexTimestamp;
2245 else
2246 indexTimestamp = pVp9Dec->hMFCVp9Handle.outputIndexTimestamp;
2247 }
2248
2249 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2250 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp] | OMX_BUFFERFLAG_ENDOFFRAME;
2251
2252 if (pVideoBuffer->frameType & VIDEO_FRAME_I)
2253 pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2254
2255 if (pVideoBuffer->frameType & VIDEO_FRAME_CORRUPT)
2256 pDstOutputData->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
2257
2258 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] output timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pExynosComponent, __FUNCTION__,
2259 pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2260 }
2261
2262 #ifdef PERFORMANCE_DEBUG
2263 if (pDstOutputData->bufferHeader != NULL) {
2264 pDstOutputData->bufferHeader->nTimeStamp = pDstOutputData->timeStamp;
2265 Exynos_OSAL_V4L2CountDecrease(pExynosOutputPort->hBufferCount, pDstOutputData->bufferHeader, OUTPUT_PORT_INDEX);
2266 }
2267 #endif
2268
2269 if (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport == VIDEO_FALSE) {
2270 if ((!(pVideoBuffer->frameType & VIDEO_FRAME_B)) &&
2271 (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
2272 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2273 }
2274
2275 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
2276 if (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) {
2277 pDstOutputData->remainDataLen = 0;
2278
2279 if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2280 if (indexTimestamp != INDEX_AFTER_EOS)
2281 Exynos_OSAL_Log(EXYNOS_LOG_WARNING, "[%p][%s] indexTimestamp(%d) is wrong", pExynosComponent, __FUNCTION__, indexTimestamp);
2282 pDstOutputData->timeStamp = 0x00;
2283 pDstOutputData->nFlags = 0x00;
2284 goto EXIT;
2285 }
2286
2287 if ((pExynosComponent->nFlags[indexTimestamp] & OMX_BUFFERFLAG_EOS) ||
2288 (pExynosComponent->bSaveFlagEOS == OMX_TRUE)) {
2289 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2290 pExynosComponent->nFlags[indexTimestamp] &= (~OMX_BUFFERFLAG_EOS);
2291 }
2292 } else if ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
2293 pDstOutputData->remainDataLen = 0;
2294
2295 if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
2296 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2297
2298 if (!(pVideoBuffer->frameType & VIDEO_FRAME_B)) {
2299 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2300 } else {
2301 pExynosComponent->bSaveFlagEOS = OMX_TRUE;
2302 pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
2303 }
2304 }
2305 } else {
2306 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2307 }
2308 } else {
2309 if ((displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2310 (displayStatus == VIDEO_FRAME_STATUS_LAST_FRAME) ||
2311 ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2312 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] displayStatus:%d, nFlags0x%x", pExynosComponent, __FUNCTION__, displayStatus, pDstOutputData->nFlags);
2313 pDstOutputData->remainDataLen = 0;
2314
2315 if (pExynosComponent->bBehaviorEOS == OMX_TRUE) {
2316 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2317
2318 if (displayStatus != VIDEO_FRAME_STATUS_LAST_FRAME) {
2319 pDstOutputData->nFlags &= (~OMX_BUFFERFLAG_EOS);
2320 } else {
2321 pDstOutputData->nFlags |= OMX_BUFFERFLAG_EOS;
2322 pExynosComponent->bBehaviorEOS = OMX_FALSE;
2323 }
2324 }
2325 } else {
2326 pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2327 }
2328 }
2329
2330 ret = OMX_ErrorNone;
2331
2332 EXIT:
2333 FunctionOut();
2334
2335 return ret;
2336 }
2337
2338 OMX_ERRORTYPE Exynos_VP9Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2339 {
2340 OMX_ERRORTYPE ret = OMX_ErrorNone;
2341 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2342 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2343 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2344
2345 FunctionIn();
2346
2347 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2348 ret = OMX_ErrorNone;
2349 goto EXIT;
2350 }
2351 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2352 ret = OMX_ErrorNone;
2353 goto EXIT;
2354 }
2355
2356 ret = Exynos_VP9Dec_SrcIn(pOMXComponent, pSrcInputData);
2357 if ((ret != OMX_ErrorNone) &&
2358 ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorInputDataDecodeYet) &&
2359 ((EXYNOS_OMX_ERRORTYPE)ret != OMX_ErrorCorruptedFrame)) {
2360
2361 if (((EXYNOS_OMX_ERRORTYPE)ret == OMX_ErrorCorruptedHeader) &&
2362 (pVideoDec->bDiscardCSDError == OMX_TRUE)) {
2363 goto EXIT;
2364 }
2365
2366 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2367 pExynosComponent->callbackData,
2368 OMX_EventError, ret, 0, NULL);
2369 }
2370
2371 EXIT:
2372 FunctionOut();
2373
2374 return ret;
2375 }
2376
2377 OMX_ERRORTYPE Exynos_VP9Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2378 {
2379 OMX_ERRORTYPE ret = OMX_ErrorNone;
2380 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2381 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2382 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2383 EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2384
2385 FunctionIn();
2386
2387 if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2388 ret = OMX_ErrorNone;
2389 goto EXIT;
2390 }
2391
2392 if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2393 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2394 ret = OMX_ErrorNone;
2395 goto EXIT;
2396 }
2397 }
2398 if ((pVp9Dec->bSourceStart == OMX_FALSE) &&
2399 (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2400 Exynos_OSAL_SignalWait(pVp9Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2401 if (pVideoDec->bExitBufferProcessThread)
2402 goto EXIT;
2403
2404 Exynos_OSAL_SignalReset(pVp9Dec->hSourceStartEvent);
2405 }
2406
2407 ret = Exynos_VP9Dec_SrcOut(pOMXComponent, pSrcOutputData);
2408 if ((ret != OMX_ErrorNone) &&
2409 (pExynosComponent->currentState == OMX_StateExecuting)) {
2410 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2411 pExynosComponent->callbackData,
2412 OMX_EventError, ret, 0, NULL);
2413 }
2414
2415 EXIT:
2416 FunctionOut();
2417
2418 return ret;
2419 }
2420
2421 OMX_ERRORTYPE Exynos_VP9Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2422 {
2423 OMX_ERRORTYPE ret = OMX_ErrorNone;
2424 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2425 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2426 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2427 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2428
2429 FunctionIn();
2430
2431 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2432 ret = OMX_ErrorNone;
2433 goto EXIT;
2434 }
2435 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2436 if (pExynosComponent->currentState == OMX_StatePause)
2437 ret = OMX_ErrorOutputBufferUseYet;
2438 else
2439 ret = OMX_ErrorNone;
2440 goto EXIT;
2441 }
2442 if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2443 if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
2444 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2445 Exynos_OSAL_SignalWait(pVp9Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2446 if (pVideoDec->bExitBufferProcessThread)
2447 goto EXIT;
2448
2449 Exynos_OSAL_SignalReset(pVp9Dec->hDestinationStartEvent);
2450 }
2451 if (Exynos_OSAL_GetElemNum(&pVp9Dec->bypassBufferInfoQ) > 0) {
2452 BYPASS_BUFFER_INFO *pBufferInfo = (BYPASS_BUFFER_INFO *)Exynos_OSAL_Dequeue(&pVp9Dec->bypassBufferInfoQ);
2453 if (pBufferInfo == NULL) {
2454 ret = OMX_ErrorUndefined;
2455 goto EXIT;
2456 }
2457
2458 pDstInputData->bufferHeader->nFlags = pBufferInfo->nFlags;
2459 pDstInputData->bufferHeader->nTimeStamp = pBufferInfo->timeStamp;
2460 Exynos_OMX_OutputBufferReturn(pOMXComponent, pDstInputData->bufferHeader);
2461 Exynos_OSAL_Free(pBufferInfo);
2462
2463 ret = OMX_ErrorNone;
2464 goto EXIT;
2465 }
2466 }
2467 if (pVp9Dec->hMFCVp9Handle.bConfiguredMFCDst == OMX_TRUE) {
2468 ret = Exynos_VP9Dec_DstIn(pOMXComponent, pDstInputData);
2469 if (ret != OMX_ErrorNone) {
2470 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2471 pExynosComponent->callbackData,
2472 OMX_EventError, ret, 0, NULL);
2473 }
2474 }
2475
2476 EXIT:
2477 FunctionOut();
2478
2479 return ret;
2480 }
2481
2482 OMX_ERRORTYPE Exynos_VP9Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2483 {
2484 OMX_ERRORTYPE ret = OMX_ErrorNone;
2485 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2486 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2487 EXYNOS_VP9DEC_HANDLE *pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2488 EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2489
2490 FunctionIn();
2491
2492 if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2493 ret = OMX_ErrorNone;
2494 goto EXIT;
2495 }
2496 if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2497 ret = OMX_ErrorNone;
2498 goto EXIT;
2499 }
2500
2501 if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2502 if ((pVp9Dec->bDestinationStart == OMX_FALSE) &&
2503 (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2504 Exynos_OSAL_SignalWait(pVp9Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2505 if (pVideoDec->bExitBufferProcessThread)
2506 goto EXIT;
2507
2508 Exynos_OSAL_SignalReset(pVp9Dec->hDestinationStartEvent);
2509 }
2510 if (Exynos_OSAL_GetElemNum(&pVp9Dec->bypassBufferInfoQ) > 0) {
2511 EXYNOS_OMX_DATABUFFER *dstOutputUseBuffer = &pExynosOutputPort->way.port2WayDataBuffer.outputDataBuffer;
2512 OMX_BUFFERHEADERTYPE *pOMXBuffer = NULL;
2513 BYPASS_BUFFER_INFO *pBufferInfo = NULL;
2514
2515 if (dstOutputUseBuffer->dataValid == OMX_FALSE) {
2516 pOMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
2517 if (pOMXBuffer == NULL) {
2518 ret = OMX_ErrorUndefined;
2519 goto EXIT;
2520 }
2521 } else {
2522 pOMXBuffer = dstOutputUseBuffer->bufferHeader;
2523 }
2524
2525 pBufferInfo = Exynos_OSAL_Dequeue(&pVp9Dec->bypassBufferInfoQ);
2526 if (pBufferInfo == NULL) {
2527 ret = OMX_ErrorUndefined;
2528 goto EXIT;
2529 }
2530
2531 pOMXBuffer->nFlags = pBufferInfo->nFlags;
2532 pOMXBuffer->nTimeStamp = pBufferInfo->timeStamp;
2533 Exynos_OMX_OutputBufferReturn(pOMXComponent, pOMXBuffer);
2534 Exynos_OSAL_Free(pBufferInfo);
2535
2536 dstOutputUseBuffer->dataValid = OMX_FALSE;
2537
2538 ret = OMX_ErrorNone;
2539 goto EXIT;
2540 }
2541 }
2542 ret = Exynos_VP9Dec_DstOut(pOMXComponent, pDstOutputData);
2543 if ((ret != OMX_ErrorNone) &&
2544 (pExynosComponent->currentState == OMX_StateExecuting)) {
2545 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2546 pExynosComponent->callbackData,
2547 OMX_EventError, ret, 0, NULL);
2548 }
2549
2550 EXIT:
2551 FunctionOut();
2552
2553 return ret;
2554 }
2555
2556 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2557 OMX_HANDLETYPE hComponent,
2558 OMX_STRING componentName)
2559 {
2560 OMX_ERRORTYPE ret = OMX_ErrorNone;
2561 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2562 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2563 EXYNOS_OMX_BASEPORT *pExynosPort = NULL;
2564 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2565 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
2566 int i = 0;
2567
2568 Exynos_OSAL_Get_Log_Property(); // For debuging
2569 FunctionIn();
2570
2571 if ((hComponent == NULL) || (componentName == NULL)) {
2572 ret = OMX_ErrorBadParameter;
2573 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2574 goto EXIT;
2575 }
2576 if ((Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_DEC, componentName) != 0) &&
2577 (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_VP9_CUSTOM_DEC, componentName) != 0)) {
2578 ret = OMX_ErrorBadParameter;
2579 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2580 goto EXIT;
2581 }
2582
2583 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2584 ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2585 if (ret != OMX_ErrorNone) {
2586 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2587 goto EXIT;
2588 }
2589 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2590 pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2591
2592 pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2593 if (pExynosComponent->componentName == NULL) {
2594 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2595 ret = OMX_ErrorInsufficientResources;
2596 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2597 goto EXIT;
2598 }
2599 Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2600
2601 pVp9Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_VP9DEC_HANDLE));
2602 if (pVp9Dec == NULL) {
2603 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2604 ret = OMX_ErrorInsufficientResources;
2605 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2606 goto EXIT;
2607 }
2608 Exynos_OSAL_Memset(pVp9Dec, 0, sizeof(EXYNOS_VP9DEC_HANDLE));
2609 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2610 pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pVp9Dec;
2611 Exynos_OSAL_Strcpy(pExynosComponent->componentName, componentName);
2612
2613 /* Set componentVersion */
2614 pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2615 pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2616 pExynosComponent->componentVersion.s.nRevision = REVISION_NUMBER;
2617 pExynosComponent->componentVersion.s.nStep = STEP_NUMBER;
2618 /* Set specVersion */
2619 pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2620 pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2621 pExynosComponent->specVersion.s.nRevision = REVISION_NUMBER;
2622 pExynosComponent->specVersion.s.nStep = STEP_NUMBER;
2623
2624 /* Input port */
2625 pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2626 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2627 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2628 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2629 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2630 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2631 if (IS_CUSTOM_COMPONENT(pExynosComponent->componentName) == OMX_TRUE)
2632 pExynosPort->portDefinition.nBufferSize = CUSTOM_DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2633
2634 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingVP9;
2635 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2636 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/x-vnd.on2.vp9");
2637 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2638 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2639 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2640 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2641 pExynosPort->bufferProcessType = BUFFER_SHARE;
2642 pExynosPort->portWayType = WAY2_PORT;
2643 pExynosPort->ePlaneType = PLANE_SINGLE;
2644
2645 /* Output port */
2646 pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2647 pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2648 pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2649 pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2650 pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2651 pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2652 pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2653 Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2654 Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2655 pExynosPort->portDefinition.format.video.pNativeRender = 0;
2656 pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2657 pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2658 pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2659 pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2660 pExynosPort->portWayType = WAY2_PORT;
2661 pExynosPort->ePlaneType = PLANE_MULTIPLE;
2662
2663 pOMXComponent->GetParameter = &Exynos_VP9Dec_GetParameter;
2664 pOMXComponent->SetParameter = &Exynos_VP9Dec_SetParameter;
2665 pOMXComponent->GetConfig = &Exynos_VP9Dec_GetConfig;
2666 pOMXComponent->SetConfig = &Exynos_VP9Dec_SetConfig;
2667 pOMXComponent->GetExtensionIndex = &Exynos_VP9Dec_GetExtensionIndex;
2668 pOMXComponent->ComponentRoleEnum = &Exynos_VP9Dec_ComponentRoleEnum;
2669 pOMXComponent->ComponentDeInit = &Exynos_OMX_ComponentDeinit;
2670
2671 pExynosComponent->exynos_codec_componentInit = &Exynos_VP9Dec_Init;
2672 pExynosComponent->exynos_codec_componentTerminate = &Exynos_VP9Dec_Terminate;
2673
2674 pVideoDec->exynos_codec_srcInputProcess = &Exynos_VP9Dec_srcInputBufferProcess;
2675 pVideoDec->exynos_codec_srcOutputProcess = &Exynos_VP9Dec_srcOutputBufferProcess;
2676 pVideoDec->exynos_codec_dstInputProcess = &Exynos_VP9Dec_dstInputBufferProcess;
2677 pVideoDec->exynos_codec_dstOutputProcess = &Exynos_VP9Dec_dstOutputBufferProcess;
2678
2679 pVideoDec->exynos_codec_start = &VP9CodecStart;
2680 pVideoDec->exynos_codec_stop = &VP9CodecStop;
2681 pVideoDec->exynos_codec_bufferProcessRun = &VP9CodecOutputBufferProcessRun;
2682 pVideoDec->exynos_codec_enqueueAllBuffer = &VP9CodecEnQueueAllBuffer;
2683
2684 #if 0 /* unused code */
2685 pVideoDec->exynos_checkInputFrame = &Check_VP9_Frame;
2686 pVideoDec->exynos_codec_getCodecInputPrivateData = &GetCodecInputPrivateData;
2687 #endif
2688
2689 pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2690 pVideoDec->exynos_codec_reconfigAllBuffers = &Vp9CodecReconfigAllBuffers;
2691
2692 pVideoDec->exynos_codec_checkFormatSupport = &CheckFormatHWSupport;
2693 pVideoDec->exynos_codec_checkResolutionChange = &Vp9CodecCheckResolution;
2694
2695 pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2696 if (pVideoDec->hSharedMemory == NULL) {
2697 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2698 Exynos_OSAL_Free(pVp9Dec);
2699 pVp9Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2700 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2701 ret = OMX_ErrorInsufficientResources;
2702 goto EXIT;
2703 }
2704
2705 pVp9Dec->hMFCVp9Handle.videoInstInfo.eCodecType = VIDEO_CODING_VP9;
2706 if (pExynosComponent->codecType == HW_VIDEO_DEC_SECURE_CODEC)
2707 pVp9Dec->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_SECURE;
2708 else
2709 pVp9Dec->hMFCVp9Handle.videoInstInfo.eSecurityType = VIDEO_NORMAL;
2710
2711 if (Exynos_Video_GetInstInfo(&(pVp9Dec->hMFCVp9Handle.videoInstInfo), VIDEO_TRUE /* dec */) != VIDEO_ERROR_NONE) {
2712 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[%p][%s]: Exynos_Video_GetInstInfo is failed", pExynosComponent, __FUNCTION__);
2713 Exynos_OSAL_Free(pVp9Dec);
2714 pVp9Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2715 Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2716 ret = OMX_ErrorInsufficientResources;
2717 goto EXIT;
2718 }
2719
2720 Exynos_OSAL_Log(EXYNOS_LOG_ESSENTIAL, "[%p][%s] GetInstInfo for dec %d %d %d %d", pExynosComponent, __FUNCTION__,
2721 (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDualDPBSupport),
2722 (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport),
2723 (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bLastFrameSupport),
2724 (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bSkypeSupport));
2725
2726 if (pVp9Dec->hMFCVp9Handle.videoInstInfo.specificInfo.dec.bDynamicDPBSupport == VIDEO_TRUE)
2727 pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].bDynamicDPBMode = OMX_TRUE;
2728
2729 Exynos_Output_SetSupportFormat(pExynosComponent);
2730
2731 pExynosComponent->currentState = OMX_StateLoaded;
2732
2733 ret = OMX_ErrorNone;
2734
2735 EXIT:
2736 FunctionOut();
2737
2738 return ret;
2739 }
2740
2741 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
2742 OMX_HANDLETYPE hComponent)
2743 {
2744 OMX_ERRORTYPE ret = OMX_ErrorNone;
2745 OMX_COMPONENTTYPE *pOMXComponent = NULL;
2746 EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
2747 EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2748 EXYNOS_VP9DEC_HANDLE *pVp9Dec = NULL;
2749
2750 FunctionIn();
2751
2752 if (hComponent == NULL) {
2753 ret = OMX_ErrorBadParameter;
2754 goto EXIT;
2755 }
2756 pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2757 pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2758 pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2759
2760 Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2761
2762 Exynos_OSAL_Free(pExynosComponent->componentName);
2763 pExynosComponent->componentName = NULL;
2764
2765 pVp9Dec = (EXYNOS_VP9DEC_HANDLE *)pVideoDec->hCodecHandle;
2766 if (pVp9Dec != NULL) {
2767 Exynos_OSAL_Free(pVp9Dec);
2768 pVp9Dec = pVideoDec->hCodecHandle = NULL;
2769 }
2770
2771 ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2772 if (ret != OMX_ErrorNone) {
2773 goto EXIT;
2774 }
2775
2776 ret = OMX_ErrorNone;
2777
2778 EXIT:
2779 FunctionOut();
2780
2781 return ret;
2782 }