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