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