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