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