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