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]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
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]->pVirAddr[0];
663            plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
664            plane.fd = pVideoDec->pMFCDecInputBuffer[i]->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            if (pVideoDec->bDRMPlayerMode == OMX_FALSE) {
676                plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
677            } else {
678                plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory,
679                                               pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
680            }
681            plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
682            plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
683            if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
684                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
685                ret = OMX_ErrorInsufficientResources;
686                goto EXIT;
687            }
688        }
689    }
690
691    /* set output geometry */
692    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
693    pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12_TILED;
694    if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
695        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
696        ret = OMX_ErrorInsufficientResources;
697        goto EXIT;
698    }
699
700    /* input buffer enqueue for header parsing */
701    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
702    if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
703                        (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
704        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
705//        ret = OMX_ErrorInsufficientResources;
706        ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
707        goto EXIT;
708    }
709
710    /* start header parsing */
711    if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
712        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
713        ret = OMX_ErrorCodecInit;
714        goto EXIT;
715    }
716
717    /* get geometry for output */
718    Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
719    if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
720        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
721        ret = OMX_ErrorInsufficientResources;
722        goto EXIT;
723    }
724
725    /* get dpb count */
726    pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
727    if (pVideoDec->bThumbnailMode == OMX_FALSE)
728        pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
729    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "H264CodecSetup nOutbufs: %d", pH264Dec->hMFCH264Handle.maxDPBNum);
730
731    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
732
733    pExynosOutputPort->cropRectangle.nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
734    pExynosOutputPort->cropRectangle.nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
735    pExynosOutputPort->cropRectangle.nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
736    pExynosOutputPort->cropRectangle.nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
737
738    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
739        if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
740            (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
741            pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
742            pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
743            pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
744            pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
745
746            Exynos_UpdateFrameSize(pOMXComponent);
747            pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
748
749            /** Send Port Settings changed call back **/
750            (*(pExynosComponent->pCallbacks->EventHandler))
751                (pOMXComponent,
752                 pExynosComponent->callbackData,
753                 OMX_EventPortSettingsChanged, /* The command was completed */
754                 OMX_DirOutput, /* This is the port index */
755                 0,
756                 NULL);
757        }
758    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
759        if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
760            (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
761            (pExynosOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
762            pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
763            pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
764            pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
765            pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
766
767            pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
768            pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum - 2;
769
770            Exynos_UpdateFrameSize(pOMXComponent);
771            pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
772
773            /** Send Port Settings changed call back **/
774            (*(pExynosComponent->pCallbacks->EventHandler))
775                (pOMXComponent,
776                 pExynosComponent->callbackData,
777                 OMX_EventPortSettingsChanged, /* The command was completed */
778                 OMX_DirOutput, /* This is the port index */
779                 0,
780                 NULL);
781        }
782    }
783    if ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
784        (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
785        /* Check Crop */
786        pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
787        pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
788        pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
789        pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
790        Exynos_UpdateFrameSize(pOMXComponent);
791
792        /** Send crop info call back **/
793        (*(pExynosComponent->pCallbacks->EventHandler))
794            (pOMXComponent,
795             pExynosComponent->callbackData,
796             OMX_EventPortSettingsChanged, /* The command was completed */
797             OMX_DirOutput, /* This is the port index */
798             OMX_IndexConfigCommonOutputCrop,
799             NULL);
800    }
801
802    Exynos_OSAL_SleepMillisec(0);
803    ret = OMX_ErrorInputDataDecodeYet;
804    H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
805
806EXIT:
807    FunctionOut();
808
809    return ret;
810}
811
812OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
813{
814    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
815    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
816    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
817    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
818    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
819    EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
820    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
821
822    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
823    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
824    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
825
826    int i, nOutbufs;
827
828    FunctionIn();
829
830    /* get dpb count */
831    nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
832
833    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
834        /* should be done before prepare output buffer */
835        if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
836            ret = OMX_ErrorInsufficientResources;
837            goto EXIT;
838        }
839    }
840
841    pOutbufOps->Set_Shareable(hMFCHandle);
842    if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
843        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
844        ret = OMX_ErrorInsufficientResources;
845        goto EXIT;
846    }
847
848    ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
849    OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
850    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
851    int plane;
852
853    nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
854                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight);
855    nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
856                        pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1);
857
858    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
859        MEMORY_TYPE memoryType;
860        if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
861            memoryType = SECURE_MEMORY;
862        else
863            memoryType = NORMAL_MEMORY;
864
865        /* Register output buffer */
866        for (i = 0; i < nOutbufs; i++) {
867            pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
868            Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
869
870            for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
871                pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] =
872                    (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[plane], memoryType);
873                if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] == NULL) {
874                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
875                    ret = OMX_ErrorInsufficientResources;
876                    goto EXIT;
877                }
878                pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] =
879                    Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
880                                                       pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
881                pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = nAllocLen[plane];
882
883                planes[plane].addr = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane];
884                planes[plane].fd = pVideoDec->pMFCDecOutputBuffer[i]->fd[plane];
885                planes[plane].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane];
886            }
887
888            if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
889                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
890                ret = OMX_ErrorInsufficientResources;
891                goto EXIT;
892            }
893            pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
894                            (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
895        }
896    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
897        /* Register output buffer */
898        /*************/
899        /*    TBD    */
900        /*************/
901#ifdef USE_ANB
902        if (pExynosOutputPort->bIsANBEnabled == OMX_TRUE) {
903            for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
904                for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
905                    planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
906                    planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
907                    planes[plane].allocSize = nAllocLen[plane];
908                }
909
910                if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
911                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
912                    ret = OMX_ErrorInsufficientResources;
913                    goto EXIT;
914                }
915                pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
916                               (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
917            }
918        } else {
919            ret = OMX_ErrorNotImplemented;
920            goto EXIT;
921        }
922#else
923        ret = OMX_ErrorNotImplemented;
924        goto EXIT;
925#endif
926    }
927
928    if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
929        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
930        ret = OMX_ErrorInsufficientResources;
931        goto EXIT;
932    }
933
934    if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
935        H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
936    }
937    pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
938
939    ret = OMX_ErrorNone;
940
941EXIT:
942    FunctionOut();
943
944    return ret;
945}
946
947OMX_ERRORTYPE Exynos_H264Dec_GetParameter(
948    OMX_IN OMX_HANDLETYPE hComponent,
949    OMX_IN OMX_INDEXTYPE  nParamIndex,
950    OMX_INOUT OMX_PTR     pComponentParameterStructure)
951{
952    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
953    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
954    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
955
956    FunctionIn();
957
958    if (hComponent == NULL || pComponentParameterStructure == NULL) {
959        ret = OMX_ErrorBadParameter;
960        goto EXIT;
961    }
962    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
963    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
964    if (ret != OMX_ErrorNone) {
965        goto EXIT;
966    }
967    if (pOMXComponent->pComponentPrivate == NULL) {
968        ret = OMX_ErrorBadParameter;
969        goto EXIT;
970    }
971
972    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
973    if (pExynosComponent->currentState == OMX_StateInvalid ) {
974        ret = OMX_ErrorInvalidState;
975        goto EXIT;
976    }
977
978    switch (nParamIndex) {
979    case OMX_IndexParamVideoAvc:
980    {
981        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
982        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
983        EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
984
985        ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
986        if (ret != OMX_ErrorNone) {
987            goto EXIT;
988        }
989
990        if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
991            ret = OMX_ErrorBadPortIndex;
992            goto EXIT;
993        }
994
995        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
996        pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex];
997
998        Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
999    }
1000        break;
1001    case OMX_IndexParamStandardComponentRole:
1002    {
1003        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1004        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1005        if (ret != OMX_ErrorNone) {
1006            goto EXIT;
1007        }
1008
1009        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
1010    }
1011        break;
1012    case OMX_IndexParamVideoProfileLevelQuerySupported:
1013    {
1014        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1015        EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1016        OMX_U32 maxProfileLevelNum = 0;
1017
1018        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1019        if (ret != OMX_ErrorNone) {
1020            goto EXIT;
1021        }
1022
1023        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1024            ret = OMX_ErrorBadPortIndex;
1025            goto EXIT;
1026        }
1027
1028        pProfileLevel = supportedAVCProfileLevels;
1029        maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1030
1031        if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1032            ret = OMX_ErrorNoMore;
1033            goto EXIT;
1034        }
1035
1036        pProfileLevel += pDstProfileLevel->nProfileIndex;
1037        pDstProfileLevel->eProfile = pProfileLevel->profile;
1038        pDstProfileLevel->eLevel = pProfileLevel->level;
1039    }
1040        break;
1041    case OMX_IndexParamVideoProfileLevelCurrent:
1042    {
1043        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1044        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1045        EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
1046
1047        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1048        if (ret != OMX_ErrorNone) {
1049            goto EXIT;
1050        }
1051
1052        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1053            ret = OMX_ErrorBadPortIndex;
1054            goto EXIT;
1055        }
1056
1057        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1058        pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex];
1059
1060        pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1061        pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1062    }
1063        break;
1064    case OMX_IndexParamVideoErrorCorrection:
1065    {
1066        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1067        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1068        EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
1069
1070        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1071        if (ret != OMX_ErrorNone) {
1072            goto EXIT;
1073        }
1074
1075        if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1076            ret = OMX_ErrorBadPortIndex;
1077            goto EXIT;
1078        }
1079
1080        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1081        pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1082
1083        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1084        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1085        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1086        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1087        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1088    }
1089        break;
1090    default:
1091        ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1092        break;
1093    }
1094EXIT:
1095    FunctionOut();
1096
1097    return ret;
1098}
1099
1100OMX_ERRORTYPE Exynos_H264Dec_SetParameter(
1101    OMX_IN OMX_HANDLETYPE hComponent,
1102    OMX_IN OMX_INDEXTYPE  nIndex,
1103    OMX_IN OMX_PTR        pComponentParameterStructure)
1104{
1105    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1106    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1107    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1108
1109    FunctionIn();
1110
1111    if (hComponent == NULL || pComponentParameterStructure == NULL) {
1112        ret = OMX_ErrorBadParameter;
1113        goto EXIT;
1114    }
1115    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1116    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1117    if (ret != OMX_ErrorNone) {
1118        goto EXIT;
1119    }
1120    if (pOMXComponent->pComponentPrivate == NULL) {
1121        ret = OMX_ErrorBadParameter;
1122        goto EXIT;
1123    }
1124
1125    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1126    if (pExynosComponent->currentState == OMX_StateInvalid ) {
1127        ret = OMX_ErrorInvalidState;
1128        goto EXIT;
1129    }
1130
1131    switch (nIndex) {
1132    case OMX_IndexParamVideoAvc:
1133    {
1134        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1135        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1136        EXYNOS_H264DEC_HANDLE   *pH264Dec = NULL;
1137
1138        ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1139        if (ret != OMX_ErrorNone) {
1140            goto EXIT;
1141        }
1142
1143        if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1144            ret = OMX_ErrorBadPortIndex;
1145            goto EXIT;
1146        }
1147
1148        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1149        pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex];
1150
1151        Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1152    }
1153        break;
1154    case OMX_IndexParamStandardComponentRole:
1155    {
1156        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1157
1158        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1159        if (ret != OMX_ErrorNone) {
1160            goto EXIT;
1161        }
1162
1163        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1164            ret = OMX_ErrorIncorrectStateOperation;
1165            goto EXIT;
1166        }
1167
1168        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE)) {
1169            pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1170        } else {
1171            ret = OMX_ErrorBadParameter;
1172            goto EXIT;
1173        }
1174    }
1175        break;
1176    case OMX_IndexParamVideoProfileLevelCurrent:
1177    {
1178        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1179        OMX_VIDEO_PARAM_AVCTYPE          *pDstAVCComponent = NULL;
1180        EXYNOS_H264DEC_HANDLE            *pH264Dec = NULL;
1181
1182        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1183        if (ret != OMX_ErrorNone)
1184            goto EXIT;
1185
1186        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1187            ret = OMX_ErrorBadPortIndex;
1188            goto EXIT;
1189        }
1190
1191        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1192
1193        pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex];
1194        pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1195        pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1196    }
1197        break;
1198    case OMX_IndexParamVideoErrorCorrection:
1199    {
1200        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1201        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1202        EXYNOS_H264DEC_HANDLE               *pH264Dec = NULL;
1203
1204        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1205        if (ret != OMX_ErrorNone) {
1206            goto EXIT;
1207        }
1208
1209        if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1210            ret = OMX_ErrorBadPortIndex;
1211            goto EXIT;
1212        }
1213
1214        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1215        pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1216
1217        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1218        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1219        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1220        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1221        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1222    }
1223        break;
1224    default:
1225        ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1226        break;
1227    }
1228EXIT:
1229    FunctionOut();
1230
1231    return ret;
1232}
1233
1234OMX_ERRORTYPE Exynos_H264Dec_GetConfig(
1235    OMX_HANDLETYPE hComponent,
1236    OMX_INDEXTYPE  nIndex,
1237    OMX_PTR        pComponentConfigStructure)
1238{
1239    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1240    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1241    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1242
1243    FunctionIn();
1244
1245    if (hComponent == NULL) {
1246        ret = OMX_ErrorBadParameter;
1247        goto EXIT;
1248    }
1249    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1250    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1251    if (ret != OMX_ErrorNone) {
1252        goto EXIT;
1253    }
1254    if (pOMXComponent->pComponentPrivate == NULL) {
1255        ret = OMX_ErrorBadParameter;
1256        goto EXIT;
1257    }
1258    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1259    if (pComponentConfigStructure == NULL) {
1260        ret = OMX_ErrorBadParameter;
1261        goto EXIT;
1262    }
1263    if (pExynosComponent->currentState == OMX_StateInvalid) {
1264        ret = OMX_ErrorInvalidState;
1265        goto EXIT;
1266    }
1267
1268    switch (nIndex) {
1269    case OMX_IndexConfigCommonOutputCrop:
1270    {
1271        EXYNOS_H264DEC_HANDLE  *pH264Dec = NULL;
1272        OMX_CONFIG_RECTTYPE    *pSrcRectType = NULL;
1273        OMX_CONFIG_RECTTYPE    *pDstRectType = NULL;
1274        pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1275
1276        if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1277            ret = OMX_ErrorNotReady;
1278            break;
1279        }
1280
1281        pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
1282
1283        if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
1284            (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
1285            ret = OMX_ErrorBadPortIndex;
1286            goto EXIT;
1287        }
1288
1289        EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
1290
1291        pSrcRectType = &(pExynosPort->cropRectangle);
1292
1293        pDstRectType->nTop = pSrcRectType->nTop;
1294        pDstRectType->nLeft = pSrcRectType->nLeft;
1295        pDstRectType->nHeight = pSrcRectType->nHeight;
1296        pDstRectType->nWidth = pSrcRectType->nWidth;
1297    }
1298        break;
1299    default:
1300        ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1301        break;
1302    }
1303
1304EXIT:
1305    FunctionOut();
1306
1307    return ret;
1308}
1309
1310OMX_ERRORTYPE Exynos_H264Dec_SetConfig(
1311    OMX_HANDLETYPE hComponent,
1312    OMX_INDEXTYPE  nIndex,
1313    OMX_PTR        pComponentConfigStructure)
1314{
1315    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1316    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1317    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1318
1319    FunctionIn();
1320
1321    if (hComponent == NULL) {
1322        ret = OMX_ErrorBadParameter;
1323        goto EXIT;
1324    }
1325    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1326    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1327    if (ret != OMX_ErrorNone) {
1328        goto EXIT;
1329    }
1330    if (pOMXComponent->pComponentPrivate == NULL) {
1331        ret = OMX_ErrorBadParameter;
1332        goto EXIT;
1333    }
1334    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1335    if (pComponentConfigStructure == NULL) {
1336        ret = OMX_ErrorBadParameter;
1337        goto EXIT;
1338    }
1339    if (pExynosComponent->currentState == OMX_StateInvalid) {
1340        ret = OMX_ErrorInvalidState;
1341        goto EXIT;
1342    }
1343
1344    switch (nIndex) {
1345    default:
1346        ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1347        break;
1348    }
1349
1350EXIT:
1351    FunctionOut();
1352
1353    return ret;
1354}
1355
1356OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex(
1357    OMX_IN OMX_HANDLETYPE  hComponent,
1358    OMX_IN OMX_STRING      cParameterName,
1359    OMX_OUT OMX_INDEXTYPE *pIndexType)
1360{
1361    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1362    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1363    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1364
1365    FunctionIn();
1366
1367    if (hComponent == NULL) {
1368        ret = OMX_ErrorBadParameter;
1369        goto EXIT;
1370    }
1371    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1372    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1373    if (ret != OMX_ErrorNone) {
1374        goto EXIT;
1375    }
1376    if (pOMXComponent->pComponentPrivate == NULL) {
1377        ret = OMX_ErrorBadParameter;
1378        goto EXIT;
1379    }
1380    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1381    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1382        ret = OMX_ErrorBadParameter;
1383        goto EXIT;
1384    }
1385    if (pExynosComponent->currentState == OMX_StateInvalid) {
1386        ret = OMX_ErrorInvalidState;
1387        goto EXIT;
1388    }
1389
1390    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1391        EXYNOS_H264DEC_HANDLE *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1392        *pIndexType = OMX_IndexVendorThumbnailMode;
1393        ret = OMX_ErrorNone;
1394    } else {
1395        ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1396    }
1397
1398EXIT:
1399    FunctionOut();
1400
1401    return ret;
1402}
1403
1404OMX_ERRORTYPE Exynos_H264Dec_ComponentRoleEnum(
1405    OMX_HANDLETYPE hComponent,
1406    OMX_U8        *cRole,
1407    OMX_U32        nIndex)
1408{
1409    OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1410    OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1411    EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1412
1413    FunctionIn();
1414
1415    if ((hComponent == NULL) || (cRole == NULL)) {
1416        ret = OMX_ErrorBadParameter;
1417        goto EXIT;
1418    }
1419    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1420        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
1421        ret = OMX_ErrorNone;
1422    } else {
1423        ret = OMX_ErrorNoMore;
1424    }
1425
1426EXIT:
1427    FunctionOut();
1428
1429    return ret;
1430}
1431
1432/* MFC Init */
1433OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1434{
1435    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
1436    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1437    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1438    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1439    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1440    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1441    OMX_PTR                        hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
1442
1443    ExynosVideoDecOps       *pDecOps    = NULL;
1444    ExynosVideoDecBufferOps *pInbufOps  = NULL;
1445    ExynosVideoDecBufferOps *pOutbufOps = NULL;
1446
1447    CSC_METHOD csc_method = CSC_METHOD_SW;
1448    int i, plane;
1449
1450    FunctionIn();
1451
1452    pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1453    pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
1454    pExynosComponent->bUseFlagEOF = OMX_TRUE;
1455    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1456
1457    /* H.264 Codec Open */
1458    ret = H264CodecOpen(pH264Dec);
1459    if (ret != OMX_ErrorNone) {
1460        goto EXIT;
1461    }
1462
1463    pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1464    pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
1465    pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1466
1467    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1468        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1469        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1470
1471        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1472            pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1473            Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1474            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
1475
1476            for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1477                /* Use ION Allocator */
1478                pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
1479                pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1480                pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1481                pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1482                if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
1483                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1484                    ret = OMX_ErrorInsufficientResources;
1485                    goto EXIT;
1486                }
1487                Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1488            }
1489
1490            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1491        }
1492    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1493        /*************/
1494        /*    TBD    */
1495        /*************/
1496        /* Does not require any actions. */
1497    }
1498
1499    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1500        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1501        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1502    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1503        /*************/
1504        /*    TBD    */
1505        /*************/
1506        /* Does not require any actions. */
1507    }
1508
1509    pH264Dec->bSourceStart = OMX_FALSE;
1510    Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent);
1511    pH264Dec->bDestinationStart = OMX_FALSE;
1512    Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationStartEvent);
1513
1514    Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1515    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1516    pH264Dec->hMFCH264Handle.indexTimestamp = 0;
1517    pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0;
1518
1519    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1520
1521#if 0//defined(USE_CSC_GSCALER)
1522    csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1523#endif
1524    if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
1525        pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
1526        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
1527        csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode);
1528    } else {
1529        pVideoDec->csc_handle = csc_init(csc_method);
1530    }
1531
1532    if (pVideoDec->csc_handle == NULL) {
1533        ret = OMX_ErrorInsufficientResources;
1534        goto EXIT;
1535    }
1536    pVideoDec->csc_set_format = OMX_FALSE;
1537
1538EXIT:
1539    FunctionOut();
1540
1541    return ret;
1542}
1543
1544/* MFC Terminate */
1545OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1546{
1547    OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
1548    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1549    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1550    EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1551    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1552    EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1553    OMX_PTR                        hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
1554
1555    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1556    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
1557    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1558
1559    int i, plane;
1560
1561    FunctionIn();
1562
1563    if (pVideoDec->csc_handle != NULL) {
1564        csc_deinit(pVideoDec->csc_handle);
1565        pVideoDec->csc_handle = NULL;
1566    }
1567
1568    Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
1569    pH264Dec->hDestinationStartEvent = NULL;
1570    pH264Dec->bDestinationStart = OMX_FALSE;
1571    Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent);
1572    pH264Dec->hSourceStartEvent = NULL;
1573    pH264Dec->bSourceStart = OMX_FALSE;
1574
1575    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1576        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1577            if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
1578                for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1579                    if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] != NULL)
1580                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane]);
1581                }
1582
1583                Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
1584                pVideoDec->pMFCDecOutputBuffer[i] = NULL;
1585            }
1586        }
1587
1588        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1589        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1590    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1591        /*************/
1592        /*    TBD    */
1593        /*************/
1594        /* Does not require any actions. */
1595    }
1596
1597    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1598        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1599            if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
1600                for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1601                    if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
1602                        Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1603                }
1604                Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
1605                pVideoDec->pMFCDecInputBuffer[i] = NULL;
1606            }
1607        }
1608
1609        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1610        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1611    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1612        /*************/
1613        /*    TBD    */
1614        /*************/
1615        /* Does not require any actions. */
1616    }
1617    H264CodecClose(pH264Dec);
1618
1619EXIT:
1620    FunctionOut();
1621
1622    return ret;
1623}
1624
1625OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1626{
1627    OMX_ERRORTYPE               ret = OMX_ErrorNone;
1628    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1629    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1630    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1631    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1632    EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1633    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1634    OMX_U32  oneFrameSize = pSrcInputData->dataLen;
1635    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1636    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
1637    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1638    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1639    int i;
1640
1641    FunctionIn();
1642
1643    if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1644        ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1645        goto EXIT;
1646    }
1647    if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1648        ret = H264CodecDstSetup(pOMXComponent);
1649    }
1650
1651    if (((pVideoDec->bDRMPlayerMode == OMX_TRUE) ||
1652            (Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize) == OMX_TRUE)) ||
1653        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1654        pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1655        pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1656        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);
1657        pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
1658        pH264Dec->hMFCH264Handle.indexTimestamp++;
1659        pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1660
1661        /* queue work for input buffer */
1662        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
1663        codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1664                                    (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1665        if (codecReturn != VIDEO_ERROR_NONE) {
1666            ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1667            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1668            goto EXIT;
1669        }
1670        H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1671        if (pH264Dec->bSourceStart == OMX_FALSE) {
1672            pH264Dec->bSourceStart = OMX_TRUE;
1673            Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
1674            Exynos_OSAL_SleepMillisec(0);
1675        }
1676        if (pH264Dec->bDestinationStart == OMX_FALSE) {
1677            pH264Dec->bDestinationStart = OMX_TRUE;
1678            Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
1679            Exynos_OSAL_SleepMillisec(0);
1680        }
1681    }
1682
1683    ret = OMX_ErrorNone;
1684
1685EXIT:
1686    FunctionOut();
1687
1688    return ret;
1689}
1690
1691OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1692{
1693    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1694    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1695    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1696    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1697    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1698    EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1699    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1700    ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
1701    ExynosVideoBuffer       *pVideoBuffer;
1702
1703    FunctionIn();
1704
1705    pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1706
1707    pSrcOutputData->dataLen       = 0;
1708    pSrcOutputData->usedDataLen   = 0;
1709    pSrcOutputData->remainDataLen = 0;
1710    pSrcOutputData->nFlags    = 0;
1711    pSrcOutputData->timeStamp = 0;
1712
1713    if (pVideoBuffer == NULL) {
1714        pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1715        pSrcOutputData->allocSize  = 0;
1716        pSrcOutputData->pPrivate = NULL;
1717        pSrcOutputData->bufferHeader = NULL;
1718    } else {
1719        pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1720        pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
1721        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
1722
1723        if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1724            int i = 0;
1725            while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
1726                if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1727                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
1728                    ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1729                    goto EXIT;
1730                }
1731                i++;
1732            }
1733            pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1734            pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
1735        }
1736
1737        /* For Share Buffer */
1738        pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1739    }
1740
1741    ret = OMX_ErrorNone;
1742
1743EXIT:
1744    FunctionOut();
1745
1746    return ret;
1747}
1748
1749OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1750{
1751    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1752    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1753    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1754    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1755    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1756    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1757    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1758    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1759    OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
1760    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1761
1762    FunctionIn();
1763
1764    if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
1765        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1766        ret = OMX_ErrorBadParameter;
1767        goto EXIT;
1768    }
1769
1770    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
1771                                        pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
1772                                        pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
1773
1774    codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
1775                     (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
1776
1777    if (codecReturn != VIDEO_ERROR_NONE) {
1778        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
1779        ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
1780        goto EXIT;
1781    }
1782    H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1783
1784    ret = OMX_ErrorNone;
1785
1786EXIT:
1787    FunctionOut();
1788
1789    return ret;
1790}
1791
1792OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1793{
1794    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1795    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1796    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1797    EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1798    void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1799    EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1800    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1801    ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1802    ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1803    ExynosVideoBuffer       *pVideoBuffer;
1804    ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1805    ExynosVideoGeometry *bufferGeometry;
1806    DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
1807    OMX_S32 indexTimestamp = 0;
1808    int plane;
1809
1810    FunctionIn();
1811
1812    if (pH264Dec->bDestinationStart == OMX_FALSE) {
1813        ret = OMX_ErrorNone;
1814        goto EXIT;
1815    }
1816
1817    while (1) {
1818        if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1819            ret = OMX_ErrorNone;
1820            goto EXIT;
1821        }
1822        displayStatus = pVideoBuffer->displayStatus;
1823        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
1824
1825        if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
1826            (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
1827            (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1828            (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
1829            if (pVideoBuffer != NULL) {
1830                ret = OMX_ErrorNone;
1831                break;
1832            } else {
1833                ret = OMX_ErrorUndefined;
1834                break;
1835            }
1836        }
1837    }
1838
1839    if (ret != OMX_ErrorNone)
1840        goto EXIT;
1841
1842    pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
1843    pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1844
1845    pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
1846    for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1847        pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
1848        pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
1849        pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
1850        pDstOutputData->dataLen +=  pVideoBuffer->planes[plane].dataSize;
1851    }
1852    pDstOutputData->usedDataLen = 0;
1853    pDstOutputData->pPrivate = pVideoBuffer;
1854    /* For Share Buffer */
1855    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1856
1857    pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
1858    bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf;
1859    pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
1860    pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
1861    switch (bufferGeometry->eColorFormat) {
1862    case VIDEO_COLORFORMAT_NV12:
1863        pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
1864        break;
1865    case VIDEO_COLORFORMAT_NV12_TILED:
1866    default:
1867        pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
1868        break;
1869    }
1870
1871    indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
1872    Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
1873    if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1874        if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
1875            (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
1876            pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
1877            pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
1878            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
1879        } else {
1880            pDstOutputData->timeStamp = 0x00;
1881            pDstOutputData->nFlags = 0x00;
1882        }
1883    } else {
1884        /* For timestamp correction. if mfc support frametype detect */
1885        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
1886#ifdef NEED_TIMESTAMP_REORDER
1887        if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
1888            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1889            pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1890            pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
1891        } else {
1892            pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
1893            pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
1894        }
1895#else
1896        pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1897        pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1898#endif
1899        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
1900    }
1901
1902    if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1903        ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1904        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
1905        pDstOutputData->remainDataLen = 0;
1906    } else {
1907        pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
1908    }
1909
1910    ret = OMX_ErrorNone;
1911
1912EXIT:
1913    FunctionOut();
1914
1915    return ret;
1916}
1917
1918OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1919{
1920    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1921    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1922    EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1923    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1924
1925    FunctionIn();
1926
1927    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1928        ret = OMX_ErrorNone;
1929        goto EXIT;
1930    }
1931    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1932        ret = OMX_ErrorNone;
1933        goto EXIT;
1934    }
1935
1936    ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
1937    if ((ret != OMX_ErrorNone) && (ret != OMX_ErrorInputDataDecodeYet)) {
1938        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1939                                                pExynosComponent->callbackData,
1940                                                OMX_EventError, ret, 0, NULL);
1941    }
1942
1943EXIT:
1944    FunctionOut();
1945
1946    return ret;
1947}
1948
1949OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1950{
1951    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1952    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1953    EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1954    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1955
1956    FunctionIn();
1957
1958    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
1959        ret = OMX_ErrorNone;
1960        goto EXIT;
1961    }
1962
1963    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1964        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
1965            ret = OMX_ErrorNone;
1966            goto EXIT;
1967        }
1968    }
1969    if ((pH264Dec->bSourceStart == OMX_FALSE) &&
1970       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
1971        Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
1972        Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent);
1973    }
1974
1975    ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
1976    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
1977        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
1978                                                pExynosComponent->callbackData,
1979                                                OMX_EventError, ret, 0, NULL);
1980    }
1981
1982EXIT:
1983    FunctionOut();
1984
1985    return ret;
1986}
1987
1988OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1989{
1990    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1991    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1992    EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1993    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1994
1995    FunctionIn();
1996
1997    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
1998        ret = OMX_ErrorNone;
1999        goto EXIT;
2000    }
2001    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2002        ret = OMX_ErrorNone;
2003        goto EXIT;
2004    }
2005    if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
2006        if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2007           (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2008            Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2009            Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2010        }
2011    }
2012    if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2013        ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
2014        if (ret != OMX_ErrorNone) {
2015            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2016                                                    pExynosComponent->callbackData,
2017                                                    OMX_EventError, ret, 0, NULL);
2018        }
2019    }
2020
2021EXIT:
2022    FunctionOut();
2023
2024    return ret;
2025}
2026
2027OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2028{
2029    OMX_ERRORTYPE             ret = OMX_ErrorNone;
2030    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2031    EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2032    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2033
2034    FunctionIn();
2035
2036    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2037        ret = OMX_ErrorNone;
2038        goto EXIT;
2039    }
2040    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2041        ret = OMX_ErrorNone;
2042        goto EXIT;
2043    }
2044
2045    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2046        if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2047           (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2048            Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2049            Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2050        }
2051    }
2052    ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
2053    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2054        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2055                                                pExynosComponent->callbackData,
2056                                                OMX_EventError, ret, 0, NULL);
2057    }
2058
2059EXIT:
2060    FunctionOut();
2061
2062    return ret;
2063}
2064
2065OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2066{
2067    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2068    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2069    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2070    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2071    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
2072    EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
2073    OMX_BOOL                       bDRMPlayerMode   = OMX_FALSE;
2074    int i = 0;
2075
2076    FunctionIn();
2077
2078    if ((hComponent == NULL) || (componentName == NULL)) {
2079        ret = OMX_ErrorBadParameter;
2080        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2081        goto EXIT;
2082    }
2083    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) {
2084        bDRMPlayerMode = OMX_FALSE;
2085    } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) {
2086        bDRMPlayerMode = OMX_TRUE;
2087    } else {
2088        ret = OMX_ErrorBadParameter;
2089        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2090        goto EXIT;
2091    }
2092
2093    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2094    ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2095    if (ret != OMX_ErrorNone) {
2096        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2097        goto EXIT;
2098    }
2099    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2100    pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2101
2102    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2103    if (pExynosComponent->componentName == NULL) {
2104        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2105        ret = OMX_ErrorInsufficientResources;
2106        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2107        goto EXIT;
2108    }
2109    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2110
2111    pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE));
2112    if (pH264Dec == NULL) {
2113        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2114        ret = OMX_ErrorInsufficientResources;
2115        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2116        goto EXIT;
2117    }
2118    Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE));
2119    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2120    pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec;
2121
2122    if (bDRMPlayerMode == OMX_TRUE)
2123        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC);
2124    else
2125        Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DEC);
2126
2127    pVideoDec->bDRMPlayerMode = bDRMPlayerMode;
2128
2129    /* Set componentVersion */
2130    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2131    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2132    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2133    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2134    /* Set specVersion */
2135    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2136    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2137    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2138    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2139
2140    /* Input port */
2141    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2142    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2143    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2144    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2145    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2146    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2147    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2148    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2149    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2150    pExynosPort->portDefinition.format.video.pNativeRender = 0;
2151    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2152    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2153    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2154    pExynosPort->bufferProcessType = BUFFER_SHARE;
2155    if (bDRMPlayerMode == OMX_TRUE)
2156        pExynosPort->bufferProcessType = BUFFER_SHARE;
2157    pExynosPort->portWayType = WAY2_PORT;
2158
2159    /* Output port */
2160    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2161    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2162    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2163    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2164    pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2165    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2166    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2167    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2168    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2169    pExynosPort->portDefinition.format.video.pNativeRender = 0;
2170    pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2171    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2172    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2173    pExynosPort->bufferProcessType = BUFFER_COPY | BUFFER_ANBSHARE;
2174    pExynosPort->portWayType = WAY2_PORT;
2175
2176    for(i = 0; i < ALL_PORT_NUM; i++) {
2177        INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2178        pH264Dec->AVCComponent[i].nPortIndex = i;
2179        pH264Dec->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2180        pH264Dec->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel4;
2181    }
2182
2183    pOMXComponent->GetParameter      = &Exynos_H264Dec_GetParameter;
2184    pOMXComponent->SetParameter      = &Exynos_H264Dec_SetParameter;
2185    pOMXComponent->GetConfig         = &Exynos_H264Dec_GetConfig;
2186    pOMXComponent->SetConfig         = &Exynos_H264Dec_SetConfig;
2187    pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex;
2188    pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum;
2189    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2190
2191    pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Dec_Init;
2192    pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate;
2193
2194    pVideoDec->exynos_codec_srcInputProcess  = &Exynos_H264Dec_srcInputBufferProcess;
2195    pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess;
2196    pVideoDec->exynos_codec_dstInputProcess  = &Exynos_H264Dec_dstInputBufferProcess;
2197    pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess;
2198
2199    pVideoDec->exynos_codec_start            = &H264CodecStart;
2200    pVideoDec->exynos_codec_stop             = &H264CodecStop;
2201    pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2202    pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
2203
2204    pVideoDec->exynos_checkInputFrame                 = &Check_H264_Frame;
2205    pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2206    pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2207
2208    pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2209    if (pVideoDec->hSharedMemory == NULL) {
2210        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2211        Exynos_OSAL_Free(pH264Dec);
2212        pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2213        Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2214        ret = OMX_ErrorInsufficientResources;
2215        goto EXIT;
2216    }
2217
2218    pExynosComponent->currentState = OMX_StateLoaded;
2219
2220    ret = OMX_ErrorNone;
2221
2222EXIT:
2223    FunctionOut();
2224
2225    return ret;
2226}
2227
2228OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2229{
2230    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2231    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2232    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2233    EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
2234    EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
2235
2236    FunctionIn();
2237
2238    if (hComponent == NULL) {
2239        ret = OMX_ErrorBadParameter;
2240        goto EXIT;
2241    }
2242    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2243    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2244    pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2245
2246    Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2247
2248    Exynos_OSAL_Free(pExynosComponent->componentName);
2249    pExynosComponent->componentName = NULL;
2250
2251    pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2252    if (pH264Dec != NULL) {
2253        Exynos_OSAL_Free(pH264Dec);
2254        pH264Dec = pVideoDec->hCodecHandle = NULL;
2255    }
2256
2257    ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2258    if (ret != OMX_ErrorNone) {
2259        goto EXIT;
2260    }
2261
2262    ret = OMX_ErrorNone;
2263
2264EXIT:
2265    FunctionOut();
2266
2267    return ret;
2268}
2269