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