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