fixed coverity issues
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / dec / mpeg4 / Exynos_OMX_Mpeg4dec.c
1 /*
2  *
3  * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 /*
19  * @file      Exynos_OMX_Mpeg4dec.c
20  * @brief
21  * @author    Yunji Kim (yunji.kim@samsung.com)
22  * @author    SeungBeom Kim (sbcrux.kim@samsung.com)
23  * @version   2.0.0
24  * @history
25  *   2012.02.20 : Create
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <mm_types.h>
32
33 #include "Exynos_OMX_Macros.h"
34 #include "Exynos_OMX_Basecomponent.h"
35 #include "Exynos_OMX_Baseport.h"
36 #include "Exynos_OMX_Vdec.h"
37 #include "Exynos_OSAL_ETC.h"
38 #include "Exynos_OSAL_Semaphore.h"
39 #include "Exynos_OSAL_Thread.h"
40 #include "library_register.h"
41 #include "Exynos_OMX_Mpeg4dec.h"
42 #include "ExynosVideoApi.h"
43 #include "Exynos_OSAL_SharedMemory.h"
44 #include "Exynos_OSAL_Event.h"
45 #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
641     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
642     ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
643     ExynosVideoGeometry      bufferConf;
644     OMX_U32                  inputBufferNumber = 0;
645     int i, plane;
646
647     if (pVideoDec->bThumbnailMode == OMX_TRUE)
648         pDecOps->Set_DisplayDelay(hMFCHandle, 0);
649
650     /* input buffer info */
651     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
652     if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4)
653         bufferConf.eCompressionFormat = VIDEO_CODING_MPEG4;
654     else
655         bufferConf.eCompressionFormat = VIDEO_CODING_H263;
656
657     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE
658         ||pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE)
659         pInbufOps->Set_Shareable(hMFCHandle);
660
661     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
662         bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
663                                 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
664         inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
665     } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
666         bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
667         inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
668     }
669
670     /* should be done before prepare input buffer */
671     if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
672         ret = OMX_ErrorInsufficientResources;
673         goto EXIT;
674     }
675
676     /* set input buffer geometry */
677     if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
678         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
679         ret = OMX_ErrorInsufficientResources;
680         goto EXIT;
681     }
682
683     /* setup input buffer */
684     if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
685         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
686         ret = OMX_ErrorInsufficientResources;
687         goto EXIT;
688     }
689
690     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
691         pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) {
692         /* Register input buffer */
693         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
694             ExynosVideoPlane plane;
695             plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
696             plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
697             plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
698             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
699                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
700                 ret = OMX_ErrorInsufficientResources;
701                 goto EXIT;
702             }
703         }
704     } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
705         pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) {
706         ExynosVideoBuffer *pBuffer = NULL;
707
708         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
709             pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
710             Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
711             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
712             /* get input buffer info */
713             if (pInbufOps->Get_Buffer) {
714                 if (pInbufOps->Get_Buffer(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
715                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info");
716                     ret = OMX_ErrorInsufficientResources;
717                     goto EXIT;
718                 }
719             }
720
721             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
722                 /* Use ION Allocator */
723                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
724                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
725                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
726                 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
727                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
728             }
729
730             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
731         }
732     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
733         /* Register input buffer */
734         for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
735             ExynosVideoPlane plane;
736             if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
737                 plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, (int)pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
738             } else {
739                 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
740             }
741             plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
742             plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
743             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
744                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
745                 ret = OMX_ErrorInsufficientResources;
746                 goto EXIT;
747             }
748         }
749     }
750
751 EXIT:
752     FunctionOut();
753
754     return ret;
755 }
756
757
758
759 OMX_ERRORTYPE Mpeg4CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
760 {
761     OMX_ERRORTYPE            ret = OMX_ErrorNone;
762     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
763     EXYNOS_MPEG4DEC_HANDLE   *pMpeg4Dec = NULL;
764
765     FunctionIn();
766
767     if (pOMXComponent == NULL) {
768         ret = OMX_ErrorBadParameter;
769         goto EXIT;
770     }
771
772     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
773     if (pVideoDec == NULL) {
774         ret = OMX_ErrorBadParameter;
775         goto EXIT;
776     }
777     pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
778     if (pMpeg4Dec == NULL) {
779         ret = OMX_ErrorBadParameter;
780         goto EXIT;
781     }
782
783     if (nPortIndex == INPUT_PORT_INDEX) {
784         if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
785             Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
786             Exynos_OSAL_SleepMillisec(0);
787         }
788     }
789
790     if (nPortIndex == OUTPUT_PORT_INDEX) {
791         if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
792             Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
793             Exynos_OSAL_SleepMillisec(0);
794         }
795     }
796
797     ret = OMX_ErrorNone;
798
799 EXIT:
800     FunctionOut();
801
802     return ret;
803 }
804
805 OMX_ERRORTYPE Mpeg4CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
806 {
807     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
808     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
809     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
810     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
811     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
812     int i, nOutbufs;
813
814     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
815     ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
816     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
817
818     FunctionIn();
819
820     if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
821         ret = OMX_ErrorBadPortIndex;
822         goto EXIT;
823     }
824
825     if ((nPortIndex == INPUT_PORT_INDEX) &&
826         (pMpeg4Dec->bSourceStart == OMX_TRUE)) {
827         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
828
829         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
830             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
831             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
832
833             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
834         }
835
836         pInbufOps->Clear_Queue(hMFCHandle);
837     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
838                (pMpeg4Dec->bDestinationStart == OMX_TRUE)) {
839         ExynosVideoBuffer *pBuffer = NULL;
840
841         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
842
843         nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
844         nOutbufs += EXTRA_DPB_NUM;
845         for (i = 0; i < nOutbufs; i++) {
846             pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
847             Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
848         }
849         pOutbufOps->Clear_Queue(hMFCHandle);
850     }
851
852 EXIT:
853     FunctionOut();
854
855     return ret;
856 }
857
858
859 OMX_ERRORTYPE Mpeg4CodecDstFreeCodecBuffers(
860     OMX_COMPONENTTYPE *pOMXComponent)
861 {
862     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
863     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
864     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
865
866     int i, j;
867
868     FunctionIn();
869
870     for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
871         if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
872             for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
873                 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL &&
874                     pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE)
875                     Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
876             }
877
878             Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
879         }
880     }
881
882     Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer));
883
884     FunctionOut();
885
886     return OMX_ErrorNone;
887 }
888
889 OMX_ERRORTYPE Mpeg4CodecDstAllocCodecBuffers(
890     OMX_COMPONENTTYPE *pOMXComponent,
891     OMX_U32            nOutbufs)
892 {
893     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
894     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
895     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
896     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
897
898     MEMORY_TYPE eMemoryType                        = NORMAL_MEMORY;
899     OMX_U32     nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
900     int i, j;
901
902     FunctionIn();
903
904     nAllocLen[0] = calc_yplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
905                         pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight);
906     nAllocLen[1] = calc_uvplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
907                         pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight >> 1);
908
909     for (i = 0; i < nOutbufs; i++) {
910         pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
911         if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) {
912             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
913             ret = OMX_ErrorInsufficientResources;
914             goto EXIT;
915         }
916         Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
917
918         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
919             pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] =
920                 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType);
921             if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) {
922                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
923                 ret = OMX_ErrorInsufficientResources;
924                 goto EXIT;
925             }
926
927            pVideoDec->pMFCDecOutputBuffer[i]->fd[j] =
928                 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
929                                                  pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
930            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j];
931         }
932     }
933
934     return OMX_ErrorNone;
935
936 EXIT:
937     Mpeg4CodecDstFreeCodecBuffers(pOMXComponent);
938
939     FunctionOut();
940
941     return ret;
942 }
943
944 OMX_ERRORTYPE Mpeg4CodecDstRegistCodecBuffers(
945     OMX_COMPONENTTYPE *pOMXComponent,
946     OMX_U32            nOutbufs)
947 {
948     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
949     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
950     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
951     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
952     void                          *hMFCHandle       = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
953     ExynosVideoDecBufferOps       *pOutbufOps       = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
954
955     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
956     OMX_U32          nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
957     int i, j;
958
959     FunctionIn();
960
961     /* Register output buffer */
962     for (i = 0; i < nOutbufs; i++) {
963         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
964             planes[j].addr      = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j];
965             planes[j].fd        = pVideoDec->pMFCDecOutputBuffer[i]->fd[j];
966             planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j];
967         }
968
969         if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
970             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
971             ret = OMX_ErrorInsufficientResources;
972             goto EXIT;
973         }
974
975         pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
976                         (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
977     }
978
979     ret = OMX_ErrorNone;
980
981 EXIT:
982     FunctionOut();
983
984     return ret;
985 }
986
987 OMX_ERRORTYPE Mpeg4CodecResetupAllElement(
988     OMX_COMPONENTTYPE   *pOMXComponent,
989     OMX_U32              nPortIndex)
990 {
991     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
992     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
993     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
994     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
995     void                          *hMFCHandle       = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
996     EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
997     ExynosVideoDecBufferOps       *pOutbufOps       = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
998
999     FunctionIn();
1000
1001     if ((nPortIndex == INPUT_PORT_INDEX) &&
1002         (pMpeg4Dec->bSourceStart == OMX_TRUE)) {
1003         ret = OMX_ErrorNotImplemented;
1004         goto EXIT;
1005     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
1006                (pMpeg4Dec->bDestinationStart == OMX_TRUE)) {
1007         if (pOutputPort->bufferProcessType & BUFFER_COPY) {
1008
1009             /**********************************/
1010             /* Codec Buffer Free & Unregister */
1011             /**********************************/
1012             Mpeg4CodecDstFreeCodecBuffers(pOMXComponent);
1013             Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
1014
1015             if (pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE)
1016                 pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
1017
1018             pOutbufOps->Cleanup(hMFCHandle);
1019             /******************************************************/
1020             /* V4L2 Destnation Setup for DPB Buffer Number Change */
1021             /******************************************************/
1022             Mpeg4CodecDstSetup(pOMXComponent);
1023
1024             pVideoDec->bDRCProcessing = OMX_FALSE;
1025         } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
1026
1027             /**********************************/
1028             /* Codec Buffer Unregister */
1029             /**********************************/
1030             pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
1031             pOutbufOps->Cleanup(hMFCHandle);
1032         }
1033     } else {
1034         ret = OMX_ErrorBadParameter;
1035         goto EXIT;
1036     }
1037
1038 EXIT:
1039     FunctionOut();
1040
1041     return ret;
1042 }
1043
1044
1045 OMX_ERRORTYPE Mpeg4CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1046 {
1047     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1048     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1049     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1050     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1051     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1052     OMX_U32                     oneFrameSize = pSrcInputData->dataLen;
1053
1054     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1055     ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
1056     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1057     ExynosVideoGeometry      bufferConf;
1058
1059     FunctionIn();
1060
1061     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
1062         OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
1063         OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
1064         if (OMXBuffer == NULL) {
1065             ret = OMX_ErrorUndefined;
1066             goto EXIT;
1067         }
1068
1069         OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
1070         OMXBuffer->nFlags = pSrcInputData->nFlags;
1071         Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
1072
1073         ret = OMX_ErrorNone;
1074         goto EXIT;
1075     }
1076
1077     if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
1078         pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE)) {
1079         ret = Mpeg4CodecSrcInit(pOMXComponent);
1080         if (ret != OMX_ErrorNone)
1081             goto EXIT;
1082     }
1083
1084     /*Check for PB Packed*/
1085     if (pMpeg4Dec->hMFCMpeg4Handle.codecType == CODEC_TYPE_MPEG4 &&
1086         Check_IsPBPacked(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) {
1087         if (pDecOps->Enable_PackedPB(hMFCHandle) != VIDEO_ERROR_NONE) {
1088             ret = OMX_ErrorInsufficientResources;
1089             goto EXIT;
1090         }
1091         pMpeg4Dec->hMFCMpeg4Handle.bPackedPB = OMX_TRUE;
1092     }
1093
1094     /* set output geometry */
1095     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1096     pMpeg4Dec->hMFCMpeg4Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
1097     if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1098         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1099         ret = OMX_ErrorInsufficientResources;
1100         goto EXIT;
1101     }
1102
1103     /* input buffer enqueue for header parsing */
1104     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
1105     if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1106                         (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
1107         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
1108 //        ret = OMX_ErrorInsufficientResources;
1109         ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
1110         goto EXIT;
1111     }
1112
1113     /* start header parsing */
1114     if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1115         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
1116         ret = OMX_ErrorCodecInit;
1117         goto EXIT;
1118     }
1119
1120     ret = Mpeg4CodecCheckResolutionChange(pOMXComponent);
1121     if (ret != OMX_ErrorNone) {
1122         ret = OMX_ErrorCodecInit;
1123         goto EXIT;
1124     }
1125
1126     Exynos_OSAL_SleepMillisec(0);
1127     ret = OMX_ErrorInputDataDecodeYet;
1128
1129 #ifdef USE_IMMEDIATE_DISPLAY
1130     /* Set Immediately display for I Frame*/
1131     pDecOps->Set_ImmediateDisplay(hMFCHandle);
1132 #endif
1133 EXIT:
1134     Mpeg4CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1135     FunctionOut();
1136
1137     return ret;
1138 }
1139
1140 OMX_ERRORTYPE Mpeg4CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
1141 {
1142     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1143     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1144     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1145     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1146     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1147     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1148
1149     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1150
1151     int i, nOutbufs;
1152
1153     FunctionIn();
1154
1155     /* get dpb count */
1156     nOutbufs = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
1157
1158     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1159         /* should be done before prepare output buffer */
1160         if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1161             ret = OMX_ErrorInsufficientResources;
1162             goto EXIT;
1163         }
1164     }
1165
1166     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE
1167         ||pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE)
1168         pOutbufOps->Set_Shareable(hMFCHandle);
1169
1170     if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1171         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1172         ret = OMX_ErrorInsufficientResources;
1173         goto EXIT;
1174     }
1175
1176     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
1177     OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1178     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1179     int plane;
1180
1181     nAllocLen[0] = calc_yplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
1182                         pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight);
1183     nAllocLen[1] = calc_uvplane(pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth,
1184                         pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight >> 1);
1185
1186     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1187         pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) {
1188         Mpeg4CodecDstAllocCodecBuffers(pOMXComponent, nOutbufs);
1189         Mpeg4CodecDstRegistCodecBuffers(pOMXComponent, nOutbufs);
1190     } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1191         pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_FALSE) {
1192
1193         /* Register output buffer */
1194         for (i = 0; i < nOutbufs; i++) {
1195             int plane;
1196             OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1197             ExynosVideoBuffer *pBuffer = NULL;
1198             pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1199             Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1200
1201             if (pOutbufOps->Get_Buffer) {
1202                  if (pOutbufOps->Get_Buffer(pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
1203                      Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info");
1204                      ret = OMX_ErrorInsufficientResources;
1205                      goto EXIT;
1206                  }
1207             }
1208
1209             for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1210                 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
1211                 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
1212                 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
1213             }
1214
1215             pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1216                             (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1217         }
1218     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1219 #ifdef USE_PB
1220         if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) {
1221         for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
1222                 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1223                     planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
1224                     planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
1225                     planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane];
1226                     planes[plane].allocSize = nAllocLen[plane];
1227                 }
1228
1229                 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1230                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1231                 ret = OMX_ErrorInsufficientResources;
1232                 goto EXIT;
1233             }
1234                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
1235                                (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1236             }
1237         } else {
1238             ret = OMX_ErrorNotImplemented;
1239             goto EXIT;
1240         }
1241 #else
1242         ret = OMX_ErrorNotImplemented;
1243         goto EXIT;
1244 #endif
1245     }
1246
1247     if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1248         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1249         ret = OMX_ErrorInsufficientResources;
1250         goto EXIT;
1251     }
1252
1253     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1254         Mpeg4CodecStop (pOMXComponent, OUTPUT_PORT_INDEX);
1255     }
1256     pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_TRUE;
1257
1258     ret = OMX_ErrorNone;
1259
1260 EXIT:
1261     FunctionOut();
1262
1263     return ret;
1264 }
1265
1266 OMX_ERRORTYPE Mpeg4CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent)
1267 {
1268     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1269     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1270     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1271     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1272     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
1273     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1274     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1275
1276     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
1277     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
1278
1279     FunctionIn();
1280
1281     /* get geometry for output */
1282     Exynos_OSAL_Memset(&pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
1283     if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
1284         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
1285         ret = OMX_ErrorInsufficientResources;
1286         goto EXIT;
1287     }
1288
1289     /* get dpb count */
1290     pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
1291     if (pVideoDec->bThumbnailMode == OMX_FALSE)
1292         pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum += EXTRA_DPB_NUM;
1293     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg4CodecCheckResolutionChange Mpeg4CodecSetup nOutbufs: %d", pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum);
1294
1295     pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_TRUE;
1296
1297     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1298         if ((pVideoDec->bDRCProcessing) ||
1299             (pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
1300             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight)) {
1301             pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
1302             pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
1303             pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
1304             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
1305
1306             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1307                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1308             }
1309             Exynos_UpdateFrameSize(pOMXComponent);
1310             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1311
1312             /** Send Port Settings changed call back **/
1313         (*(pExynosComponent->pCallbacks->EventHandler))
1314             (pOMXComponent,
1315              pExynosComponent->callbackData,
1316              OMX_EventPortSettingsChanged, /* The command was completed */
1317              OMX_DirOutput, /* This is the port index */
1318                  0,
1319              NULL);
1320     }
1321     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1322         if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth) ||
1323             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight) ||
1324             (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum)) {
1325             pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth;
1326             pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight;
1327             pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
1328             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
1329
1330             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1331                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1332             }
1333 #ifdef TIZEN_FEATURE_E3250
1334             pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
1335             pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum;
1336 #else
1337             pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 4;
1338             pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg4Dec->hMFCMpeg4Handle.maxDPBNum - 4;
1339 #endif
1340             Exynos_UpdateFrameSize(pOMXComponent);
1341             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1342
1343             /** Send Port Settings changed call back **/
1344             (*(pExynosComponent->pCallbacks->EventHandler))
1345                 (pOMXComponent,
1346                  pExynosComponent->callbackData,
1347                  OMX_EventPortSettingsChanged, /* The command was completed */
1348                  OMX_DirOutput, /* This is the port index */
1349                  0,
1350                  NULL);
1351         }
1352     }
1353
1354     ret = OMX_ErrorNone;
1355
1356 EXIT:
1357     FunctionOut();
1358
1359     return ret;
1360 }
1361
1362
1363 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetParameter(
1364     OMX_IN OMX_HANDLETYPE hComponent,
1365     OMX_IN OMX_INDEXTYPE  nParamIndex,
1366     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1367 {
1368     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1369     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1370     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1371
1372     FunctionIn();
1373
1374     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1375         ret = OMX_ErrorBadParameter;
1376         goto EXIT;
1377     }
1378     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1379     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1380     if (ret != OMX_ErrorNone) {
1381         goto EXIT;
1382     }
1383     if (pOMXComponent->pComponentPrivate == NULL) {
1384         ret = OMX_ErrorBadParameter;
1385         goto EXIT;
1386     }
1387
1388     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1389     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1390         ret = OMX_ErrorInvalidState;
1391         goto EXIT;
1392     }
1393
1394     switch (nParamIndex) {
1395     case OMX_IndexParamVideoMpeg4:
1396     {
1397         OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
1398         OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = NULL;
1399         EXYNOS_MPEG4DEC_HANDLE       *pMpeg4Dec      = NULL;
1400
1401         ret = Exynos_OMX_Check_SizeVersion(pDstMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1402         if (ret != OMX_ErrorNone) {
1403             goto EXIT;
1404         }
1405
1406         if (pDstMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
1407             ret = OMX_ErrorBadPortIndex;
1408             goto EXIT;
1409         }
1410
1411         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1412         pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstMpeg4Param->nPortIndex];
1413
1414         Exynos_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1415     }
1416         break;
1417     case OMX_IndexParamVideoH263:
1418     {
1419         OMX_VIDEO_PARAM_H263TYPE  *pDstH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
1420         OMX_VIDEO_PARAM_H263TYPE  *pSrcH263Param = NULL;
1421         EXYNOS_MPEG4DEC_HANDLE       *pMpeg4Dec     = NULL;
1422
1423         ret = Exynos_OMX_Check_SizeVersion(pDstH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1424         if (ret != OMX_ErrorNone) {
1425             goto EXIT;
1426         }
1427
1428         if (pDstH263Param->nPortIndex >= ALL_PORT_NUM) {
1429             ret = OMX_ErrorBadPortIndex;
1430             goto EXIT;
1431         }
1432
1433         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1434         pSrcH263Param = &pMpeg4Dec->h263Component[pDstH263Param->nPortIndex];
1435
1436         Exynos_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1437     }
1438         break;
1439     case OMX_IndexParamStandardComponentRole:
1440     {
1441         OMX_S32                      codecType;
1442         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1443
1444         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1445         if (ret != OMX_ErrorNone) {
1446             goto EXIT;
1447         }
1448
1449         codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1450         if (codecType == CODEC_TYPE_MPEG4)
1451             Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
1452         else
1453             Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
1454     }
1455         break;
1456     case OMX_IndexParamVideoProfileLevelQuerySupported:
1457     {
1458         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel   = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1459         EXYNOS_OMX_VIDEO_PROFILELEVEL    *pProfileLevel      = NULL;
1460         OMX_U32                           maxProfileLevelNum = 0;
1461         OMX_S32                           codecType;
1462
1463         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1464         if (ret != OMX_ErrorNone) {
1465             goto EXIT;
1466         }
1467
1468         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1469             ret = OMX_ErrorBadPortIndex;
1470             goto EXIT;
1471         }
1472
1473         codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1474         if (codecType == CODEC_TYPE_MPEG4) {
1475             pProfileLevel = supportedMPEG4ProfileLevels;
1476             maxProfileLevelNum = sizeof(supportedMPEG4ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1477         } else {
1478             pProfileLevel = supportedH263ProfileLevels;
1479             maxProfileLevelNum = sizeof(supportedH263ProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1480         }
1481
1482         if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1483             ret = OMX_ErrorNoMore;
1484             goto EXIT;
1485         }
1486
1487         pProfileLevel += pDstProfileLevel->nProfileIndex;
1488         pDstProfileLevel->eProfile = pProfileLevel->profile;
1489         pDstProfileLevel->eLevel = pProfileLevel->level;
1490     }
1491         break;
1492     case OMX_IndexParamVideoProfileLevelCurrent:
1493     {
1494         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1495         OMX_VIDEO_PARAM_MPEG4TYPE        *pSrcMpeg4Param   = NULL;
1496         OMX_VIDEO_PARAM_H263TYPE         *pSrcH263Param    = NULL;
1497         EXYNOS_MPEG4DEC_HANDLE              *pMpeg4Dec        = NULL;
1498         OMX_S32                           codecType;
1499
1500         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1501         if (ret != OMX_ErrorNone) {
1502             goto EXIT;
1503         }
1504
1505         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1506             ret = OMX_ErrorBadPortIndex;
1507             goto EXIT;
1508         }
1509
1510         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1511         codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
1512         if (codecType == CODEC_TYPE_MPEG4) {
1513             pSrcMpeg4Param = &pMpeg4Dec->mpeg4Component[pDstProfileLevel->nPortIndex];
1514             pDstProfileLevel->eProfile = pSrcMpeg4Param->eProfile;
1515             pDstProfileLevel->eLevel = pSrcMpeg4Param->eLevel;
1516         } else {
1517             pSrcH263Param = &pMpeg4Dec->h263Component[pDstProfileLevel->nPortIndex];
1518             pDstProfileLevel->eProfile = pSrcH263Param->eProfile;
1519             pDstProfileLevel->eLevel = pSrcH263Param->eLevel;
1520         }
1521     }
1522         break;
1523     case OMX_IndexParamVideoErrorCorrection:
1524     {
1525         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1526         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1527         EXYNOS_MPEG4DEC_HANDLE                 *pMpeg4Dec               = NULL;
1528
1529         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1530         if (ret != OMX_ErrorNone) {
1531             goto EXIT;
1532         }
1533
1534         if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1535             ret = OMX_ErrorBadPortIndex;
1536             goto EXIT;
1537         }
1538
1539         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1540         pSrcErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
1541
1542         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1543         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1544         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1545         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1546         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1547     }
1548         break;
1549     default:
1550         ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1551         break;
1552     }
1553 EXIT:
1554     FunctionOut();
1555
1556     return ret;
1557 }
1558
1559 OMX_ERRORTYPE Exynos_Mpeg4Dec_SetParameter(
1560     OMX_IN OMX_HANDLETYPE hComponent,
1561     OMX_IN OMX_INDEXTYPE  nIndex,
1562     OMX_IN OMX_PTR        pComponentParameterStructure)
1563 {
1564     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1565     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1566     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1567
1568     FunctionIn();
1569
1570     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1571         ret = OMX_ErrorBadParameter;
1572         goto EXIT;
1573     }
1574     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1575     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1576     if (ret != OMX_ErrorNone) {
1577         goto EXIT;
1578     }
1579     if (pOMXComponent->pComponentPrivate == NULL) {
1580         ret = OMX_ErrorBadParameter;
1581         goto EXIT;
1582     }
1583
1584     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1585     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1586         ret = OMX_ErrorInvalidState;
1587         goto EXIT;
1588     }
1589
1590     switch (nIndex) {
1591     case OMX_IndexParamVideoMpeg4:
1592     {
1593         OMX_VIDEO_PARAM_MPEG4TYPE *pDstMpeg4Param = NULL;
1594         OMX_VIDEO_PARAM_MPEG4TYPE *pSrcMpeg4Param = (OMX_VIDEO_PARAM_MPEG4TYPE *)pComponentParameterStructure;
1595         EXYNOS_MPEG4DEC_HANDLE    *pMpeg4Dec      = NULL;
1596
1597         ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1598         if (ret != OMX_ErrorNone) {
1599             goto EXIT;
1600         }
1601
1602         if (pSrcMpeg4Param->nPortIndex >= ALL_PORT_NUM) {
1603             ret = OMX_ErrorBadPortIndex;
1604             goto EXIT;
1605         }
1606
1607         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1608         pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcMpeg4Param->nPortIndex];
1609
1610         Exynos_OSAL_Memcpy(pDstMpeg4Param, pSrcMpeg4Param, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
1611     }
1612         break;
1613     case OMX_IndexParamVideoH263:
1614     {
1615         OMX_VIDEO_PARAM_H263TYPE *pDstH263Param = NULL;
1616         OMX_VIDEO_PARAM_H263TYPE *pSrcH263Param = (OMX_VIDEO_PARAM_H263TYPE *)pComponentParameterStructure;
1617         EXYNOS_MPEG4DEC_HANDLE   *pMpeg4Dec     = NULL;
1618
1619         ret = Exynos_OMX_Check_SizeVersion(pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1620         if (ret != OMX_ErrorNone) {
1621             goto EXIT;
1622         }
1623
1624         if (pSrcH263Param->nPortIndex >= ALL_PORT_NUM) {
1625             ret = OMX_ErrorBadPortIndex;
1626             goto EXIT;
1627         }
1628
1629         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1630         pDstH263Param = &pMpeg4Dec->h263Component[pSrcH263Param->nPortIndex];
1631
1632         Exynos_OSAL_Memcpy(pDstH263Param, pSrcH263Param, sizeof(OMX_VIDEO_PARAM_H263TYPE));
1633     }
1634         break;
1635     case OMX_IndexParamStandardComponentRole:
1636     {
1637         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1638
1639         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1640         if (ret != OMX_ErrorNone) {
1641             goto EXIT;
1642         }
1643
1644         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1645             ret = OMX_ErrorIncorrectStateOperation;
1646             goto EXIT;
1647         }
1648
1649         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE)) {
1650             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1651         } else if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE)) {
1652             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
1653         } else {
1654             ret = OMX_ErrorBadParameter;
1655             goto EXIT;
1656         }
1657     }
1658         break;
1659     case OMX_IndexParamPortDefinition:
1660     {
1661         OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1662         OMX_U32                       portIndex       = pPortDefinition->nPortIndex;
1663         EXYNOS_OMX_BASEPORT          *pExynosPort;
1664         OMX_U32                       width, height, size;
1665         OMX_U32                       realWidth, realHeight;
1666         OMX_PARAM_PORTDEFINITIONTYPE  portDefinition_backup;
1667
1668         if (portIndex >= pExynosComponent->portParam.nPorts) {
1669             ret = OMX_ErrorBadPortIndex;
1670             goto EXIT;
1671         }
1672         ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1673         if (ret != OMX_ErrorNone) {
1674             goto EXIT;
1675         }
1676
1677         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1678
1679         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1680             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1681                 ret = OMX_ErrorIncorrectStateOperation;
1682                 goto EXIT;
1683             }
1684         }
1685         if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1686             ret = OMX_ErrorBadParameter;
1687             goto EXIT;
1688         }
1689
1690         Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize);
1691         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1692         RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup);
1693
1694         realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1695         realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1696         width = ((realWidth + 15) & (~15));
1697         height = ((realHeight + 15) & (~15));
1698         size = (width * height * 3) / 2;
1699         pExynosPort->portDefinition.format.video.nStride = width;
1700         pExynosPort->portDefinition.format.video.nSliceHeight = height;
1701         pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
1702
1703         if (portIndex == INPUT_PORT_INDEX) {
1704             EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1705             pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1706             pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1707             pExynosOutputPort->portDefinition.format.video.nStride = width;
1708             pExynosOutputPort->portDefinition.format.video.nSliceHeight = height;
1709
1710             switch ((int)pExynosOutputPort->portDefinition.format.video.eColorFormat) {
1711             case OMX_COLOR_FormatYUV420Planar:
1712             case OMX_COLOR_FormatYUV420SemiPlanar:
1713                 pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
1714                 break;
1715 #ifdef TIZEN_FEATURE_E3250 /* NV12 fd */
1716             case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
1717             case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd:
1718                 pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer);
1719                 break;
1720 #endif
1721             case OMX_SEC_COLOR_FormatNV12Tiled:
1722                 pExynosOutputPort->portDefinition.nBufferSize =
1723                     calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1724                     calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1725                 break;
1726             default:
1727                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
1728                 ret = OMX_ErrorUnsupportedSetting;
1729                 break;
1730             }
1731
1732             if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1733                 pExynosOutputPort->portDefinition.nBufferSize =
1734                     calc_yplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1735                     calc_uvplane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1736             }
1737         }
1738     }
1739         break;
1740     case OMX_IndexParamVideoProfileLevelCurrent:
1741     {
1742         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1743         OMX_VIDEO_PARAM_MPEG4TYPE        *pDstMpeg4Param   = NULL;
1744         OMX_VIDEO_PARAM_H263TYPE         *pDstH263Param    = NULL;
1745         EXYNOS_MPEG4DEC_HANDLE           *pMpeg4Dec        = NULL;
1746         OMX_S32                           codecType;
1747
1748         ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1749         if (ret != OMX_ErrorNone)
1750             goto EXIT;
1751
1752         if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1753             ret = OMX_ErrorBadPortIndex;
1754             goto EXIT;
1755         }
1756
1757         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1758         codecType = pMpeg4Dec->hMFCMpeg4Handle.codecType;
1759         if (codecType == CODEC_TYPE_MPEG4) {
1760             /*
1761              * To do: Check validity of profile & level parameters
1762              */
1763
1764             pDstMpeg4Param = &pMpeg4Dec->mpeg4Component[pSrcProfileLevel->nPortIndex];
1765             pDstMpeg4Param->eProfile = pSrcProfileLevel->eProfile;
1766             pDstMpeg4Param->eLevel = pSrcProfileLevel->eLevel;
1767         } else {
1768             /*
1769              * To do: Check validity of profile & level parameters
1770              */
1771
1772             pDstH263Param = &pMpeg4Dec->h263Component[pSrcProfileLevel->nPortIndex];
1773             pDstH263Param->eProfile = pSrcProfileLevel->eProfile;
1774             pDstH263Param->eLevel = pSrcProfileLevel->eLevel;
1775         }
1776     }
1777         break;
1778     case OMX_IndexParamVideoErrorCorrection:
1779     {
1780         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1781         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1782         EXYNOS_MPEG4DEC_HANDLE              *pMpeg4Dec               = NULL;
1783
1784         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1785         if (ret != OMX_ErrorNone) {
1786             goto EXIT;
1787         }
1788
1789         if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1790             ret = OMX_ErrorBadPortIndex;
1791             goto EXIT;
1792         }
1793
1794         pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1795         pDstErrorCorrectionType = &pMpeg4Dec->errorCorrectionType[INPUT_PORT_INDEX];
1796
1797         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1798         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1799         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1800         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1801         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1802     }
1803         break;
1804     default:
1805         ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1806         break;
1807     }
1808 EXIT:
1809     FunctionOut();
1810
1811     return ret;
1812 }
1813
1814 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetConfig(
1815     OMX_IN OMX_HANDLETYPE hComponent,
1816     OMX_IN OMX_INDEXTYPE  nIndex,
1817     OMX_IN OMX_PTR        pComponentConfigStructure)
1818 {
1819     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1820     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1821     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1822
1823     FunctionIn();
1824
1825     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1826         ret = OMX_ErrorBadParameter;
1827         goto EXIT;
1828     }
1829     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1830     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1831     if (ret != OMX_ErrorNone) {
1832         goto EXIT;
1833     }
1834     if (pOMXComponent->pComponentPrivate == NULL) {
1835         ret = OMX_ErrorBadParameter;
1836         goto EXIT;
1837     }
1838     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1839     if (pExynosComponent->currentState == OMX_StateInvalid) {
1840         ret = OMX_ErrorInvalidState;
1841         goto EXIT;
1842     }
1843
1844     switch (nIndex) {
1845     default:
1846         ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1847         break;
1848     }
1849
1850 EXIT:
1851     FunctionOut();
1852
1853     return ret;
1854 }
1855
1856 OMX_ERRORTYPE Exynos_Mpeg4Dec_SetConfig(
1857     OMX_IN OMX_HANDLETYPE hComponent,
1858     OMX_IN OMX_INDEXTYPE  nIndex,
1859     OMX_IN OMX_PTR        pComponentConfigStructure)
1860 {
1861     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1862     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1863     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1864
1865     FunctionIn();
1866
1867     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1868         ret = OMX_ErrorBadParameter;
1869         goto EXIT;
1870     }
1871     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1872     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1873     if (ret != OMX_ErrorNone) {
1874         goto EXIT;
1875     }
1876     if (pOMXComponent->pComponentPrivate == NULL) {
1877         ret = OMX_ErrorBadParameter;
1878         goto EXIT;
1879     }
1880     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1881     if (pExynosComponent->currentState == OMX_StateInvalid) {
1882         ret = OMX_ErrorInvalidState;
1883         goto EXIT;
1884     }
1885
1886     switch (nIndex) {
1887     default:
1888         ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1889         break;
1890     }
1891
1892 EXIT:
1893     FunctionOut();
1894
1895     return ret;
1896 }
1897
1898 OMX_ERRORTYPE Exynos_Mpeg4Dec_GetExtensionIndex(
1899     OMX_IN  OMX_HANDLETYPE  hComponent,
1900     OMX_IN  OMX_STRING      cParameterName,
1901     OMX_OUT OMX_INDEXTYPE  *pIndexType)
1902 {
1903     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1904     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1905     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1906
1907     FunctionIn();
1908
1909     if (hComponent == NULL) {
1910         ret = OMX_ErrorBadParameter;
1911         goto EXIT;
1912     }
1913     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1914     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1915     if (ret != OMX_ErrorNone) {
1916         goto EXIT;
1917     }
1918     if (pOMXComponent->pComponentPrivate == NULL) {
1919         ret = OMX_ErrorBadParameter;
1920         goto EXIT;
1921     }
1922     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1923     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1924         ret = OMX_ErrorBadParameter;
1925         goto EXIT;
1926     }
1927     if (pExynosComponent->currentState == OMX_StateInvalid) {
1928         ret = OMX_ErrorInvalidState;
1929         goto EXIT;
1930     }
1931
1932     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1933         *pIndexType = OMX_IndexVendorThumbnailMode;
1934         ret = OMX_ErrorNone;
1935     } else {
1936         ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1937     }
1938
1939 EXIT:
1940     FunctionOut();
1941
1942     return ret;
1943 }
1944
1945 OMX_ERRORTYPE Exynos_Mpeg4Dec_ComponentRoleEnum(
1946     OMX_IN  OMX_HANDLETYPE hComponent,
1947     OMX_OUT OMX_U8        *cRole,
1948     OMX_IN  OMX_U32        nIndex)
1949 {
1950     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1951     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1952     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1953     OMX_S32                   codecType;
1954
1955     FunctionIn();
1956
1957     if ((hComponent == NULL) || (cRole == NULL)) {
1958         ret = OMX_ErrorBadParameter;
1959         goto EXIT;
1960     }
1961     if (nIndex != (MAX_COMPONENT_ROLE_NUM - 1)) {
1962         ret = OMX_ErrorNoMore;
1963         goto EXIT;
1964     }
1965     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1966     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1967     if (ret != OMX_ErrorNone) {
1968         goto EXIT;
1969     }
1970     if (pOMXComponent->pComponentPrivate == NULL) {
1971         ret = OMX_ErrorBadParameter;
1972         goto EXIT;
1973     }
1974     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1975     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1976         ret = OMX_ErrorInvalidState;
1977         goto EXIT;
1978     }
1979
1980     codecType = ((EXYNOS_MPEG4DEC_HANDLE *)(((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle))->hMFCMpeg4Handle.codecType;
1981     if (codecType == CODEC_TYPE_MPEG4)
1982         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG4_DEC_ROLE);
1983     else
1984         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H263_DEC_ROLE);
1985
1986 EXIT:
1987     FunctionOut();
1988
1989     return ret;
1990 }
1991
1992 /* MFC Init */
1993 OMX_ERRORTYPE Exynos_Mpeg4Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1994 {
1995     OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
1996     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1997     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1998     EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1999     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2000     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec         = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
2001
2002     CSC_METHOD csc_method = CSC_METHOD_SW;
2003     int i, plane;
2004
2005     FunctionIn();
2006
2007     pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc = OMX_FALSE;
2008     pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst = OMX_FALSE;
2009     pExynosComponent->bUseFlagEOF = OMX_TRUE;
2010     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
2011
2012     /* Mpeg4 Codec Open */
2013     ret = Mpeg4CodecOpen(pMpeg4Dec);
2014     if (ret != OMX_ErrorNone) {
2015         goto EXIT;
2016     }
2017
2018     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2019         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
2020         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
2021
2022         if (pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf == OMX_TRUE) {
2023             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
2024                 pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
2025                 Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
2026                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
2027
2028             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2029             /* Use ION Allocator */
2030                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
2031                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
2032                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
2033             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
2034             if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
2035                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
2036                 ret = OMX_ErrorInsufficientResources;
2037                 goto EXIT;
2038             }
2039                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
2040             }
2041
2042                 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
2043             }
2044         } else {
2045                 ret = Mpeg4CodecSrcInit(pOMXComponent);
2046                 if (ret != OMX_ErrorNone)
2047                     goto EXIT;
2048         }
2049     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2050         /*************/
2051         /*    TBD    */
2052         /*************/
2053         /* Does not require any actions. */
2054     }
2055
2056     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2057         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
2058         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
2059     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2060         /*************/
2061         /*    TBD    */
2062         /*************/
2063         /* Does not require any actions. */
2064     }
2065
2066     pMpeg4Dec->bSourceStart = OMX_FALSE;
2067     Exynos_OSAL_SignalCreate(&pMpeg4Dec->hSourceStartEvent);
2068     pMpeg4Dec->bDestinationStart = OMX_FALSE;
2069     Exynos_OSAL_SignalCreate(&pMpeg4Dec->hDestinationStartEvent);
2070
2071     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
2072     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
2073     pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp = 0;
2074     pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = 0;
2075
2076     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
2077
2078 #if 0//defined(USE_CSC_GSCALER)
2079     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
2080 #endif
2081     pVideoDec->csc_handle = csc_init(csc_method);
2082     if (pVideoDec->csc_handle == NULL) {
2083         ret = OMX_ErrorInsufficientResources;
2084         goto EXIT;
2085     }
2086     pVideoDec->csc_set_format = OMX_FALSE;
2087
2088 EXIT:
2089     FunctionOut();
2090
2091     return ret;
2092 }
2093
2094 /* MFC Terminate */
2095 OMX_ERRORTYPE Exynos_Mpeg4Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
2096 {
2097     OMX_ERRORTYPE          ret = OMX_ErrorNone;
2098     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2099     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2100     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2101     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2102     EXYNOS_MPEG4DEC_HANDLE    *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2103
2104     int i;
2105
2106     FunctionIn();
2107
2108     if (pVideoDec->csc_handle != NULL) {
2109         csc_deinit(pVideoDec->csc_handle);
2110         pVideoDec->csc_handle = NULL;
2111     }
2112
2113     Exynos_OSAL_SignalTerminate(pMpeg4Dec->hDestinationStartEvent);
2114     pMpeg4Dec->hDestinationStartEvent = NULL;
2115     pMpeg4Dec->bDestinationStart = OMX_FALSE;
2116     Exynos_OSAL_SignalTerminate(pMpeg4Dec->hSourceStartEvent);
2117     pMpeg4Dec->hSourceStartEvent = NULL;
2118     pMpeg4Dec->bSourceStart = OMX_FALSE;
2119
2120     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2121         Mpeg4CodecDstFreeCodecBuffers(pOMXComponent);
2122
2123         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
2124         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
2125     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2126         /*************/
2127         /*    TBD    */
2128         /*************/
2129         /* Does not require any actions. */
2130     }
2131
2132     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2133         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
2134             if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
2135 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2136                 int plane;
2137                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2138                     if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
2139                         Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
2140                 }
2141 #endif
2142                 Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
2143                 pVideoDec->pMFCDecInputBuffer[i] = NULL;
2144             }
2145         }
2146
2147         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
2148         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
2149     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2150         /*************/
2151         /*    TBD    */
2152         /*************/
2153         /* Does not require any actions. */
2154     }
2155     Mpeg4CodecClose(pMpeg4Dec);
2156
2157     FunctionOut();
2158
2159     return ret;
2160 }
2161
2162 OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2163 {
2164     OMX_ERRORTYPE               ret = OMX_ErrorNone;
2165     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2166     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2167     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
2168     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
2169        OMX_BOOL bInStartCode = OMX_FALSE;
2170     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
2171     ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
2172     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2173
2174     FunctionIn();
2175
2176     if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCSrc == OMX_FALSE) {
2177         ret = Mpeg4CodecSrcSetup(pOMXComponent, pSrcInputData);
2178         goto EXIT;
2179     }
2180     if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_FALSE) {
2181         ret = Mpeg4CodecDstSetup(pOMXComponent);
2182
2183         if (ret != OMX_ErrorNone) {
2184             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg4CodecDstSetup Failed");
2185             goto EXIT;
2186         }
2187     }
2188
2189   if (((bInStartCode = Check_Stream_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize, pMpeg4Dec->hMFCMpeg4Handle.codecType)) == OMX_TRUE) ||
2190         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){
2191         pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->timeStamp;
2192         pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp] = pSrcInputData->nFlags;
2193         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);
2194         pDecOps->Set_FrameTag(hMFCHandle, pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp);
2195         pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp++;
2196         pMpeg4Dec->hMFCMpeg4Handle.indexTimestamp %= MAX_TIMESTAMP;
2197
2198 #ifdef USE_IMMEDIATE_DISPLAY
2199     /* Set Immediately display for I Frame*/
2200         if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
2201             if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) {
2202                 /* Enable Immediately display After seek*/
2203                 pDecOps->Set_ImmediateDisplay(hMFCHandle);
2204                 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE;
2205             }
2206         }
2207 #endif
2208         /* queue work for input buffer */
2209         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
2210         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
2211                                     (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
2212         if (codecReturn != VIDEO_ERROR_NONE) {
2213             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2214             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2215             goto EXIT;
2216         }
2217         Mpeg4CodecStart(pOMXComponent, INPUT_PORT_INDEX);
2218         if (pMpeg4Dec->bSourceStart == OMX_FALSE) {
2219             pMpeg4Dec->bSourceStart = OMX_TRUE;
2220             Exynos_OSAL_SignalSet(pMpeg4Dec->hSourceStartEvent);
2221             Exynos_OSAL_SleepMillisec(0);
2222         }
2223         if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
2224             pMpeg4Dec->bDestinationStart = OMX_TRUE;
2225             Exynos_OSAL_SignalSet(pMpeg4Dec->hDestinationStartEvent);
2226             Exynos_OSAL_SleepMillisec(0);
2227         }
2228          } else if (bInStartCode == OMX_FALSE) {
2229         ret = OMX_ErrorCorruptedFrame;
2230         goto EXIT;
2231     }
2232
2233     ret = OMX_ErrorNone;
2234
2235 EXIT:
2236     FunctionOut();
2237
2238     return ret;
2239 }
2240
2241 OMX_ERRORTYPE Exynos_Mpeg4Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2242 {
2243     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2244     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2245     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2246     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2247     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
2248     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2249     ExynosVideoDecBufferOps *pInbufOps  = pMpeg4Dec->hMFCMpeg4Handle.pInbufOps;
2250     ExynosVideoBuffer       *pVideoBuffer;
2251
2252     FunctionIn();
2253
2254     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
2255
2256     pSrcOutputData->dataLen       = 0;
2257     pSrcOutputData->usedDataLen   = 0;
2258     pSrcOutputData->remainDataLen = 0;
2259     pSrcOutputData->nFlags    = 0;
2260     pSrcOutputData->timeStamp = 0;
2261
2262     if (pVideoBuffer == NULL) {
2263         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2264         pSrcOutputData->allocSize  = 0;
2265         pSrcOutputData->pPrivate = NULL;
2266         pSrcOutputData->bufferHeader = NULL;
2267     } else {
2268         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2269         pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2270         pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
2271
2272         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2273             int i = 0;
2274             while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
2275                 i++;
2276                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2277                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2278                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2279                     goto EXIT;
2280                 }
2281             }
2282             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
2283             pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
2284         }
2285
2286         /* For Share Buffer */
2287         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2288     }
2289
2290     ret = OMX_ErrorNone;
2291
2292 EXIT:
2293     FunctionOut();
2294
2295     return ret;
2296 }
2297
2298 OMX_ERRORTYPE Exynos_Mpeg4Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2299 {
2300     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2301     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2302     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2303     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2304     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
2305     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2306     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
2307     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
2308     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2309
2310     FunctionIn();
2311
2312     if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
2313         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2314         ret = OMX_ErrorBadParameter;
2315         goto EXIT;
2316     }
2317
2318     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
2319                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
2320                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
2321
2322     if ((pVideoDec->bDRCProcessing == OMX_TRUE) &&
2323         (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2324         (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
2325         ret = Mpeg4CodecDstSetup(pOMXComponent);
2326         if (ret != OMX_ErrorNone) {
2327             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig CodecDstSetup Failed");
2328             goto EXIT;
2329         }
2330         pVideoDec->bDRCProcessing = OMX_FALSE;
2331     }
2332
2333     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
2334                  (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2335
2336     if (codecReturn != VIDEO_ERROR_NONE) {
2337         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2338         ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2339         goto EXIT;
2340     }
2341     Mpeg4CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2342
2343     ret = OMX_ErrorNone;
2344
2345 EXIT:
2346     FunctionOut();
2347
2348     return ret;
2349 }
2350
2351 OMX_ERRORTYPE Exynos_Mpeg4Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2352 {
2353     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2354     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2355     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2356     EXYNOS_MPEG4DEC_HANDLE         *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2357     void                          *hMFCHandle = pMpeg4Dec->hMFCMpeg4Handle.hMFCHandle;
2358     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2359     ExynosVideoDecOps       *pDecOps    = pMpeg4Dec->hMFCMpeg4Handle.pDecOps;
2360     ExynosVideoDecBufferOps *pOutbufOps = pMpeg4Dec->hMFCMpeg4Handle.pOutbufOps;
2361     ExynosVideoBuffer       *pVideoBuffer;
2362     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2363     ExynosVideoGeometry *bufferGeometry;
2364     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
2365     OMX_S32 indexTimestamp = 0;
2366     int plane;
2367
2368     FunctionIn();
2369
2370     if (pMpeg4Dec->bDestinationStart == OMX_FALSE) {
2371         ret = OMX_ErrorNone;
2372         goto EXIT;
2373     }
2374
2375     while (1) {
2376         pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2377         if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2378             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2379             ret = OMX_ErrorHardware;
2380             goto EXIT;
2381         }
2382
2383         if (pVideoBuffer == NULL) {
2384             ret = OMX_ErrorNone;
2385             goto EXIT;
2386         }
2387         displayStatus = pVideoBuffer->displayStatus;
2388         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
2389
2390         if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2391             (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2392             (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2393             (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2394             (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2395             ret = OMX_ErrorNone;
2396             break;
2397         }
2398     }
2399
2400     if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) {
2401         if (pVideoDec->bDRCProcessing != OMX_TRUE) {
2402             pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2403             pVideoDec->bDRCProcessing = OMX_TRUE;
2404             Mpeg4CodecCheckResolutionChange(pOMXComponent);
2405             pVideoDec->csc_set_format = OMX_FALSE;
2406         }
2407         ret = OMX_ErrorNone;
2408         goto EXIT;
2409     }
2410
2411     pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp++;
2412     pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2413
2414     pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2415     for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
2416         pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2417         pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2418         pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo;
2419         pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2420         pDstOutputData->dataLen +=  pVideoBuffer->planes[plane].dataSize;
2421     }
2422     pDstOutputData->usedDataLen = 0;
2423     pDstOutputData->pPrivate = pVideoBuffer;
2424     /* For Share Buffer */
2425     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2426
2427     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2428     bufferGeometry = &pMpeg4Dec->hMFCMpeg4Handle.codecOutbufConf;
2429     pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2430     pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2431     switch (bufferGeometry->eColorFormat) {
2432     case VIDEO_COLORFORMAT_NV12:
2433 #ifdef TIZEN_FEATURE_E3250 /* NV12 fd */
2434         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2435 #else
2436         pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2437 #endif
2438         break;
2439     case VIDEO_COLORFORMAT_NV12_TILED:
2440     default:
2441         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
2442         break;
2443     }
2444
2445     indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2446     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
2447     if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2448         if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2449             (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2450             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2451             pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2452             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2453         } else {
2454             pDstOutputData->timeStamp = 0x00;
2455             pDstOutputData->nFlags = 0x00;
2456         }
2457     } else {
2458         /* For timestamp correction. if mfc support frametype detect */
2459         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
2460 //#ifdef NEED_TIMESTAMP_REORDER
2461         if (pMpeg4Dec->hMFCMpeg4Handle.bPackedPB == OMX_TRUE ||
2462             pVideoDec->bNeedTimestampReorder == OMX_TRUE) { /* TIZEN_FEATURE_E3250 */
2463             if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
2464                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2465                 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2466                 pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp = indexTimestamp;
2467             } else {
2468                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2469                 pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg4Dec->hMFCMpeg4Handle.outputIndexTimestamp];
2470             }
2471         } else {
2472 //#else
2473             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2474             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2475         }
2476 //#endif
2477         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2478     }
2479
2480     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2481         (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2482         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2483         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2484         pDstOutputData->remainDataLen = 0;
2485     } else {
2486         pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2487     }
2488
2489     ret = OMX_ErrorNone;
2490
2491 EXIT:
2492     FunctionOut();
2493
2494     return ret;
2495 }
2496
2497 OMX_ERRORTYPE Exynos_Mpeg4Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2498 {
2499     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2500     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2501     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2502
2503     FunctionIn();
2504
2505     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2506         ret = OMX_ErrorNone;
2507         goto EXIT;
2508     }
2509     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2510         ret = OMX_ErrorNone;
2511         goto EXIT;
2512     }
2513
2514     ret = Exynos_Mpeg4Dec_SrcIn(pOMXComponent, pSrcInputData);
2515 if ((ret != OMX_ErrorNone) &&
2516         (ret != (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) &&
2517         (ret != (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame)) {
2518         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2519                                                 pExynosComponent->callbackData,
2520                                                 OMX_EventError, ret, 0, NULL);
2521     }
2522
2523 EXIT:
2524     FunctionOut();
2525
2526     return ret;
2527 }
2528
2529 OMX_ERRORTYPE Exynos_Mpeg4Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2530 {
2531     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2532     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2533     EXYNOS_MPEG4DEC_HANDLE   *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2534     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2535
2536     FunctionIn();
2537
2538     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2539         ret = OMX_ErrorNone;
2540         goto EXIT;
2541     }
2542
2543     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2544         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2545             ret = OMX_ErrorNone;
2546             goto EXIT;
2547         }
2548     }
2549     if ((pMpeg4Dec->bSourceStart == OMX_FALSE) &&
2550        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2551         Exynos_OSAL_SignalWait(pMpeg4Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2552         Exynos_OSAL_SignalReset(pMpeg4Dec->hSourceStartEvent);
2553     }
2554
2555     ret = Exynos_Mpeg4Dec_SrcOut(pOMXComponent, pSrcOutputData);
2556     if ((ret != OMX_ErrorNone) &&
2557         (pExynosComponent->currentState == OMX_StateExecuting)) {
2558         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2559                                                 pExynosComponent->callbackData,
2560                                                 OMX_EventError, ret, 0, NULL);
2561     }
2562
2563 EXIT:
2564     FunctionOut();
2565
2566     return ret;
2567 }
2568
2569 OMX_ERRORTYPE Exynos_Mpeg4Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2570 {
2571     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2572     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2573     EXYNOS_MPEG4DEC_HANDLE    *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2574     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2575
2576     FunctionIn();
2577
2578     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2579         ret = OMX_ErrorNone;
2580         goto EXIT;
2581     }
2582     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2583         ret = OMX_ErrorNone;
2584         goto EXIT;
2585     }
2586     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2587         if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
2588            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2589             Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2590             Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
2591         }
2592     }
2593     if (pMpeg4Dec->hMFCMpeg4Handle.bConfiguredMFCDst == OMX_TRUE) {
2594         ret = Exynos_Mpeg4Dec_DstIn(pOMXComponent, pDstInputData);
2595         if (ret != OMX_ErrorNone) {
2596             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2597                                                 pExynosComponent->callbackData,
2598                                                 OMX_EventError, ret, 0, NULL);
2599         }
2600     }
2601
2602 EXIT:
2603     FunctionOut();
2604
2605     return ret;
2606 }
2607
2608 OMX_ERRORTYPE Exynos_Mpeg4Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2609 {
2610     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2611     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2612     EXYNOS_MPEG4DEC_HANDLE   *pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2613     EXYNOS_OMX_BASEPORT     *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2614
2615     FunctionIn();
2616
2617     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2618         ret = OMX_ErrorNone;
2619         goto EXIT;
2620     }
2621     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2622         ret = OMX_ErrorNone;
2623         goto EXIT;
2624     }
2625
2626     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2627         if ((pMpeg4Dec->bDestinationStart == OMX_FALSE) &&
2628             (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2629             Exynos_OSAL_SignalWait(pMpeg4Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2630             Exynos_OSAL_SignalReset(pMpeg4Dec->hDestinationStartEvent);
2631         }
2632     }
2633     ret = Exynos_Mpeg4Dec_DstOut(pOMXComponent, pDstOutputData);
2634     if ((ret != OMX_ErrorNone) &&
2635         (pExynosComponent->currentState == OMX_StateExecuting)) {
2636         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2637                                                 pExynosComponent->callbackData,
2638                                                 OMX_EventError, ret, 0, NULL);
2639     }
2640
2641 EXIT:
2642     FunctionOut();
2643
2644     return ret;
2645 }
2646
2647 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2648 {
2649     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2650     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2651     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2652     EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2653     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
2654     EXYNOS_MPEG4DEC_HANDLE        *pMpeg4Dec        = NULL;
2655     int i = 0;
2656     OMX_S32 codecType = -1;
2657
2658     FunctionIn();
2659
2660     if ((hComponent == NULL) || (componentName == NULL)) {
2661         ret = OMX_ErrorBadParameter;
2662         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2663         goto EXIT;
2664     }
2665     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG4_DEC, componentName) == 0) {
2666         codecType = CODEC_TYPE_MPEG4;
2667     } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H263_DEC, componentName) == 0) {
2668         codecType = CODEC_TYPE_H263;
2669     } else {
2670         ret = OMX_ErrorBadParameter;
2671         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2672         goto EXIT;
2673     }
2674
2675     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2676     ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2677     if (ret != OMX_ErrorNone) {
2678         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2679         goto EXIT;
2680     }
2681     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2682     pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2683
2684     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2685     if (pExynosComponent->componentName == NULL) {
2686         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2687         ret = OMX_ErrorInsufficientResources;
2688         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2689         goto EXIT;
2690     }
2691     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2692
2693     pMpeg4Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG4DEC_HANDLE));
2694     if (pMpeg4Dec == NULL) {
2695         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2696         ret = OMX_ErrorInsufficientResources;
2697         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2698         goto EXIT;
2699     }
2700     Exynos_OSAL_Memset(pMpeg4Dec, 0, sizeof(EXYNOS_MPEG4DEC_HANDLE));
2701     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2702     pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg4Dec;
2703     pMpeg4Dec->hMFCMpeg4Handle.codecType = codecType;
2704
2705     if (codecType == CODEC_TYPE_MPEG4)
2706         Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG4_DEC);
2707     else
2708         Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H263_DEC);
2709
2710     /* In case of BUFFER_COPY mode
2711             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2712             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2713          In case of BUFFER_SHARE
2714             bShareableBuf should be TRUE, FALSE is ignored
2715     */
2716     pMpeg4Dec->hMFCMpeg4Handle.bShareableBuf = OMX_FALSE;
2717     pMpeg4Dec->hMFCMpeg4Handle.bPackedPB = OMX_FALSE;
2718
2719     /* Set componentVersion */
2720     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2721     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2722     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2723     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2724     /* Set specVersion */
2725     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2726     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2727     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2728     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2729
2730     /* Input port */
2731     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2732     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2733     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2734     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2735     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2736     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2737     if (codecType == CODEC_TYPE_MPEG4) {
2738         pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
2739         Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2740         Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg4");
2741     } else {
2742         pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingH263;
2743         Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2744         Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/h263");
2745     }
2746     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2747     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2748     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2749     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2750     pExynosPort->bufferProcessType = BUFFER_COPY;
2751     pExynosPort->portWayType = WAY2_PORT;
2752
2753     /* Output port */
2754     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2755     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2756     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2757     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2758     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2759     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2760     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2761     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2762     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2763     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2764     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2765 #ifdef TIZEN_FEATURE_E3250
2766     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2767     pExynosPort->bufferProcessType = BUFFER_SHARE;
2768 #else
2769     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2770     pExynosPort->bufferProcessType = BUFFER_COPY;
2771 #endif
2772     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2773     pExynosPort->portWayType = WAY2_PORT;
2774
2775     if (codecType == CODEC_TYPE_MPEG4) {
2776         for(i = 0; i < ALL_PORT_NUM; i++) {
2777             INIT_SET_SIZE_VERSION(&pMpeg4Dec->mpeg4Component[i], OMX_VIDEO_PARAM_MPEG4TYPE);
2778             pMpeg4Dec->mpeg4Component[i].nPortIndex = i;
2779             pMpeg4Dec->mpeg4Component[i].eProfile   = OMX_VIDEO_MPEG4ProfileSimple;
2780             pMpeg4Dec->mpeg4Component[i].eLevel     = OMX_VIDEO_MPEG4Level3;
2781         }
2782     } else {
2783         for(i = 0; i < ALL_PORT_NUM; i++) {
2784             INIT_SET_SIZE_VERSION(&pMpeg4Dec->h263Component[i], OMX_VIDEO_PARAM_H263TYPE);
2785             pMpeg4Dec->h263Component[i].nPortIndex = i;
2786             pMpeg4Dec->h263Component[i].eProfile   = OMX_VIDEO_H263ProfileBaseline | OMX_VIDEO_H263ProfileISWV2;
2787             pMpeg4Dec->h263Component[i].eLevel     = OMX_VIDEO_H263Level45;
2788         }
2789     }
2790
2791     pOMXComponent->GetParameter      = &Exynos_Mpeg4Dec_GetParameter;
2792     pOMXComponent->SetParameter      = &Exynos_Mpeg4Dec_SetParameter;
2793     pOMXComponent->GetConfig         = &Exynos_Mpeg4Dec_GetConfig;
2794     pOMXComponent->SetConfig         = &Exynos_Mpeg4Dec_SetConfig;
2795     pOMXComponent->GetExtensionIndex = &Exynos_Mpeg4Dec_GetExtensionIndex;
2796     pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg4Dec_ComponentRoleEnum;
2797     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2798
2799     pExynosComponent->exynos_codec_componentInit      = &Exynos_Mpeg4Dec_Init;
2800     pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg4Dec_Terminate;
2801
2802     pVideoDec->exynos_codec_srcInputProcess  = &Exynos_Mpeg4Dec_srcInputBufferProcess;
2803     pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg4Dec_srcOutputBufferProcess;
2804     pVideoDec->exynos_codec_dstInputProcess  = &Exynos_Mpeg4Dec_dstInputBufferProcess;
2805     pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg4Dec_dstOutputBufferProcess;
2806
2807     pVideoDec->exynos_codec_start            = &Mpeg4CodecStart;
2808     pVideoDec->exynos_codec_stop             = &Mpeg4CodecStop;
2809     pVideoDec->exynos_codec_bufferProcessRun = &Mpeg4CodecOutputBufferProcessRun;
2810     pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg4CodecEnQueueAllBuffer;
2811     pVideoDec->exynos_codec_resetupAllElement = &Mpeg4CodecResetupAllElement;
2812
2813     pVideoDec->exynos_checkInputFrame = NULL;
2814     pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2815     pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2816
2817 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2818     pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2819     if (pVideoDec->hSharedMemory == NULL) {
2820         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2821         Exynos_OSAL_Free(pMpeg4Dec);
2822         pMpeg4Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2823         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2824         ret = OMX_ErrorInsufficientResources;
2825         goto EXIT;
2826     }
2827 #endif
2828     pExynosComponent->currentState = OMX_StateLoaded;
2829
2830     ret = OMX_ErrorNone;
2831
2832 EXIT:
2833     FunctionOut();
2834
2835     return ret;
2836 }
2837
2838 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2839 {
2840     OMX_ERRORTYPE            ret = OMX_ErrorNone;
2841     OMX_COMPONENTTYPE       *pOMXComponent = NULL;
2842     EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
2843     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2844     EXYNOS_MPEG4DEC_HANDLE      *pMpeg4Dec = NULL;
2845
2846     FunctionIn();
2847
2848     if (hComponent == NULL) {
2849         ret = OMX_ErrorBadParameter;
2850         goto EXIT;
2851     }
2852     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2853     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2854     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2855 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2856     Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2857 #endif
2858     Exynos_OSAL_Free(pExynosComponent->componentName);
2859     pExynosComponent->componentName = NULL;
2860
2861     pMpeg4Dec = (EXYNOS_MPEG4DEC_HANDLE *)pVideoDec->hCodecHandle;
2862     if (pMpeg4Dec != NULL) {
2863         Exynos_OSAL_Free(pMpeg4Dec);
2864         pMpeg4Dec = pVideoDec->hCodecHandle = NULL;
2865     }
2866
2867     ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2868     if (ret != OMX_ErrorNone) {
2869         goto EXIT;
2870     }
2871
2872     ret = OMX_ErrorNone;
2873
2874 EXIT:
2875     FunctionOut();
2876
2877     return ret;
2878 }