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