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