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