for callback invoke when resolution is changed
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / dec / mpeg2 / Exynos_OMX_Mpeg2dec.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_Mpeg2dec.c
20  * @brief
21  * @author      Satish Kumar Reddy (palli.satish@samsung.com)
22  * @version     2.0.0
23  * @history
24  *   2012.07.10 : Create
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <mm_types.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OMX_Basecomponent.h"
34 #include "Exynos_OMX_Baseport.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OSAL_ETC.h"
37 #include "Exynos_OSAL_Semaphore.h"
38 #include "Exynos_OSAL_Thread.h"
39 #include "library_register.h"
40 #include "Exynos_OMX_Mpeg2dec.h"
41 #include "ExynosVideoApi.h"
42 #include "Exynos_OSAL_SharedMemory.h"
43 #include "Exynos_OSAL_Event.h"
44
45 #ifdef USE_PB
46 #include "Exynos_OSAL_Platform_Specific.h"
47 #endif
48
49 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
50 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
51 #include "csc.h"
52
53 #undef  EXYNOS_LOG_TAG
54 #define EXYNOS_LOG_TAG    "EXYNOS_MPEG2_DEC"
55 #define EXYNOS_LOG_OFF
56 //#define EXYNOS_TRACE_ON
57 #include "Exynos_OSAL_Log.h"
58
59 #define MPEG2_DEC_NUM_OF_EXTRA_BUFFERS 7
60
61 //#define FULL_FRAME_SEARCH /* Full frame search not support*/
62
63 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
64 {
65     OMX_ERRORTYPE       ret = OMX_ErrorNone;
66
67 EXIT:
68     return ret;
69 }
70
71 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, void *addr[], int size[])
72 {
73     OMX_ERRORTYPE       ret = OMX_ErrorNone;
74     ExynosVideoBuffer  *pCodecBuffer;
75
76     if (codecBuffer == NULL) {
77         ret = OMX_ErrorBadParameter;
78         goto EXIT;
79     }
80
81     pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
82
83     if (addr != NULL) {
84         addr[0] = pCodecBuffer->planes[0].addr;
85         addr[1] = pCodecBuffer->planes[1].addr;
86         addr[2] = pCodecBuffer->planes[2].addr;
87     }
88
89     if (size != NULL) {
90         size[0] = pCodecBuffer->planes[0].allocSize;
91         size[1] = pCodecBuffer->planes[1].allocSize;
92         size[2] = pCodecBuffer->planes[2].allocSize;
93     }
94
95 EXIT:
96     return ret;
97 }
98
99 int Check_Mpeg2_Frame(
100     OMX_U8   *pInputStream,
101     int       buffSize,
102     OMX_U32   flag,
103     OMX_BOOL  bPreviousFrameEOF,
104     OMX_BOOL *pbEndOfFrame)
105 {
106     FunctionIn();
107
108     *pbEndOfFrame = OMX_TRUE;
109
110     /* Frame  Start code*/
111     if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) {
112         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found");
113         *pbEndOfFrame = OMX_FALSE;
114     }
115
116     FunctionOut();
117     return buffSize;
118 }
119
120 static OMX_BOOL Check_Mpeg2_StartCode(
121     OMX_U8     *pInputStream,
122     OMX_U32     streamSize)
123 {
124     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "streamSize: %d",streamSize);
125
126     if (streamSize < 3) {
127         return OMX_FALSE;
128     }
129
130     /* Frame  Start code*/
131     if (pInputStream[0] != 0x00 || pInputStream[1] != 0x00 || pInputStream[2]!=0x01) {
132         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mpeg2 Frame Start Code not Found");
133         return OMX_FALSE;
134     }
135
136     return OMX_TRUE;
137 }
138
139 OMX_ERRORTYPE Mpeg2CodecOpen(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec)
140 {
141     OMX_ERRORTYPE           ret = OMX_ErrorNone;
142     ExynosVideoDecOps       *pDecOps    = NULL;
143     ExynosVideoDecBufferOps *pInbufOps  = NULL;
144     ExynosVideoDecBufferOps *pOutbufOps = NULL;
145
146     FunctionIn();
147
148     if (pMpeg2Dec == NULL) {
149         ret = OMX_ErrorBadParameter;
150         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
151         goto EXIT;
152     }
153
154     /* alloc ops structure */
155     pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
156     pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
157     pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
158
159     if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
160         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
161         ret = OMX_ErrorInsufficientResources;
162         goto EXIT;
163     }
164
165     pMpeg2Dec->hMFCMpeg2Handle.pDecOps    = pDecOps;
166     pMpeg2Dec->hMFCMpeg2Handle.pInbufOps  = pInbufOps;
167     pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = pOutbufOps;
168
169     /* function pointer mapping */
170     pDecOps->nSize    = sizeof(ExynosVideoDecOps);
171     pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
172     pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
173
174     Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
175
176     /* check mandatory functions for decoder ops */
177     if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
178         (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
179         (pDecOps->Get_FrameTag == NULL)) {
180         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
181         ret = OMX_ErrorInsufficientResources;
182         goto EXIT;
183     }
184
185     /* check mandatory functions for buffer ops */
186     if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
187         (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
188         (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
189         (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
190         (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
191         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
192         ret = OMX_ErrorInsufficientResources;
193         goto EXIT;
194     }
195
196     /* alloc context, open, querycap */
197 #ifdef USE_DMA_BUF
198     pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
199 #else
200     pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.pDecOps->Init(V4L2_MEMORY_USERPTR);
201 #endif
202     if (pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle == NULL) {
203         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
204         ret = OMX_ErrorInsufficientResources;
205         goto EXIT;
206     }
207
208     ret = OMX_ErrorNone;
209
210 EXIT:
211     if (ret != OMX_ErrorNone) {
212         if (pDecOps != NULL) {
213             Exynos_OSAL_Free(pDecOps);
214             pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL;
215         }
216         if (pInbufOps != NULL) {
217             Exynos_OSAL_Free(pInbufOps);
218             pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL;
219         }
220         if (pOutbufOps != NULL) {
221             Exynos_OSAL_Free(pOutbufOps);
222             pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL;
223         }
224     }
225
226     FunctionOut();
227
228     return ret;
229 }
230
231 OMX_ERRORTYPE Mpeg2CodecClose(EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec)
232 {
233     OMX_ERRORTYPE            ret = OMX_ErrorNone;
234     void                    *hMFCHandle = NULL;
235     ExynosVideoDecOps       *pDecOps    = NULL;
236     ExynosVideoDecBufferOps *pInbufOps  = NULL;
237     ExynosVideoDecBufferOps *pOutbufOps = NULL;
238
239     FunctionIn();
240
241     if (pMpeg2Dec == NULL) {
242         ret = OMX_ErrorBadParameter;
243         goto EXIT;
244     }
245
246     hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
247     pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
248     pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
249     pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
250
251     if (hMFCHandle != NULL) {
252         pDecOps->Finalize(hMFCHandle);
253         pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle = NULL;
254     }
255     if (pOutbufOps != NULL) {
256         Exynos_OSAL_Free(pOutbufOps);
257         pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps = NULL;
258     }
259     if (pInbufOps != NULL) {
260         Exynos_OSAL_Free(pInbufOps);
261         pMpeg2Dec->hMFCMpeg2Handle.pInbufOps = NULL;
262     }
263     if (pDecOps != NULL) {
264         Exynos_OSAL_Free(pDecOps);
265         pMpeg2Dec->hMFCMpeg2Handle.pDecOps = NULL;
266     }
267
268     ret = OMX_ErrorNone;
269
270 EXIT:
271     FunctionOut();
272
273     return ret;
274 }
275
276 OMX_ERRORTYPE Mpeg2CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
277 {
278     OMX_ERRORTYPE            ret = OMX_ErrorNone;
279     void                    *hMFCHandle = NULL;
280     ExynosVideoDecOps       *pDecOps    = NULL;
281     ExynosVideoDecBufferOps *pInbufOps  = NULL;
282     ExynosVideoDecBufferOps *pOutbufOps = NULL;
283     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
284     EXYNOS_MPEG2DEC_HANDLE   *pMpeg2Dec = NULL;
285
286     FunctionIn();
287
288     if (pOMXComponent == NULL) {
289         ret = OMX_ErrorBadParameter;
290         goto EXIT;
291     }
292
293     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
294     if (pVideoDec == NULL) {
295         ret = OMX_ErrorBadParameter;
296         goto EXIT;
297     }
298
299     pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
300     if (pMpeg2Dec == NULL) {
301         ret = OMX_ErrorBadParameter;
302         goto EXIT;
303     }
304
305     hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
306     pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
307     pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
308     pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
309
310     if (nPortIndex == INPUT_PORT_INDEX)
311         pInbufOps->Run(hMFCHandle);
312     else if (nPortIndex == OUTPUT_PORT_INDEX)
313         pOutbufOps->Run(hMFCHandle);
314
315     ret = OMX_ErrorNone;
316
317 EXIT:
318     FunctionOut();
319
320     return ret;
321 }
322
323 OMX_ERRORTYPE Mpeg2CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
324 {
325     OMX_ERRORTYPE            ret = OMX_ErrorNone;
326     void                    *hMFCHandle = NULL;
327     ExynosVideoDecOps       *pDecOps    = NULL;
328     ExynosVideoDecBufferOps *pInbufOps  = NULL;
329     ExynosVideoDecBufferOps *pOutbufOps = NULL;
330     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
331     EXYNOS_MPEG2DEC_HANDLE   *pMpeg2Dec = NULL;
332
333     FunctionIn();
334
335     if (pOMXComponent == NULL) {
336         ret = OMX_ErrorBadParameter;
337         goto EXIT;
338     }
339
340     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
341     if (pVideoDec == NULL) {
342         ret = OMX_ErrorBadParameter;
343         goto EXIT;
344     }
345     pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
346     if (pMpeg2Dec == NULL) {
347         ret = OMX_ErrorBadParameter;
348         goto EXIT;
349     }
350
351     hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
352     pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
353     pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
354     pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
355
356     if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
357         pInbufOps->Stop(hMFCHandle);
358     else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
359         pOutbufOps->Stop(hMFCHandle);
360
361     ret = OMX_ErrorNone;
362
363 EXIT:
364     FunctionOut();
365
366     return ret;
367 }
368
369 OMX_ERRORTYPE Mpeg2CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
370 {
371     OMX_ERRORTYPE            ret = OMX_ErrorNone;
372     void                    *hMFCHandle = NULL;
373     ExynosVideoDecOps       *pDecOps    = NULL;
374     ExynosVideoDecBufferOps *pInbufOps  = NULL;
375     ExynosVideoDecBufferOps *pOutbufOps = NULL;
376     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
377     EXYNOS_MPEG2DEC_HANDLE   *pMpeg2Dec = NULL;
378
379     FunctionIn();
380
381     if (pOMXComponent == NULL) {
382         ret = OMX_ErrorBadParameter;
383         goto EXIT;
384     }
385
386     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
387     if (pVideoDec == NULL) {
388         ret = OMX_ErrorBadParameter;
389         goto EXIT;
390     }
391     pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
392     if (pMpeg2Dec == NULL) {
393         ret = OMX_ErrorBadParameter;
394         goto EXIT;
395     }
396
397     hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
398     pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
399     pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
400     pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
401
402     if (nPortIndex == INPUT_PORT_INDEX) {
403         if (pMpeg2Dec->bSourceStart == OMX_FALSE) {
404             Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent);
405             Exynos_OSAL_SleepMillisec(0);
406         }
407     }
408
409     if (nPortIndex == OUTPUT_PORT_INDEX) {
410         if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
411             Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent);
412             Exynos_OSAL_SleepMillisec(0);
413         }
414     }
415
416     ret = OMX_ErrorNone;
417
418 EXIT:
419     FunctionOut();
420
421     return ret;
422 }
423
424 OMX_ERRORTYPE Mpeg2CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
425 {
426     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
427     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
428     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
429     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
430     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
431     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
432     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
433     int i, nOutbufs;
434
435     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
436     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
437     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
438
439     FunctionIn();
440
441     if ((nPortIndex == INPUT_PORT_INDEX) &&
442         (pMpeg2Dec->bSourceStart == OMX_TRUE)) {
443         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
444
445         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
446             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
447             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
448
449             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
450         }
451
452         pInbufOps->Clear_Queue(hMFCHandle);
453     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
454                (pMpeg2Dec->bDestinationStart == OMX_TRUE)) {
455         OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
456         ExynosVideoBuffer *pBuffer = NULL;
457
458         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
459
460         nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
461         nOutbufs += EXTRA_DPB_NUM;
462         for (i = 0; i < nOutbufs; i++) {
463             pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
464             Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
465         }
466         pOutbufOps->Clear_Queue(hMFCHandle);
467     } else {
468         ret = OMX_ErrorBadParameter;
469         goto EXIT;
470     }
471
472 EXIT:
473     FunctionOut();
474
475     return ret;
476 }
477
478 OMX_ERRORTYPE Mpeg2CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
479 {
480     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
481     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
482     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
483     EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
484     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
485     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
486     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
487     OMX_U32                        oneFrameSize = pSrcInputData->dataLen;
488
489     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
490     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
491     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
492     ExynosVideoGeometry      bufferConf;
493     OMX_U32                  inputBufferNumber = 0;
494     int i;
495
496     FunctionIn();
497
498     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
499         OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
500         OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
501         if (OMXBuffer == NULL) {
502             ret = OMX_ErrorUndefined;
503             goto EXIT;
504         }
505
506         OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
507         OMXBuffer->nFlags = pSrcInputData->nFlags;
508         Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
509
510         ret = OMX_ErrorNone;
511         goto EXIT;
512     }
513
514     if (pVideoDec->bThumbnailMode == OMX_TRUE)
515         pDecOps->Set_DisplayDelay(hMFCHandle, 0);
516
517     /* input buffer info */
518     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
519     bufferConf.eCompressionFormat = VIDEO_CODING_MPEG2;
520     pInbufOps->Set_Shareable(hMFCHandle);
521     if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
522         bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
523                                 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
524         inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
525     } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
526         bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
527         inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
528     }
529
530     /* should be done before prepare input buffer */
531     if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
532         ret = OMX_ErrorInsufficientResources;
533         goto EXIT;
534     }
535
536     /* set input buffer geometry */
537     if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
538         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
539         ret = OMX_ErrorInsufficientResources;
540         goto EXIT;
541     }
542
543     /* setup input buffer */
544     if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
545         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
546         ret = OMX_ErrorInsufficientResources;
547         goto EXIT;
548     }
549
550     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
551         /* Register input buffer */
552         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
553             ExynosVideoPlane plane;
554             plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
555             plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
556             plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
557             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
558                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "BUFFER_COPY Failed to Register input buffer");
559                 ret = OMX_ErrorInsufficientResources;
560                 goto EXIT;
561             }
562         }
563     } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
564         /* Register input buffer */
565         for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
566             ExynosVideoPlane plane;
567             plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
568             plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
569             plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
570             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
571                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "BUFFER_SHARE Failed to Register input buffer");
572                 ret = OMX_ErrorInsufficientResources;
573                 goto EXIT;
574             }
575         }
576     }
577
578     /* set output geometry */
579     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
580     pMpeg2Dec->hMFCMpeg2Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
581     if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
582         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
583         ret = OMX_ErrorInsufficientResources;
584         goto EXIT;
585     }
586
587     /* input buffer enqueue for header parsing */
588     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
589     if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
590                         (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
591         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
592 //        ret = OMX_ErrorInsufficientResources;
593         ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
594         goto EXIT;
595     }
596
597     /* start header parsing */
598     if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
599         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
600         ret = OMX_ErrorCodecInit;
601         goto EXIT;
602     }
603
604     /* get geometry for output */
605     Exynos_OSAL_Memset(&pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
606     if (pOutbufOps->Get_Geometry(hMFCHandle, &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
607         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
608         ret = OMX_ErrorInsufficientResources;
609         goto EXIT;
610     }
611
612     /* get dpb count */
613     pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
614     if (pVideoDec->bThumbnailMode == OMX_FALSE)
615         pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum += EXTRA_DPB_NUM;
616     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Mpeg2CodecSetup nOutbufs: %d", pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum);
617
618     pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_TRUE;
619
620     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
621         if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
622             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight)) {
623             pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
624             pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
625             pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
626             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
627
628             Exynos_UpdateFrameSize(pOMXComponent);
629 /* FIXME: OMX_EventPortSettingsChanged. do not set NEED_PORT_DISABLE in SLP platform now */
630 /*            pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;*/
631
632             /** Send Port Settings changed call back **/
633             (*(pExynosComponent->pCallbacks->EventHandler))
634                 (pOMXComponent,
635                  pExynosComponent->callbackData,
636                  OMX_EventPortSettingsChanged, /* The command was completed */
637                  OMX_DirOutput, /* This is the port index */
638                  0,
639                  NULL);
640         }
641     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
642         if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth) ||
643             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight) ||
644             (pExynosOutputPort->portDefinition.nBufferCountActual != pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum)) {
645             pExynosInputPort->portDefinition.format.video.nFrameWidth = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth;
646             pExynosInputPort->portDefinition.format.video.nFrameHeight = pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight;
647             pExynosInputPort->portDefinition.format.video.nStride = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
648             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
649
650             pExynosOutputPort->portDefinition.nBufferCountActual = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum - 4;
651             pExynosOutputPort->portDefinition.nBufferCountMin = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum - 4;
652
653             Exynos_UpdateFrameSize(pOMXComponent);
654             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
655
656             /** Send Port Settings changed call back **/
657             (*(pExynosComponent->pCallbacks->EventHandler))
658                 (pOMXComponent,
659                  pExynosComponent->callbackData,
660                  OMX_EventPortSettingsChanged, /* The command was completed */
661                  OMX_DirOutput, /* This is the port index */
662                  0,
663                  NULL);
664         }
665     }
666     Exynos_OSAL_SleepMillisec(0);
667     ret = OMX_ErrorInputDataDecodeYet;
668     Mpeg2CodecStop(pOMXComponent, INPUT_PORT_INDEX);
669
670 EXIT:
671     FunctionOut();
672
673     return ret;
674 }
675
676 OMX_ERRORTYPE Mpeg2CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
677 {
678     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
679     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
680     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
681     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
682     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
683     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
684     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
685
686     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
687     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
688     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
689
690     int i, nOutbufs;
691
692     FunctionIn();
693
694     /* get dpb count */
695     nOutbufs = pMpeg2Dec->hMFCMpeg2Handle.maxDPBNum;
696
697     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
698         /* should be done before prepare output buffer */
699         if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
700             ret = OMX_ErrorInsufficientResources;
701             goto EXIT;
702         }
703     }
704
705     pOutbufOps->Set_Shareable(hMFCHandle);
706     if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
707         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
708         ret = OMX_ErrorInsufficientResources;
709         goto EXIT;
710     }
711
712     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
713     OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
714     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
715     int plane;
716
717     nAllocLen[0] = calc_plane(pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth,
718                         pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight);
719     nAllocLen[1] = calc_plane(pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameWidth,
720                         pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf.nFrameHeight >> 1);
721
722     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
723         /* Register output buffer */
724         for (i = 0; i < nOutbufs; i++) {
725             pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
726             Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
727
728             for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
729                 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] =
730                     (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], NORMAL_MEMORY);
731                 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) {
732                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
733                 ret = OMX_ErrorInsufficientResources;
734                 goto EXIT;
735             }
736                 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] =
737                     Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
738                                                        pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
739                 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane];
740
741                 planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane];
742                 planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane];
743                 planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane];
744             }
745
746             if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
747                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
748                 ret = OMX_ErrorInsufficientResources;
749                 goto EXIT;
750             }
751             pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
752                             (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
753         }
754     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
755         /* Register output buffer */
756         /*************/
757         /*    TBD    */
758         /*************/
759 #ifdef USE_PB
760         if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) {
761             for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
762                 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
763                     planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
764                     planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
765                     planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane];
766                     planes[plane].allocSize = nAllocLen[plane];
767                 }
768
769                 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
770                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
771                     ret = OMX_ErrorInsufficientResources;
772                     goto EXIT;
773                 }
774                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
775                               (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
776             }
777         } else {
778             ret = OMX_ErrorNotImplemented;
779             goto EXIT;
780         }
781 #else
782         ret = OMX_ErrorNotImplemented;
783         goto EXIT;
784 #endif
785     }
786
787     if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
788         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
789         ret = OMX_ErrorInsufficientResources;
790         goto EXIT;
791     }
792
793     if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
794         Mpeg2CodecStop (pOMXComponent, OUTPUT_PORT_INDEX);
795     }
796     pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_TRUE;
797
798     ret = OMX_ErrorNone;
799
800 EXIT:
801     FunctionOut();
802
803     return ret;
804 }
805
806 OMX_ERRORTYPE Exynos_Mpeg2Dec_GetParameter(
807     OMX_IN OMX_HANDLETYPE hComponent,
808     OMX_IN OMX_INDEXTYPE  nParamIndex,
809     OMX_INOUT OMX_PTR     pComponentParameterStructure)
810 {
811     OMX_ERRORTYPE          ret = OMX_ErrorNone;
812     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
813     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
814
815     FunctionIn();
816
817     if (hComponent == NULL || pComponentParameterStructure == NULL) {
818         ret = OMX_ErrorBadParameter;
819         goto EXIT;
820     }
821     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
822     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
823     if (ret != OMX_ErrorNone) {
824         goto EXIT;
825     }
826     if (pOMXComponent->pComponentPrivate == NULL) {
827         ret = OMX_ErrorBadParameter;
828         goto EXIT;
829     }
830
831     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
832     if (pExynosComponent->currentState == OMX_StateInvalid ) {
833         ret = OMX_ErrorInvalidState;
834         goto EXIT;
835     }
836
837     switch (nParamIndex) {
838     case OMX_IndexParamVideoMpeg2:
839     {
840         OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
841         OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = NULL;
842         EXYNOS_MPEG2DEC_HANDLE       *pMpeg2Dec      = NULL;
843         ret = Exynos_OMX_Check_SizeVersion(pDstMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
844         if (ret != OMX_ErrorNone) {
845             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "1");
846             goto EXIT;
847         }
848
849         if (pDstMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
850             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "2");
851             ret = OMX_ErrorBadPortIndex;
852         }
853
854         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
855         pSrcMpeg2Param = &pMpeg2Dec->Mpeg2Component[pDstMpeg2Param->nPortIndex];
856
857         Exynos_OSAL_Memcpy(pDstMpeg2Param, pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
858     }
859         break;
860     case OMX_IndexParamStandardComponentRole:
861     {
862         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
863         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
864         if (ret != OMX_ErrorNone) {
865             goto EXIT;
866         }
867
868         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
869     }
870         break;
871     case OMX_IndexParamVideoProfileLevelCurrent:
872     {
873         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
874         OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Component = NULL;
875         EXYNOS_MPEG2DEC_HANDLE      *pMpeg2Dec = NULL;
876
877         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
878         if (ret != OMX_ErrorNone) {
879             goto EXIT;
880         }
881
882         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
883             ret = OMX_ErrorBadPortIndex;
884             goto EXIT;
885         }
886
887         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
888         pSrcMpeg2Component = &pMpeg2Dec->Mpeg2Component[pDstProfileLevel->nPortIndex];
889
890         pDstProfileLevel->eProfile = pSrcMpeg2Component->eProfile;
891         pDstProfileLevel->eLevel = pSrcMpeg2Component->eLevel;
892     }
893         break;
894     case OMX_IndexParamVideoErrorCorrection:
895     {
896         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
897         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
898         EXYNOS_MPEG2DEC_HANDLE                *pMpeg2Dec                 = NULL;
899
900         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
901         if (ret != OMX_ErrorNone) {
902             goto EXIT;
903         }
904
905         if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
906             ret = OMX_ErrorBadPortIndex;
907             goto EXIT;
908         }
909
910         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
911         pSrcErrorCorrectionType = &pMpeg2Dec->errorCorrectionType[INPUT_PORT_INDEX];
912
913         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
914         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
915         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
916         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
917         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
918     }
919         break;
920     default:
921         ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
922         break;
923     }
924 EXIT:
925     FunctionOut();
926
927     return ret;
928 }
929
930 OMX_ERRORTYPE Exynos_Mpeg2Dec_SetParameter(
931     OMX_IN OMX_HANDLETYPE hComponent,
932     OMX_IN OMX_INDEXTYPE  nIndex,
933     OMX_IN OMX_PTR        pComponentParameterStructure)
934 {
935     OMX_ERRORTYPE           ret = OMX_ErrorNone;
936     OMX_COMPONENTTYPE     *pOMXComponent = NULL;
937     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
938
939     FunctionIn();
940
941     if (hComponent == NULL || pComponentParameterStructure == NULL) {
942         ret = OMX_ErrorBadParameter;
943         goto EXIT;
944     }
945     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
946     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
947     if (ret != OMX_ErrorNone) {
948         goto EXIT;
949     }
950     if (pOMXComponent->pComponentPrivate == NULL) {
951         ret = OMX_ErrorBadParameter;
952         goto EXIT;
953     }
954
955     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
956     if (pExynosComponent->currentState == OMX_StateInvalid ) {
957         ret = OMX_ErrorInvalidState;
958         goto EXIT;
959     }
960
961     switch (nIndex) {
962     case OMX_IndexParamVideoMpeg2:
963     {
964         OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Param = NULL;
965         OMX_VIDEO_PARAM_MPEG2TYPE *pSrcMpeg2Param = (OMX_VIDEO_PARAM_MPEG2TYPE *)pComponentParameterStructure;
966         EXYNOS_MPEG2DEC_HANDLE       *pMpeg2Dec      = NULL;
967         ret = Exynos_OMX_Check_SizeVersion(pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
968         if (ret != OMX_ErrorNone) {
969             goto EXIT;
970         }
971
972         if (pSrcMpeg2Param->nPortIndex > OUTPUT_PORT_INDEX) {
973             ret = OMX_ErrorBadPortIndex;
974             goto EXIT;
975         }
976
977         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
978         pDstMpeg2Param = &pMpeg2Dec->Mpeg2Component[pSrcMpeg2Param->nPortIndex];
979
980         Exynos_OSAL_Memcpy(pDstMpeg2Param, pSrcMpeg2Param, sizeof(OMX_VIDEO_PARAM_MPEG2TYPE));
981     }
982         break;
983     case OMX_IndexParamStandardComponentRole:
984     {
985         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
986
987         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
988         if (ret != OMX_ErrorNone) {
989             goto EXIT;
990         }
991
992         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
993             ret = OMX_ErrorIncorrectStateOperation;
994             goto EXIT;
995         }
996
997         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE)) {
998             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
999         } else {
1000             ret = OMX_ErrorBadParameter;
1001             goto EXIT;
1002         }
1003     }
1004         break;
1005     case OMX_IndexParamPortDefinition:
1006     {
1007         OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1008         OMX_U32                       portIndex       = pPortDefinition->nPortIndex;
1009         EXYNOS_OMX_BASEPORT          *pExynosPort;
1010         OMX_U32                       width, height, size;
1011         OMX_U32                       realWidth, realHeight;
1012
1013         if (portIndex >= pExynosComponent->portParam.nPorts) {
1014             ret = OMX_ErrorBadPortIndex;
1015             goto EXIT;
1016         }
1017         ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1018         if (ret != OMX_ErrorNone) {
1019             goto EXIT;
1020         }
1021
1022         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1023
1024         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1025             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1026                 ret = OMX_ErrorIncorrectStateOperation;
1027                 goto EXIT;
1028             }
1029         }
1030         if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1031             ret = OMX_ErrorBadParameter;
1032             goto EXIT;
1033         }
1034
1035         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1036
1037         realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1038         realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1039         width = ((realWidth + 15) & (~15));
1040         height = ((realHeight + 15) & (~15));
1041         size = (width * height * 3) / 2;
1042         pExynosPort->portDefinition.format.video.nStride = width;
1043         pExynosPort->portDefinition.format.video.nSliceHeight = height;
1044         pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
1045
1046         if (portIndex == INPUT_PORT_INDEX) {
1047             EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1048             pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1049             pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1050             pExynosOutputPort->portDefinition.format.video.nStride = width;
1051             pExynosOutputPort->portDefinition.format.video.nSliceHeight = height;
1052
1053             switch (pExynosOutputPort->portDefinition.format.video.eColorFormat) {
1054             case OMX_COLOR_FormatYUV420Planar:
1055             case OMX_COLOR_FormatYUV420SemiPlanar:
1056 //            case OMX_SEC_COLOR_FormatNV12TPhysicalAddress:
1057             //case OMX_SEC_COLOR_FormatANBYUV420SemiPlanar:
1058                 pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
1059                 break;
1060             case OMX_SEC_COLOR_FormatNV12Tiled:
1061                 pExynosOutputPort->portDefinition.nBufferSize =
1062                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1063                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1064                 break;
1065             default:
1066                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
1067                 ret = OMX_ErrorUnsupportedSetting;
1068                 break;
1069             }
1070
1071             if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1072                 pExynosOutputPort->portDefinition.nBufferSize =
1073                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1074                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1075             }
1076         }
1077     }
1078         break;
1079     case OMX_IndexParamVideoProfileLevelCurrent:
1080     {
1081         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1082         OMX_VIDEO_PARAM_MPEG2TYPE *pDstMpeg2Component = NULL;
1083         EXYNOS_MPEG2DEC_HANDLE      *pMpeg2Dec = NULL;
1084
1085         ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1086         if (ret != OMX_ErrorNone)
1087             goto EXIT;
1088
1089         if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1090             ret = OMX_ErrorBadPortIndex;
1091             goto EXIT;
1092         }
1093
1094         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1095
1096         pDstMpeg2Component = &pMpeg2Dec->Mpeg2Component[pSrcProfileLevel->nPortIndex];
1097         pDstMpeg2Component->eProfile = pSrcProfileLevel->eProfile;
1098         pDstMpeg2Component->eLevel = pSrcProfileLevel->eLevel;
1099     }
1100         break;
1101     case OMX_IndexParamVideoErrorCorrection:
1102     {
1103         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1104         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1105         EXYNOS_MPEG2DEC_HANDLE                *pMpeg2Dec                 = NULL;
1106
1107         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1108         if (ret != OMX_ErrorNone) {
1109             goto EXIT;
1110         }
1111
1112         if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1113             ret = OMX_ErrorBadPortIndex;
1114             goto EXIT;
1115         }
1116
1117         pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1118         pDstErrorCorrectionType = &pMpeg2Dec->errorCorrectionType[INPUT_PORT_INDEX];
1119
1120         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1121         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1122         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1123         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1124         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1125     }
1126         break;
1127     default:
1128         ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1129         break;
1130     }
1131 EXIT:
1132     FunctionOut();
1133
1134     return ret;
1135 }
1136
1137 OMX_ERRORTYPE Exynos_Mpeg2Dec_GetConfig(
1138     OMX_HANDLETYPE hComponent,
1139     OMX_INDEXTYPE  nIndex,
1140     OMX_PTR        pComponentConfigStructure)
1141 {
1142     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1143     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1144     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1145
1146     FunctionIn();
1147
1148     if (hComponent == NULL) {
1149         ret = OMX_ErrorBadParameter;
1150         goto EXIT;
1151     }
1152     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1153     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1154     if (ret != OMX_ErrorNone) {
1155         goto EXIT;
1156     }
1157     if (pOMXComponent->pComponentPrivate == NULL) {
1158         ret = OMX_ErrorBadParameter;
1159         goto EXIT;
1160     }
1161     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1162     if (pExynosComponent->currentState == OMX_StateInvalid) {
1163         ret = OMX_ErrorInvalidState;
1164         goto EXIT;
1165     }
1166
1167     switch (nIndex) {
1168     default:
1169         ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1170         break;
1171     }
1172
1173 EXIT:
1174     FunctionOut();
1175
1176     return ret;
1177 }
1178
1179 OMX_ERRORTYPE Exynos_Mpeg2Dec_SetConfig(
1180     OMX_HANDLETYPE hComponent,
1181     OMX_INDEXTYPE  nIndex,
1182     OMX_PTR        pComponentConfigStructure)
1183 {
1184     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1185     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1186     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1187
1188     FunctionIn();
1189
1190     if (hComponent == NULL) {
1191         ret = OMX_ErrorBadParameter;
1192         goto EXIT;
1193     }
1194     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1195     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1196     if (ret != OMX_ErrorNone) {
1197         goto EXIT;
1198     }
1199     if (pOMXComponent->pComponentPrivate == NULL) {
1200         ret = OMX_ErrorBadParameter;
1201         goto EXIT;
1202     }
1203     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1204     if (pExynosComponent->currentState == OMX_StateInvalid) {
1205         ret = OMX_ErrorInvalidState;
1206         goto EXIT;
1207     }
1208
1209     switch (nIndex) {
1210     default:
1211         ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1212         break;
1213     }
1214
1215 EXIT:
1216     FunctionOut();
1217
1218     return ret;
1219 }
1220
1221 OMX_ERRORTYPE Exynos_Mpeg2Dec_GetExtensionIndex(
1222     OMX_IN  OMX_HANDLETYPE  hComponent,
1223     OMX_IN  OMX_STRING      cParameterName,
1224     OMX_OUT OMX_INDEXTYPE   *pIndexType)
1225 {
1226     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1227     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1228     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1229
1230     FunctionIn();
1231
1232     if (hComponent == NULL) {
1233         ret = OMX_ErrorBadParameter;
1234         goto EXIT;
1235     }
1236     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1237     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1238     if (ret != OMX_ErrorNone) {
1239         goto EXIT;
1240     }
1241     if (pOMXComponent->pComponentPrivate == NULL) {
1242         ret = OMX_ErrorBadParameter;
1243         goto EXIT;
1244     }
1245     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1246     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1247         ret = OMX_ErrorBadParameter;
1248         goto EXIT;
1249     }
1250     if (pExynosComponent->currentState == OMX_StateInvalid) {
1251         ret = OMX_ErrorInvalidState;
1252         goto EXIT;
1253     }
1254
1255     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1256         EXYNOS_MPEG2DEC_HANDLE *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1257         *pIndexType = OMX_IndexVendorThumbnailMode;
1258         ret = OMX_ErrorNone;
1259     } else {
1260         ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1261     }
1262
1263 EXIT:
1264     FunctionOut();
1265
1266     return ret;
1267 }
1268
1269 OMX_ERRORTYPE Exynos_Mpeg2Dec_ComponentRoleEnum(
1270     OMX_HANDLETYPE hComponent,
1271     OMX_U8        *cRole,
1272     OMX_U32        nIndex)
1273 {
1274     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1275     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1276     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1277
1278     FunctionIn();
1279
1280     if ((hComponent == NULL) || (cRole == NULL)) {
1281         ret = OMX_ErrorBadParameter;
1282         goto EXIT;
1283     }
1284     if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1285         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_MPEG2_DEC_ROLE);
1286         ret = OMX_ErrorNone;
1287     } else {
1288         ret = OMX_ErrorNoMore;
1289     }
1290
1291 EXIT:
1292     FunctionOut();
1293
1294     return ret;
1295 }
1296
1297 /* MFC Init */
1298 OMX_ERRORTYPE Exynos_Mpeg2Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1299 {
1300     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1301     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1302     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1303     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1304     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1305     EXYNOS_MPEG2DEC_HANDLE          *pMpeg2Dec           = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
1306     OMX_PTR                hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1307
1308     ExynosVideoDecOps       *pDecOps    = NULL;
1309     ExynosVideoDecBufferOps *pInbufOps  = NULL;
1310     ExynosVideoDecBufferOps *pOutbufOps = NULL;
1311
1312     CSC_METHOD csc_method = CSC_METHOD_SW;
1313     int i, plane;
1314
1315     FunctionIn();
1316
1317     pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc = OMX_FALSE;
1318     pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst = OMX_FALSE;
1319     pExynosComponent->bUseFlagEOF = OMX_TRUE;
1320     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1321
1322     /* Mpeg2 Codec Open */
1323     ret = Mpeg2CodecOpen(pMpeg2Dec);
1324     if (ret != OMX_ErrorNone) {
1325         goto EXIT;
1326     }
1327
1328     pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1329     pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
1330     pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
1331
1332     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1333         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1334         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1335
1336         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1337             pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1338             Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1339             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
1340
1341             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1342             /* Use ION Allocator */
1343                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
1344                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1345                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1346             pVideoDec->pMFCDecInputBuffer[i]->dataSize   = 0;
1347                 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
1348                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1349                 ret = OMX_ErrorInsufficientResources;
1350                 goto EXIT;
1351             }
1352                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1353             }
1354
1355             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1356         }
1357     } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1358         /*************/
1359         /*    TBD    */
1360         /*************/
1361         /* Does not require any actions. */
1362     }
1363
1364     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1365         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1366         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1367     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1368         /*************/
1369         /*    TBD    */
1370         /*************/
1371         /* Does not require any actions. */
1372     }
1373
1374     pMpeg2Dec->bSourceStart = OMX_FALSE;
1375     Exynos_OSAL_SignalCreate(&pMpeg2Dec->hSourceStartEvent);
1376     pMpeg2Dec->bDestinationStart = OMX_FALSE;
1377     Exynos_OSAL_SignalCreate(&pMpeg2Dec->hDestinationStartEvent);
1378
1379     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1380     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1381     pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp = 0;
1382     pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = 0;
1383
1384     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1385
1386 #if 0//defined(USE_CSC_GSCALER)
1387     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1388 #endif
1389     pVideoDec->csc_handle = csc_init(csc_method);
1390     if (pVideoDec->csc_handle == NULL) {
1391         ret = OMX_ErrorInsufficientResources;
1392         goto EXIT;
1393     }
1394     pVideoDec->csc_set_format = OMX_FALSE;
1395
1396 EXIT:
1397     FunctionOut();
1398
1399     return ret;
1400 }
1401
1402 /* MFC Terminate */
1403 OMX_ERRORTYPE Exynos_Mpeg2Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1404 {
1405     OMX_ERRORTYPE          ret = OMX_ErrorNone;
1406     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1407     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1408     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1409     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1410     EXYNOS_MPEG2DEC_HANDLE    *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1411     OMX_PTR                hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1412
1413     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1414     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
1415     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
1416
1417     int i, plane;
1418
1419     FunctionIn();
1420
1421     if (pVideoDec->csc_handle != NULL) {
1422         csc_deinit(pVideoDec->csc_handle);
1423         pVideoDec->csc_handle = NULL;
1424     }
1425
1426     Exynos_OSAL_SignalTerminate(pMpeg2Dec->hDestinationStartEvent);
1427     pMpeg2Dec->hDestinationStartEvent = NULL;
1428     pMpeg2Dec->bDestinationStart = OMX_FALSE;
1429     Exynos_OSAL_SignalTerminate(pMpeg2Dec->hSourceStartEvent);
1430     pMpeg2Dec->hSourceStartEvent = NULL;
1431     pMpeg2Dec->bSourceStart = OMX_FALSE;
1432
1433     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1434         for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1435             if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
1436 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1437                 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1438                     if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL)
1439                         Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
1440                 }
1441 #endif
1442                 Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
1443                 pVideoDec->pMFCDecOutputBuffer[i] = NULL;
1444             }
1445         }
1446
1447         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1448         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1449     } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1450         /*************/
1451         /*    TBD    */
1452         /*************/
1453         /* Does not require any actions. */
1454     }
1455
1456     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1457         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1458             if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
1459 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1460                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1461                     if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
1462                         Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1463                 }
1464 #endif
1465             Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
1466             pVideoDec->pMFCDecInputBuffer[i] = NULL;
1467         }
1468         }
1469
1470         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1471         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1472     } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1473         /*************/
1474         /*    TBD    */
1475         /*************/
1476         /* Does not require any actions. */
1477     }
1478     Mpeg2CodecClose(pMpeg2Dec);
1479
1480 EXIT:
1481     FunctionOut();
1482
1483     return ret;
1484 }
1485
1486 OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1487 {
1488     OMX_ERRORTYPE               ret = OMX_ErrorNone;
1489     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1490     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1491     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1492     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1493     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1494     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1495     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
1496     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1497     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
1498     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
1499     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1500     int i;
1501
1502     FunctionIn();
1503
1504     if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCSrc == OMX_FALSE) {
1505         ret = Mpeg2CodecSrcSetup(pOMXComponent, pSrcInputData);
1506         goto EXIT;
1507     }
1508     if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_FALSE) {
1509         ret = Mpeg2CodecDstSetup(pOMXComponent);
1510     }
1511
1512     if ((Check_Mpeg2_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize) == OMX_TRUE) ||
1513         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)){
1514         pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->timeStamp;
1515         pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp] = pSrcInputData->nFlags;
1516         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp, pSrcInputData->nFlags);
1517         pDecOps->Set_FrameTag(hMFCHandle, pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp);
1518         pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp++;
1519         pMpeg2Dec->hMFCMpeg2Handle.indexTimestamp %= MAX_TIMESTAMP;
1520
1521         /* queue work for input buffer */
1522         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1523         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1524                                     (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1525         if (codecReturn != VIDEO_ERROR_NONE) {
1526             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1527             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1528             goto EXIT;
1529         }
1530         Mpeg2CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1531         if (pMpeg2Dec->bSourceStart == OMX_FALSE) {
1532             pMpeg2Dec->bSourceStart = OMX_TRUE;
1533             Exynos_OSAL_SignalSet(pMpeg2Dec->hSourceStartEvent);
1534             Exynos_OSAL_SleepMillisec(0);
1535         }
1536         if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
1537             pMpeg2Dec->bDestinationStart = OMX_TRUE;
1538             Exynos_OSAL_SignalSet(pMpeg2Dec->hDestinationStartEvent);
1539             Exynos_OSAL_SleepMillisec(0);
1540         }
1541     }
1542
1543     ret = OMX_ErrorNone;
1544
1545 EXIT:
1546     FunctionOut();
1547
1548     return ret;
1549 }
1550
1551 OMX_ERRORTYPE Exynos_Mpeg2Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1552 {
1553     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1554     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1555     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1556     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1557     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1558     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1559     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1560     ExynosVideoDecBufferOps *pInbufOps  = pMpeg2Dec->hMFCMpeg2Handle.pInbufOps;
1561     ExynosVideoBuffer       *pVideoBuffer;
1562
1563     FunctionIn();
1564
1565     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1566
1567     pSrcOutputData->dataLen       = 0;
1568     pSrcOutputData->usedDataLen   = 0;
1569     pSrcOutputData->remainDataLen = 0;
1570     pSrcOutputData->nFlags    = 0;
1571     pSrcOutputData->timeStamp = 0;
1572
1573     if (pVideoBuffer == NULL) {
1574         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1575         pSrcOutputData->allocSize  = 0;
1576         pSrcOutputData->pPrivate = NULL;
1577         pSrcOutputData->bufferHeader = NULL;
1578     } else {
1579         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1580         pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1581         pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
1582
1583         if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1584             int i = 0;
1585             while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1586                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1587                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1588                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1589                     goto EXIT;
1590                 }
1591                 i++;
1592             }
1593             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1594             pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1595         }
1596
1597         /* For Share Buffer */
1598         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1599     }
1600
1601     ret = OMX_ErrorNone;
1602
1603 EXIT:
1604     FunctionOut();
1605
1606     return ret;
1607 }
1608
1609 OMX_ERRORTYPE Exynos_Mpeg2Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1610 {
1611     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1612     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1613     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1614     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1615     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1616     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1617     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1618     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
1619     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
1620     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1621
1622     FunctionIn();
1623
1624     if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1625         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1626         ret = OMX_ErrorBadParameter;
1627         goto EXIT;
1628     }
1629
1630     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
1631                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
1632                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
1633
1634     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1635                      (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
1636
1637     if (codecReturn != VIDEO_ERROR_NONE) {
1638         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1639         ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1640         goto EXIT;
1641     }
1642     Mpeg2CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1643
1644     ret = OMX_ErrorNone;
1645
1646 EXIT:
1647     FunctionOut();
1648
1649     return ret;
1650 }
1651
1652 OMX_ERRORTYPE Exynos_Mpeg2Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1653 {
1654     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1655     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1656     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1657     EXYNOS_MPEG2DEC_HANDLE         *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1658     void                          *hMFCHandle = pMpeg2Dec->hMFCMpeg2Handle.hMFCHandle;
1659     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1660     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1661     ExynosVideoDecOps       *pDecOps    = pMpeg2Dec->hMFCMpeg2Handle.pDecOps;
1662     ExynosVideoDecBufferOps *pOutbufOps = pMpeg2Dec->hMFCMpeg2Handle.pOutbufOps;
1663     ExynosVideoBuffer       *pVideoBuffer;
1664     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1665     ExynosVideoGeometry *bufferGeometry;
1666     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1667     OMX_S32 indexTimestamp = 0;
1668     int plane;
1669
1670     FunctionIn();
1671
1672     if (pMpeg2Dec->bDestinationStart == OMX_FALSE) {
1673         ret = OMX_ErrorNone;
1674         goto EXIT;
1675     }
1676
1677     while (1) {
1678         if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1679             ret = OMX_ErrorNone;
1680             goto EXIT;
1681         }
1682         displayStatus = pVideoBuffer->displayStatus;
1683         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1684
1685         if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1686             (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1687             (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1688             (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1689             if (pVideoBuffer != NULL) {
1690                 ret = OMX_ErrorNone;
1691                 break;
1692             } else {
1693                 ret = OMX_ErrorUndefined;
1694                 break;
1695             }
1696         }
1697     }
1698
1699     if (ret != OMX_ErrorNone)
1700         goto EXIT;
1701
1702     pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp++;
1703     pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1704
1705     pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
1706     for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1707         pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1708         pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1709         pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo;
1710         pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1711         pDstOutputData->dataLen +=  pVideoBuffer->planes[plane].dataSize;
1712     }
1713     pDstOutputData->usedDataLen = 0;
1714     pDstOutputData->pPrivate = pVideoBuffer;
1715     /* For Share Buffer */
1716     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1717
1718     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1719     bufferGeometry = &pMpeg2Dec->hMFCMpeg2Handle.codecOutbufConf;
1720     pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1721     pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1722     switch (bufferGeometry->eColorFormat) {
1723     case VIDEO_COLORFORMAT_NV12:
1724         pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1725         break;
1726     case VIDEO_COLORFORMAT_NV12_TILED:
1727     default:
1728         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1729         break;
1730     }
1731
1732     indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
1733     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
1734     if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1735         if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
1736             (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
1737             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
1738             pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
1739             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
1740         } else {
1741             pDstOutputData->timeStamp = 0x00;
1742             pDstOutputData->nFlags = 0x00;
1743         }
1744     } else {
1745         /* For timestamp correction. if mfc support frametype detect */
1746         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
1747 //#ifdef NEED_TIMESTAMP_REORDER
1748         /* TIZEN_FEATURE_E3250 */
1749         if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) {
1750             if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
1751                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1752                 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1753                 pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp = indexTimestamp;
1754             } else {
1755                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
1756                 pDstOutputData->nFlags = pExynosComponent->nFlags[pMpeg2Dec->hMFCMpeg2Handle.outputIndexTimestamp];
1757             }
1758 //#else
1759         } else {
1760             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1761             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1762         }
1763 //#endif
1764         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
1765     }
1766
1767     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1768         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1769         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
1770         pDstOutputData->remainDataLen = 0;
1771     } else {
1772         pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
1773     }
1774
1775     ret = OMX_ErrorNone;
1776
1777 EXIT:
1778     FunctionOut();
1779
1780     return ret;
1781 }
1782
1783 OMX_ERRORTYPE Exynos_Mpeg2Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1784 {
1785     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1786     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1787     EXYNOS_MPEG2DEC_HANDLE    *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1788     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1789
1790     FunctionIn();
1791
1792     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1793         ret = OMX_ErrorNone;
1794         goto EXIT;
1795     }
1796     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1797         ret = OMX_ErrorNone;
1798         goto EXIT;
1799     }
1800
1801     ret = Exynos_Mpeg2Dec_SrcIn(pOMXComponent, pSrcInputData);
1802     if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
1803         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1804                                                 pExynosComponent->callbackData,
1805                                                 OMX_EventError, ret, 0, NULL);
1806     }
1807
1808 EXIT:
1809     FunctionOut();
1810
1811     return ret;
1812 }
1813
1814 OMX_ERRORTYPE Exynos_Mpeg2Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1815 {
1816     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1817     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1818     EXYNOS_MPEG2DEC_HANDLE    *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1819     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1820
1821     FunctionIn();
1822
1823     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1824         ret = OMX_ErrorNone;
1825         goto EXIT;
1826     }
1827
1828     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1829         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1830             ret = OMX_ErrorNone;
1831             goto EXIT;
1832         }
1833     }
1834     if ((pMpeg2Dec->bSourceStart == OMX_FALSE) &&
1835        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
1836         Exynos_OSAL_SignalWait(pMpeg2Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
1837         Exynos_OSAL_SignalReset(pMpeg2Dec->hSourceStartEvent);
1838     }
1839
1840     ret = Exynos_Mpeg2Dec_SrcOut(pOMXComponent, pSrcOutputData);
1841     if ((ret != OMX_ErrorNone) &&
1842         (pExynosComponent->currentState == OMX_StateExecuting)) {
1843         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1844                                                 pExynosComponent->callbackData,
1845                                                 OMX_EventError, ret, 0, NULL);
1846     }
1847
1848 EXIT:
1849     FunctionOut();
1850
1851     return ret;
1852 }
1853
1854 OMX_ERRORTYPE Exynos_Mpeg2Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1855 {
1856     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1857     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1858     EXYNOS_MPEG2DEC_HANDLE    *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1859     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1860
1861     FunctionIn();
1862
1863     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1864         ret = OMX_ErrorNone;
1865         goto EXIT;
1866     }
1867     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1868         ret = OMX_ErrorNone;
1869         goto EXIT;
1870     }
1871     if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1872         if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
1873            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1874             Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1875             Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent);
1876         }
1877     }
1878     if (pMpeg2Dec->hMFCMpeg2Handle.bConfiguredMFCDst == OMX_TRUE) {
1879         ret = Exynos_Mpeg2Dec_DstIn(pOMXComponent, pDstInputData);
1880         if (ret != OMX_ErrorNone) {
1881             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1882                                                 pExynosComponent->callbackData,
1883                                                 OMX_EventError, ret, 0, NULL);
1884         }
1885     }
1886
1887 EXIT:
1888     FunctionOut();
1889
1890     return ret;
1891 }
1892
1893 OMX_ERRORTYPE Exynos_Mpeg2Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1894 {
1895     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1896     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1897     EXYNOS_MPEG2DEC_HANDLE    *pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1898     EXYNOS_OMX_BASEPORT     *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1899
1900     FunctionIn();
1901
1902     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1903         ret = OMX_ErrorNone;
1904         goto EXIT;
1905     }
1906     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
1907         ret = OMX_ErrorNone;
1908         goto EXIT;
1909     }
1910
1911     if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1912         if ((pMpeg2Dec->bDestinationStart == OMX_FALSE) &&
1913            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1914             Exynos_OSAL_SignalWait(pMpeg2Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
1915             Exynos_OSAL_SignalReset(pMpeg2Dec->hDestinationStartEvent);
1916         }
1917     }
1918     ret = Exynos_Mpeg2Dec_DstOut(pOMXComponent, pDstOutputData);
1919     if ((ret != OMX_ErrorNone) &&
1920         (pExynosComponent->currentState == OMX_StateExecuting)) {
1921         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1922                                                 pExynosComponent->callbackData,
1923                                                 OMX_EventError, ret, 0, NULL);
1924     }
1925
1926 EXIT:
1927     FunctionOut();
1928
1929     return ret;
1930 }
1931
1932 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
1933     OMX_HANDLETYPE  hComponent,
1934     OMX_STRING      componentName)
1935 {
1936     OMX_ERRORTYPE                    ret                = OMX_ErrorNone;
1937     OMX_COMPONENTTYPE               *pOMXComponent      = NULL;
1938     EXYNOS_OMX_BASECOMPONENT        *pExynosComponent   = NULL;
1939     EXYNOS_OMX_BASEPORT             *pExynosPort        = NULL;
1940     EXYNOS_OMX_VIDEODEC_COMPONENT   *pVideoDec          = NULL;
1941     EXYNOS_MPEG2DEC_HANDLE            *pMpeg2Dec            = NULL;
1942     int i = 0;
1943
1944     FunctionIn();
1945
1946     if ((hComponent == NULL) || (componentName == NULL)) {
1947         ret = OMX_ErrorBadParameter;
1948         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
1949         goto EXIT;
1950     }
1951     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_MPEG2_DEC, componentName) != 0) {
1952         ret = OMX_ErrorBadParameter;
1953         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
1954         goto EXIT;
1955     }
1956
1957     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1958     ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
1959     if (ret != OMX_ErrorNone) {
1960         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
1961         goto EXIT;
1962     }
1963     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1964     pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
1965
1966     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
1967     if (pExynosComponent->componentName == NULL) {
1968         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1969         ret = OMX_ErrorInsufficientResources;
1970         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1971         goto EXIT;
1972     }
1973     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
1974
1975     pMpeg2Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_MPEG2DEC_HANDLE));
1976     if (pMpeg2Dec == NULL) {
1977         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
1978         ret = OMX_ErrorInsufficientResources;
1979         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
1980         goto EXIT;
1981     }
1982     Exynos_OSAL_Memset(pMpeg2Dec, 0, sizeof(EXYNOS_MPEG2DEC_HANDLE));
1983     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1984     pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pMpeg2Dec;
1985
1986     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_MPEG2_DEC);
1987
1988     /* Set componentVersion */
1989     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
1990     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
1991     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
1992     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
1993     /* Set specVersion */
1994     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
1995     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
1996     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
1997     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
1998
1999     /* Input port */
2000     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2001     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2002     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2003     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2004     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2005     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2006     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2;
2007     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2008     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/mpeg2");
2009     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2010     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2011     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2012     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2013     //pExynosPort->bufferProcessType = BUFFER_SHARE;
2014     pExynosPort->bufferProcessType = BUFFER_COPY;
2015     pExynosPort->portWayType = WAY2_PORT;
2016
2017     /* Output port */
2018     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2019     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2020     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2021     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2022     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2023     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2024     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2025     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2026     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2027     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2028     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2029     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2030     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2031 #ifdef TIZEN_FEATURE_E3250
2032     pExynosPort->bufferProcessType = BUFFER_SHARE;
2033 #else
2034     pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_PBSHARE;
2035 #endif
2036     pExynosPort->portWayType = WAY2_PORT;
2037
2038     for(i = 0; i < ALL_PORT_NUM; i++) {
2039         INIT_SET_SIZE_VERSION(&pMpeg2Dec->Mpeg2Component[i], OMX_VIDEO_PARAM_MPEG2TYPE);
2040         pMpeg2Dec->Mpeg2Component[i].nPortIndex = i;
2041         pMpeg2Dec->Mpeg2Component[i].eProfile = OMX_VIDEO_MPEG2ProfileMain;
2042         pMpeg2Dec->Mpeg2Component[i].eLevel = OMX_VIDEO_MPEG2LevelML; /* Check again**** */
2043     }
2044
2045     pOMXComponent->GetParameter      = &Exynos_Mpeg2Dec_GetParameter;
2046     pOMXComponent->SetParameter      = &Exynos_Mpeg2Dec_SetParameter;
2047     pOMXComponent->GetConfig         = &Exynos_Mpeg2Dec_GetConfig;
2048     pOMXComponent->SetConfig         = &Exynos_Mpeg2Dec_SetConfig;
2049     pOMXComponent->GetExtensionIndex = &Exynos_Mpeg2Dec_GetExtensionIndex;
2050     pOMXComponent->ComponentRoleEnum = &Exynos_Mpeg2Dec_ComponentRoleEnum;
2051     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2052
2053     pExynosComponent->exynos_codec_componentInit      = &Exynos_Mpeg2Dec_Init;
2054     pExynosComponent->exynos_codec_componentTerminate = &Exynos_Mpeg2Dec_Terminate;
2055
2056     pVideoDec->exynos_codec_srcInputProcess  = &Exynos_Mpeg2Dec_srcInputBufferProcess;
2057     pVideoDec->exynos_codec_srcOutputProcess = &Exynos_Mpeg2Dec_srcOutputBufferProcess;
2058     pVideoDec->exynos_codec_dstInputProcess  = &Exynos_Mpeg2Dec_dstInputBufferProcess;
2059     pVideoDec->exynos_codec_dstOutputProcess = &Exynos_Mpeg2Dec_dstOutputBufferProcess;
2060
2061     pVideoDec->exynos_codec_start         = &Mpeg2CodecStart;
2062     pVideoDec->exynos_codec_stop          = &Mpeg2CodecStop;
2063     pVideoDec->exynos_codec_bufferProcessRun = &Mpeg2CodecOutputBufferProcessRun;
2064     pVideoDec->exynos_codec_enqueueAllBuffer = &Mpeg2CodecEnQueueAllBuffer;
2065
2066     pVideoDec->exynos_checkInputFrame                 = &Check_Mpeg2_Frame;
2067     pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2068     pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2069
2070 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2071     pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2072     if (pVideoDec->hSharedMemory == NULL) {
2073         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2074         Exynos_OSAL_Free(pMpeg2Dec);
2075         pMpeg2Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2076         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2077         ret = OMX_ErrorInsufficientResources;
2078         goto EXIT;
2079     }
2080 #endif
2081     pExynosComponent->currentState = OMX_StateLoaded;
2082
2083     ret = OMX_ErrorNone;
2084
2085 EXIT:
2086     FunctionOut();
2087
2088     return ret;
2089 }
2090
2091 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(
2092     OMX_HANDLETYPE hComponent)
2093 {
2094     OMX_ERRORTYPE                ret                = OMX_ErrorNone;
2095     OMX_COMPONENTTYPE           *pOMXComponent      = NULL;
2096     EXYNOS_OMX_BASECOMPONENT    *pExynosComponent   = NULL;
2097     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
2098     EXYNOS_MPEG2DEC_HANDLE        *pMpeg2Dec            = NULL;
2099
2100     FunctionIn();
2101
2102     if (hComponent == NULL) {
2103         ret = OMX_ErrorBadParameter;
2104         goto EXIT;
2105     }
2106     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2107     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2108     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2109 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2110     Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2111 #endif
2112     Exynos_OSAL_Free(pExynosComponent->componentName);
2113     pExynosComponent->componentName = NULL;
2114
2115     pMpeg2Dec = (EXYNOS_MPEG2DEC_HANDLE *)pVideoDec->hCodecHandle;
2116     if (pMpeg2Dec != NULL) {
2117         Exynos_OSAL_Free(pMpeg2Dec);
2118         pMpeg2Dec = pVideoDec->hCodecHandle = NULL;
2119     }
2120
2121     ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2122     if (ret != OMX_ErrorNone) {
2123         goto EXIT;
2124     }
2125
2126     ret = OMX_ErrorNone;
2127
2128 EXIT:
2129     FunctionOut();
2130
2131     return ret;
2132 }