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