c104712f90c8bf0a058724357255f33f35394727
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / dec / h264 / Exynos_OMX_H264dec.c
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 #include <mm_types.h>
31
32 #include "Exynos_OMX_Macros.h"
33 #include "Exynos_OMX_Basecomponent.h"
34 #include "Exynos_OMX_Baseport.h"
35 #include "Exynos_OMX_Vdec.h"
36 #include "Exynos_OSAL_ETC.h"
37 #include "Exynos_OSAL_Semaphore.h"
38 #include "Exynos_OSAL_Thread.h"
39 #include "library_register.h"
40 #include "Exynos_OMX_H264dec.h"
41 #include "ExynosVideoApi.h"
42 #include "Exynos_OSAL_SharedMemory.h"
43 #include "Exynos_OSAL_Event.h"
44 #include "Exynos_OMX_VdecControl.h"
45
46
47
48 #ifdef USE_PB
49 #include "Exynos_OSAL_Platform_Specific.h"
50 #endif
51
52 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
53 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
54 #include "csc.h"
55
56 #undef  EXYNOS_LOG_TAG
57 #define EXYNOS_LOG_TAG    "EXYNOS_H264_DEC"
58 #define EXYNOS_LOG_OFF
59 //#define EXYNOS_TRACE_ON
60 #include "Exynos_OSAL_Log.h"
61
62 #define H264_DEC_NUM_OF_EXTRA_BUFFERS 7
63
64 //#define ADD_SPS_PPS_I_FRAME
65 //#define FULL_FRAME_SEARCH
66
67 /* H.264 Decoder Supported Levels & profiles */
68 EXYNOS_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={
69     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1},
70     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b},
71     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11},
72     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12},
73     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13},
74     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2},
75     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21},
76     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22},
77     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3},
78     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31},
79     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32},
80     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4},
81     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41},
82     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
83
84     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1},
85     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
86     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
87     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12},
88     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13},
89     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2},
90     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21},
91     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22},
92     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3},
93     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31},
94     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32},
95     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4},
96     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41},
97     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
98
99     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
100     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
101     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
102     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
103     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
104     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2},
105     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
106     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
107     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3},
108     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
109     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
110     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
111     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
112     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}};
113
114 static OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, void *pVirtAddr, OMX_U32 *dataSize)
115 {
116     return OMX_ErrorNone;
117 }
118
119 static OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
120 {
121     OMX_ERRORTYPE       ret          = OMX_ErrorNone;
122     ExynosVideoBuffer  *pCodecBuffer = NULL;
123
124     if (codecBuffer == NULL) {
125         ret = OMX_ErrorBadParameter;
126         goto EXIT;
127     }
128
129     pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
130
131     if (addr != NULL) {
132         addr[0] = pCodecBuffer->planes[0].addr;
133         addr[1] = pCodecBuffer->planes[1].addr;
134         addr[2] = pCodecBuffer->planes[2].addr;
135     }
136
137     if (size != NULL) {
138         size[0] = pCodecBuffer->planes[0].allocSize;
139         size[1] = pCodecBuffer->planes[1].allocSize;
140         size[2] = pCodecBuffer->planes[2].allocSize;
141     }
142
143 EXIT:
144     return ret;
145 }
146
147 #ifndef TIZEN_FEATURE_E3250
148 int Check_H264_Frame(
149     OMX_U8   *pInputStream,
150     OMX_U32   buffSize,
151     OMX_U32   flag,
152     OMX_BOOL  bPreviousFrameEOF,
153     OMX_BOOL *pbEndOfFrame)
154 {
155     OMX_U32  preFourByte       = (OMX_U32)-1;
156     int      accessUnitSize    = 0;
157     int      frameTypeBoundary = 0;
158     int      nextNaluSize      = 0;
159     int      naluStart         = 0;
160
161     if (bPreviousFrameEOF == OMX_TRUE)
162         naluStart = 0;
163     else
164         naluStart = 1;
165
166     while (1) {
167         int inputOneByte = 0;
168
169         if (accessUnitSize == (int)buffSize)
170             goto EXIT;
171
172         inputOneByte = *(pInputStream++);
173         accessUnitSize += 1;
174
175         if (preFourByte == 0x00000001 || (preFourByte << 8) == 0x00000100) {
176             int naluType = inputOneByte & 0x1F;
177
178             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d", naluType);
179             if (naluStart == 0) {
180 #ifdef ADD_SPS_PPS_I_FRAME
181                 if (naluType == 1 || naluType == 5)
182 #else
183                 if (naluType == 1 || naluType == 5 || naluType == 7 || naluType == 8)
184 #endif
185                     naluStart = 1;
186             } else {
187 #ifdef OLD_DETECT
188                 frameTypeBoundary = (8 - naluType) & (naluType - 10); //AUD(9)
189 #else
190                 if (naluType == 9)
191                     frameTypeBoundary = -2;
192 #endif
193                 if (naluType == 1 || naluType == 5) {
194                     if (accessUnitSize == (int)buffSize) {
195                         accessUnitSize--;
196                         goto EXIT;
197                     }
198                     inputOneByte = *pInputStream++;
199                     accessUnitSize += 1;
200
201                     if (inputOneByte >= 0x80)
202                         frameTypeBoundary = -1;
203                 }
204                 if (frameTypeBoundary < 0) {
205                     break;
206                 }
207             }
208
209         }
210         preFourByte = (preFourByte << 8) + inputOneByte;
211     }
212
213     *pbEndOfFrame = OMX_TRUE;
214     nextNaluSize = -5;
215     if (frameTypeBoundary == -1)
216         nextNaluSize = -6;
217     if (preFourByte != 0x00000001)
218         nextNaluSize++;
219     return (accessUnitSize + nextNaluSize);
220
221 EXIT:
222     *pbEndOfFrame = OMX_FALSE;
223
224     return accessUnitSize;
225 }
226 #endif
227
228 static OMX_BOOL Check_H264_StartCode(
229     OMX_U8 *pInputStream,
230     OMX_U32 streamSize)
231 {
232     if (streamSize < 4) {
233         return OMX_FALSE;
234     }
235
236     if ((pInputStream[0] == 0x00) &&
237         (pInputStream[1] == 0x00) &&
238         (pInputStream[2] == 0x00) &&
239         (pInputStream[3] != 0x00) &&
240         ((pInputStream[3] >> 3) == 0x00)) {
241         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[4] & 0x1F), pInputStream[3], pInputStream[4], pInputStream[5]);
242         return OMX_TRUE;
243     } else if ((pInputStream[0] == 0x00) &&
244                (pInputStream[1] == 0x00) &&
245                (pInputStream[2] != 0x00) &&
246                ((pInputStream[2] >> 3) == 0x00)) {
247         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NaluType : %d, 0x%x, 0x%x, 0x%x", (pInputStream[3] & 0x1F), pInputStream[2], pInputStream[3], pInputStream[4]);
248         return OMX_TRUE;
249     } else {
250         return OMX_FALSE;
251     }
252 }
253
254 OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264DEC_HANDLE *pH264Dec)
255 {
256     OMX_ERRORTYPE            ret        = OMX_ErrorNone;
257     ExynosVideoDecOps       *pDecOps    = NULL;
258     ExynosVideoDecBufferOps *pInbufOps  = NULL;
259     ExynosVideoDecBufferOps *pOutbufOps = NULL;
260
261     FunctionIn();
262
263     if (pH264Dec == NULL) {
264         ret = OMX_ErrorBadParameter;
265         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
266         goto EXIT;
267     }
268
269     /* alloc ops structure */
270     pDecOps    = (ExynosVideoDecOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecOps));
271     pInbufOps  = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
272     pOutbufOps = (ExynosVideoDecBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoDecBufferOps));
273
274     if ((pDecOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
275         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate decoder ops buffer");
276         ret = OMX_ErrorInsufficientResources;
277         goto EXIT;
278     }
279
280     pH264Dec->hMFCH264Handle.pDecOps    = pDecOps;
281     pH264Dec->hMFCH264Handle.pInbufOps  = pInbufOps;
282     pH264Dec->hMFCH264Handle.pOutbufOps = pOutbufOps;
283
284     /* function pointer mapping */
285     pDecOps->nSize    = sizeof(ExynosVideoDecOps);
286     pInbufOps->nSize  = sizeof(ExynosVideoDecBufferOps);
287     pOutbufOps->nSize = sizeof(ExynosVideoDecBufferOps);
288
289     Exynos_Video_Register_Decoder(pDecOps, pInbufOps, pOutbufOps);
290
291     /* check mandatory functions for decoder ops */
292     if ((pDecOps->Init == NULL) || (pDecOps->Finalize == NULL) ||
293         (pDecOps->Get_ActualBufferCount == NULL) || (pDecOps->Set_FrameTag == NULL) ||
294 #ifdef USE_S3D_SUPPORT
295         (pDecOps->Enable_SEIParsing == NULL) || (pDecOps->Get_FramePackingInfo == NULL) ||
296 #endif
297         (pDecOps->Get_FrameTag == NULL)) {
298         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
299         ret = OMX_ErrorInsufficientResources;
300         goto EXIT;
301     }
302
303     /* check mandatory functions for buffer ops */
304     if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
305         (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
306         (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
307         (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
308         (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
309         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
310         ret = OMX_ErrorInsufficientResources;
311         goto EXIT;
312     }
313
314     /* alloc context, open, querycap */
315     if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
316 #ifdef USE_DMA_BUF
317         pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
318 #else
319         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s :%d V4L2_MEMORY_USERPTR", __FUNCTION__, __LINE__);
320         pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_USERPTR);
321 #endif
322     } else {
323         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s :%d V4L2_MEMORY_DMABUF", __FUNCTION__, __LINE__);
324         pH264Dec->hMFCH264Handle.hMFCHandle = pH264Dec->hMFCH264Handle.pDecOps->Init(V4L2_MEMORY_DMABUF);
325     }
326     if (pH264Dec->hMFCH264Handle.hMFCHandle == NULL) {
327         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
328         ret = OMX_ErrorInsufficientResources;
329         goto EXIT;
330     }
331
332 #ifdef USE_S3D_SUPPORT
333     /*S3D: Enable SEI parsing to check Frame Packing */
334     if (pDecOps->Enable_SEIParsing(pH264Dec->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
335         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Enable SEI Parsing");
336         ret = OMX_ErrorInsufficientResources;
337         goto EXIT;
338     }
339 #endif
340
341     ret = OMX_ErrorNone;
342
343 EXIT:
344     if (ret != OMX_ErrorNone) {
345         if (pDecOps != NULL) {
346             Exynos_OSAL_Free(pDecOps);
347             pH264Dec->hMFCH264Handle.pDecOps = NULL;
348         }
349         if (pInbufOps != NULL) {
350             Exynos_OSAL_Free(pInbufOps);
351             pH264Dec->hMFCH264Handle.pInbufOps = NULL;
352         }
353         if (pOutbufOps != NULL) {
354             Exynos_OSAL_Free(pOutbufOps);
355             pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
356         }
357     }
358
359     FunctionOut();
360
361     return ret;
362 }
363
364 OMX_ERRORTYPE H264CodecClose(EXYNOS_H264DEC_HANDLE *pH264Dec)
365 {
366     OMX_ERRORTYPE            ret        = OMX_ErrorNone;
367     void                    *hMFCHandle = NULL;
368     ExynosVideoDecOps       *pDecOps    = NULL;
369     ExynosVideoDecBufferOps *pInbufOps  = NULL;
370     ExynosVideoDecBufferOps *pOutbufOps = NULL;
371
372     FunctionIn();
373
374     if (pH264Dec == NULL) {
375         ret = OMX_ErrorBadParameter;
376         goto EXIT;
377     }
378
379     hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
380     pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
381     pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
382     pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
383
384     if (hMFCHandle != NULL) {
385         pDecOps->Finalize(hMFCHandle);
386         pH264Dec->hMFCH264Handle.hMFCHandle = NULL;
387     }
388     if (pOutbufOps != NULL) {
389         Exynos_OSAL_Free(pOutbufOps);
390         pH264Dec->hMFCH264Handle.pOutbufOps = NULL;
391     }
392     if (pInbufOps != NULL) {
393         Exynos_OSAL_Free(pInbufOps);
394         pH264Dec->hMFCH264Handle.pInbufOps = NULL;
395     }
396     if (pDecOps != NULL) {
397         Exynos_OSAL_Free(pDecOps);
398         pH264Dec->hMFCH264Handle.pDecOps = NULL;
399     }
400
401     ret = OMX_ErrorNone;
402
403 EXIT:
404     FunctionOut();
405
406     return ret;
407 }
408
409 OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
410 {
411     OMX_ERRORTYPE            ret = OMX_ErrorNone;
412     void                    *hMFCHandle = NULL;
413     ExynosVideoDecBufferOps *pInbufOps  = NULL;
414     ExynosVideoDecBufferOps *pOutbufOps = NULL;
415     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
416     EXYNOS_H264DEC_HANDLE   *pH264Dec = NULL;
417
418     FunctionIn();
419
420     if (pOMXComponent == NULL) {
421         ret = OMX_ErrorBadParameter;
422         goto EXIT;
423     }
424
425     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
426     if (pVideoDec == NULL) {
427         ret = OMX_ErrorBadParameter;
428         goto EXIT;
429     }
430
431     pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
432     if (pH264Dec == NULL) {
433         ret = OMX_ErrorBadParameter;
434         goto EXIT;
435     }
436
437     hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
438     pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
439     pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
440
441     if (nPortIndex == INPUT_PORT_INDEX)
442         pInbufOps->Run(hMFCHandle);
443     else if (nPortIndex == OUTPUT_PORT_INDEX)
444         pOutbufOps->Run(hMFCHandle);
445
446     ret = OMX_ErrorNone;
447
448 EXIT:
449     FunctionOut();
450
451     return ret;
452 }
453
454 OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
455 {
456     OMX_ERRORTYPE            ret = OMX_ErrorNone;
457     void                    *hMFCHandle = NULL;
458     ExynosVideoDecBufferOps *pInbufOps  = NULL;
459     ExynosVideoDecBufferOps *pOutbufOps = NULL;
460     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
461     EXYNOS_H264DEC_HANDLE   *pH264Dec = NULL;
462
463     FunctionIn();
464
465     if (pOMXComponent == NULL) {
466         ret = OMX_ErrorBadParameter;
467         goto EXIT;
468     }
469
470     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
471     if (pVideoDec == NULL) {
472         ret = OMX_ErrorBadParameter;
473         goto EXIT;
474     }
475     pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
476     if (pH264Dec == NULL) {
477         ret = OMX_ErrorBadParameter;
478         goto EXIT;
479     }
480
481     hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
482     pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
483     pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
484
485     if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
486         pInbufOps->Stop(hMFCHandle);
487     else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
488         pOutbufOps->Stop(hMFCHandle);
489
490     ret = OMX_ErrorNone;
491
492 EXIT:
493     FunctionOut();
494
495     return ret;
496 }
497
498 OMX_ERRORTYPE H264CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent)
499 {
500     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
501     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
502     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
503     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
504     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
505     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
506     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
507
508     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
509     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
510     ExynosVideoGeometry      bufferConf;
511     OMX_U32                  inputBufferNumber = 0;
512     int i, plane;
513
514
515     if (pVideoDec->bThumbnailMode == OMX_TRUE)
516         pDecOps->Set_DisplayDelay(hMFCHandle, 0);
517
518     /* input buffer info */
519     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
520     bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
521
522     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE
523         ||pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE)
524         pInbufOps->Set_Shareable(hMFCHandle);
525
526     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
527         bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth
528                                 * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
529         inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
530     } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
531         bufferConf.nSizeImage = DEFAULT_MFC_INPUT_BUFFER_SIZE;
532         inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
533     }
534
535     /* should be done before prepare input buffer */
536     if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
537         ret = OMX_ErrorInsufficientResources;
538         goto EXIT;
539     }
540
541     /* set input buffer geometry */
542     if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
543         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
544         ret = OMX_ErrorInsufficientResources;
545         goto EXIT;
546     }
547
548     /* setup input buffer */
549     if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
550         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
551         ret = OMX_ErrorInsufficientResources;
552         goto EXIT;
553     }
554
555     if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
556         pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
557         /* Register input buffer */
558         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
559             ExynosVideoPlane plane;
560             plane.addr = pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0];
561             plane.allocSize = pVideoDec->pMFCDecInputBuffer[i]->bufferSize[0];
562             plane.fd = pVideoDec->pMFCDecInputBuffer[i]->fd[0];
563             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
564                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
565                 ret = OMX_ErrorInsufficientResources;
566                 goto EXIT;
567             }
568         }
569     } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
570         pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE) {
571         ExynosVideoBuffer *pBuffer = NULL;
572
573         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
574             pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
575             Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
576             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
577             /* get input buffer info */
578             if (pInbufOps->Get_Buffer) {
579                 if (pInbufOps->Get_Buffer(pH264Dec->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
580                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info");
581                     ret = OMX_ErrorInsufficientResources;
582                     goto EXIT;
583                 }
584             }
585
586             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
587                 /* Use ION Allocator */
588                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
589                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
590                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
591                 pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
592                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "@pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
593             }
594
595             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
596         }
597     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
598         /* Register input buffer */
599         for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
600             ExynosVideoPlane plane;
601 #if 0
602             if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
603 #endif
604 #ifdef TIZEN_FEATURE_E54XX
605                 /* IL Client assigns FD value in pBuffer */
606                 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
607 #else
608                 plane.addr = Exynos_OSAL_SharedMemory_IONToVirt(pVideoDec->hSharedMemory, (int)pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer);
609 #endif
610 #if 0
611             } else {
612                 plane.addr = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
613             }
614 #endif
615             plane.allocSize = pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
616             plane.fd = pExynosInputPort->extendBufferHeader[i].buf_fd[0];
617             if (pInbufOps->Register(hMFCHandle, &plane, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
618                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
619                 ret = OMX_ErrorInsufficientResources;
620                 goto EXIT;
621             }
622         }
623     }
624
625 EXIT:
626     FunctionOut();
627
628     return ret;
629 }
630
631
632 OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
633 {
634     OMX_ERRORTYPE            ret = OMX_ErrorNone;
635     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = NULL;
636     EXYNOS_H264DEC_HANDLE   *pH264Dec = NULL;
637
638     FunctionIn();
639
640     if (pOMXComponent == NULL) {
641         ret = OMX_ErrorBadParameter;
642         goto EXIT;
643     }
644
645     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
646     if (pVideoDec == NULL) {
647         ret = OMX_ErrorBadParameter;
648         goto EXIT;
649     }
650     pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
651     if (pH264Dec == NULL) {
652         ret = OMX_ErrorBadParameter;
653         goto EXIT;
654     }
655
656
657     if (nPortIndex == INPUT_PORT_INDEX) {
658         if (pH264Dec->bSourceStart == OMX_FALSE) {
659             Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
660             Exynos_OSAL_SleepMillisec(0);
661         }
662     }
663
664     if (nPortIndex == OUTPUT_PORT_INDEX) {
665         if (pH264Dec->bDestinationStart == OMX_FALSE) {
666             Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
667             Exynos_OSAL_SleepMillisec(0);
668         }
669     }
670
671     ret = OMX_ErrorNone;
672
673 EXIT:
674     FunctionOut();
675
676     return ret;
677 }
678
679 OMX_ERRORTYPE H264CodecEnQueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
680 {
681     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
682     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
683     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
684     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
685     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
686     int i, nOutbufs;
687
688     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
689     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
690     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
691
692     FunctionIn();
693
694     if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
695         ret = OMX_ErrorBadPortIndex;
696         goto EXIT;
697     }
698
699     if ((nPortIndex == INPUT_PORT_INDEX) &&
700         (pH264Dec->bSourceStart == OMX_TRUE)) {
701         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
702
703         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
704             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
705             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]);
706
707             Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
708         }
709
710         pInbufOps->Clear_Queue(hMFCHandle);
711     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
712                (pH264Dec->bDestinationStart == OMX_TRUE)) {
713         ExynosVideoBuffer *pBuffer = NULL;
714
715         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
716
717         nOutbufs = pDecOps->Get_ActualBufferCount(hMFCHandle);
718         nOutbufs += EXTRA_DPB_NUM;
719         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "EXTRA_DPB_NUM = %d, nOutbufs =%d", EXTRA_DPB_NUM, nOutbufs);
720         for (i = 0; i < nOutbufs; i++) {
721             pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
722             Exynos_CodecBufferEnQueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
723         }
724         pOutbufOps->Clear_Queue(hMFCHandle);
725     }
726
727 EXIT:
728     FunctionOut();
729
730     return ret;
731 }
732
733 #ifdef USE_S3D_SUPPORT
734 OMX_BOOL H264CodecCheckFramePacking(OMX_COMPONENTTYPE *pOMXComponent)
735 {
736     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
737     EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
738     ExynosVideoDecOps             *pDecOps           = pH264Dec->hMFCH264Handle.pDecOps;
739     ExynosVideoFramePacking        framePacking;
740     void                          *hMFCHandle        = pH264Dec->hMFCH264Handle.hMFCHandle;
741     OMX_BOOL                       ret               = OMX_FALSE;
742
743     /* Get Frame packing information*/
744     if (pDecOps->Get_FramePackingInfo(pH264Dec->hMFCH264Handle.hMFCHandle, &framePacking) != VIDEO_ERROR_NONE) {
745         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Get Frame Packing Information");
746         ret = OMX_FALSE;
747         goto EXIT;
748     }
749
750     if (framePacking.available) {
751         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement ID: 0x%08x", framePacking.arrangement_id);
752         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "arrangement_type: %d", framePacking.arrangement_type);
753         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "content_interpretation_type: %d", framePacking.content_interpretation_type);
754         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "current_frame_is_frame0_flag: %d", framePacking.current_frame_is_frame0_flag);
755         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "spatial_flipping_flag: %d", framePacking.spatial_flipping_flag);
756         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "fr0X:%d fr0Y:%d fr0X:%d fr0Y:%d", framePacking.frame0_grid_pos_x,
757             framePacking.frame0_grid_pos_y, framePacking.frame1_grid_pos_x, framePacking.frame1_grid_pos_y);
758
759         pH264Dec->hMFCH264Handle.S3DFPArgmtType = (EXYNOS_OMX_FPARGMT_TYPE) framePacking.arrangement_type;
760         /** Send Port Settings changed call back - output color format change */
761        (*(pExynosComponent->pCallbacks->EventHandler))
762               (pOMXComponent,
763                pExynosComponent->callbackData,
764                OMX_EventPortSettingsChanged, /* The command was completed */
765                OMX_DirOutput, /* This is the port index */
766                0,
767                NULL);
768
769         Exynos_OSAL_SleepMillisec(0);
770         ret = OMX_TRUE;
771     }
772
773 EXIT:
774     return ret;
775 }
776 #endif
777
778 OMX_ERRORTYPE H264CodecDstFreeCodecBuffers(
779     OMX_COMPONENTTYPE *pOMXComponent)
780 {
781     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
782     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
783     EXYNOS_H264DEC_HANDLE         *pH264Dec         = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
784
785     int i, j;
786
787     FunctionIn();
788
789     for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
790         if (pVideoDec->pMFCDecOutputBuffer[i] != NULL) {
791             for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
792                 if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] != NULL &&
793                     pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE)
794                     Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
795             }
796
797             Exynos_OSAL_Free(pVideoDec->pMFCDecOutputBuffer[i]);
798         }
799     }
800
801     Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer, 0, sizeof(pVideoDec->pMFCDecOutputBuffer));
802
803     FunctionOut();
804
805     return OMX_ErrorNone;
806 }
807
808 OMX_ERRORTYPE H264CodecDstAllocCodecBuffers(
809     OMX_COMPONENTTYPE *pOMXComponent,
810     OMX_U32            nOutbufs)
811 {
812     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
813     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
814     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
815     EXYNOS_H264DEC_HANDLE         *pH264Dec         = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
816
817     MEMORY_TYPE eMemoryType                        = NORMAL_MEMORY;
818     OMX_U32     nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
819     int i, j;
820
821     FunctionIn();
822
823     nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
824                         pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight);
825     nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
826                         pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1);
827
828     if (pVideoDec->bDRMPlayerMode == OMX_TRUE)
829         eMemoryType = SECURE_MEMORY;
830
831     for (i = 0; i < nOutbufs; i++) {
832         pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
833         if (pVideoDec->pMFCDecOutputBuffer[i] == NULL) {
834             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc codec buffer");
835             ret = OMX_ErrorInsufficientResources;
836             goto EXIT;
837         }
838         Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
839
840         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
841             pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] =
842                 (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, nAllocLen[j], eMemoryType);
843             if (pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j] == NULL) {
844                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
845                 ret = OMX_ErrorInsufficientResources;
846                 goto EXIT;
847             }
848
849            pVideoDec->pMFCDecOutputBuffer[i]->fd[j] =
850                 Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory,
851                                                  pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j]);
852            pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j] = nAllocLen[j];
853         }
854     }
855
856     return OMX_ErrorNone;
857
858 EXIT:
859     H264CodecDstFreeCodecBuffers(pOMXComponent);
860
861     FunctionOut();
862
863     return ret;
864 }
865
866 OMX_ERRORTYPE H264CodecDstRegistCodecBuffers(
867     OMX_COMPONENTTYPE *pOMXComponent,
868     OMX_U32            nOutbufs)
869 {
870     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
871     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
872     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
873     EXYNOS_H264DEC_HANDLE         *pH264Dec         = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
874     void                          *hMFCHandle       = pH264Dec->hMFCH264Handle.hMFCHandle;
875     ExynosVideoDecBufferOps       *pOutbufOps       = pH264Dec->hMFCH264Handle.pOutbufOps;
876
877     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
878     OMX_U32          nDataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
879     int i, j;
880
881     FunctionIn();
882
883     /* Register output buffer */
884     for (i = 0; i < nOutbufs; i++) {
885         for (j = 0; j < MFC_OUTPUT_BUFFER_PLANE; j++) {
886             planes[j].addr      = pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[j];
887             planes[j].fd        = pVideoDec->pMFCDecOutputBuffer[i]->fd[j];
888             planes[j].allocSize = pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[j];
889         }
890
891         if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
892             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
893             ret = OMX_ErrorInsufficientResources;
894             goto EXIT;
895         }
896
897         pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
898                         (unsigned int *)nDataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
899     }
900
901     ret = OMX_ErrorNone;
902
903 EXIT:
904     FunctionOut();
905
906     return ret;
907 }
908
909 OMX_ERRORTYPE H264CodecResetupAllElement(
910     OMX_COMPONENTTYPE   *pOMXComponent,
911     OMX_U32              nPortIndex)
912 {
913     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
914     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
915     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
916     EXYNOS_H264DEC_HANDLE         *pH264Dec         = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
917     void                          *hMFCHandle       = pH264Dec->hMFCH264Handle.hMFCHandle;
918     EXYNOS_OMX_BASEPORT           *pOutputPort      = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
919     ExynosVideoDecBufferOps       *pOutbufOps       = pH264Dec->hMFCH264Handle.pOutbufOps;
920
921     FunctionIn();
922
923     if ((nPortIndex == INPUT_PORT_INDEX) &&
924         (pH264Dec->bSourceStart == OMX_TRUE)) {
925         ret = OMX_ErrorNotImplemented;
926         goto EXIT;
927     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
928                (pH264Dec->bDestinationStart == OMX_TRUE)) {
929         if (pOutputPort->bufferProcessType & BUFFER_COPY) {
930
931             /**********************************/
932             /* Codec Buffer Free & Unregister */
933             /**********************************/
934             H264CodecDstFreeCodecBuffers(pOMXComponent);
935             Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
936
937             if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE)
938                 pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
939
940             pOutbufOps->Cleanup(hMFCHandle);
941             /******************************************************/
942             /* V4L2 Destnation Setup for DPB Buffer Number Change */
943             /******************************************************/
944             H264CodecDstSetup(pOMXComponent);
945
946             pVideoDec->bDRCProcessing = OMX_FALSE;
947         } else if (pOutputPort->bufferProcessType & BUFFER_SHARE) {
948
949             /**********************************/
950             /* Codec Buffer Unregister */
951             /**********************************/
952             pOutbufOps->Clear_RegisteredBuffer(hMFCHandle);
953             pOutbufOps->Cleanup(hMFCHandle);
954         }
955     } else {
956         ret = OMX_ErrorBadParameter;
957         goto EXIT;
958     }
959
960 EXIT:
961     FunctionOut();
962
963     return ret;
964 }
965
966 OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
967 {
968     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
969     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
970     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
971     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
972     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
973     OMX_U32                        oneFrameSize = pSrcInputData->dataLen;
974
975     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
976     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
977     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
978     ExynosVideoGeometry      bufferConf;
979
980     FunctionIn();
981
982     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
983         OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
984         OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
985         if (OMXBuffer == NULL) {
986             ret = OMX_ErrorUndefined;
987             goto EXIT;
988         }
989
990         OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
991         OMXBuffer->nFlags = pSrcInputData->nFlags;
992         Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
993
994         ret = OMX_ErrorNone;
995         goto EXIT;
996     }
997
998     if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
999         pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE)) {
1000         ret = H264CodecSrcInit(pOMXComponent);
1001         if (ret != OMX_ErrorNone)
1002             goto EXIT;
1003     }
1004
1005     /* set output geometry */
1006     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1007     pH264Dec->hMFCH264Handle.MFCOutputColorType = bufferConf.eColorFormat = VIDEO_COLORFORMAT_NV12;
1008     if (pOutbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1009         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1010         ret = OMX_ErrorInsufficientResources;
1011         goto EXIT;
1012     }
1013
1014     /* input buffer enqueue for header parsing */
1015     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d", oneFrameSize);
1016     if (pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
1017                         (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
1018         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer for header parsing");
1019 //        ret = OMX_ErrorInsufficientResources;
1020         ret = (OMX_ERRORTYPE)OMX_ErrorCodecInit;
1021         goto EXIT;
1022     }
1023
1024     /* start header parsing */
1025     if (pInbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1026         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
1027         ret = OMX_ErrorCodecInit;
1028         goto EXIT;
1029     }
1030
1031     ret = H264CodecCheckResolutionChange(pOMXComponent);
1032     if (ret != OMX_ErrorNone) {
1033         ret = OMX_ErrorCodecInit;
1034         goto EXIT;
1035     }
1036
1037     Exynos_OSAL_SleepMillisec(0);
1038     ret = OMX_ErrorInputDataDecodeYet;
1039
1040 #ifdef USE_IMMEDIATE_DISPLAY
1041     /* Set Immediately display for I Frame*/
1042    pDecOps->Set_ImmediateDisplay(hMFCHandle);
1043 #endif
1044
1045 EXIT:
1046     H264CodecStop(pOMXComponent, INPUT_PORT_INDEX);
1047     FunctionOut();
1048
1049     return ret;
1050 }
1051
1052 OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
1053 {
1054     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1055     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1056     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1057     EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1058     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1059     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1060
1061     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1062     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1063
1064     int i, nOutbufs;
1065
1066     FunctionIn();
1067
1068     /* get dpb count */
1069     nOutbufs = pH264Dec->hMFCH264Handle.maxDPBNum;
1070
1071     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1072         /* should be done before prepare output buffer */
1073         if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
1074             ret = OMX_ErrorInsufficientResources;
1075             goto EXIT;
1076         }
1077     }
1078
1079     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE
1080         ||pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE)
1081         pOutbufOps->Set_Shareable(hMFCHandle);
1082
1083     if (pOutbufOps->Setup(hMFCHandle, nOutbufs) != VIDEO_ERROR_NONE) {
1084         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1085         ret = OMX_ErrorInsufficientResources;
1086         goto EXIT;
1087     }
1088
1089     ExynosVideoPlane planes[MFC_OUTPUT_BUFFER_PLANE];
1090     OMX_U32 nAllocLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1091     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1092     int plane;
1093
1094     nAllocLen[0] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
1095                         pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight);
1096     nAllocLen[1] = calc_plane(pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth,
1097                         pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight >> 1);
1098
1099     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1100         pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1101         H264CodecDstAllocCodecBuffers(pOMXComponent, nOutbufs);
1102         H264CodecDstRegistCodecBuffers(pOMXComponent, nOutbufs);
1103     } else if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
1104         pH264Dec->hMFCH264Handle.bShareableBuf == OMX_FALSE) {
1105
1106         /* Register output buffer */
1107         for (i = 0; i < nOutbufs; i++) {
1108             int plane;
1109             OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0, 0};
1110             ExynosVideoBuffer *pBuffer = NULL;
1111             pVideoDec->pMFCDecOutputBuffer[i] = (CODEC_DEC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1112             Exynos_OSAL_Memset(pVideoDec->pMFCDecOutputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1113
1114             if (pOutbufOps->Get_Buffer) {
1115                  if (pOutbufOps->Get_Buffer(pH264Dec->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
1116                      Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info");
1117                      ret = OMX_ErrorInsufficientResources;
1118                      goto EXIT;
1119                  }
1120             }
1121
1122             for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1123                 pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
1124                 pVideoDec->pMFCDecOutputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
1125                 pVideoDec->pMFCDecOutputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
1126             }
1127
1128             pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoDec->pMFCDecOutputBuffer[i]->pVirAddr,
1129                             (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1130         }
1131     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1132 #ifdef USE_PB
1133         if (pExynosOutputPort->bIsPBEnabled == OMX_TRUE) {
1134             for (i = 0; i < pExynosOutputPort->assignedBufferNum; i++) {
1135                 for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
1136                     planes[plane].fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[plane];
1137                     planes[plane].addr = pExynosOutputPort->extendBufferHeader[i].pYUVBuf[plane];
1138                     planes[plane].tbm_bo = pExynosOutputPort->extendBufferHeader[i].tbm_bo[plane];
1139                     planes[plane].allocSize = nAllocLen[plane];
1140                 }
1141
1142                 if (pOutbufOps->Register(hMFCHandle, planes, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1143                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1144                     ret = OMX_ErrorInsufficientResources;
1145                     goto EXIT;
1146                 }
1147                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pExynosOutputPort->extendBufferHeader[i].pYUVBuf,
1148                                (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1149             }
1150         } else {
1151             ret = OMX_ErrorNotImplemented;
1152             goto EXIT;
1153         }
1154 #else
1155         ret = OMX_ErrorNotImplemented;
1156         goto EXIT;
1157 #endif
1158         /* Waiting for DPB buffer setup to be completed,
1159         *   valid only for share mode
1160         */
1161         if (pDecOps->Enable_DecodeWait != NULL)
1162             pDecOps->Enable_DecodeWait(hMFCHandle);
1163
1164     }
1165
1166     if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1167         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1168         ret = OMX_ErrorInsufficientResources;
1169         goto EXIT;
1170     }
1171
1172     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1173         H264CodecStop(pOMXComponent, OUTPUT_PORT_INDEX);
1174     }
1175     pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
1176
1177     ret = OMX_ErrorNone;
1178
1179 EXIT:
1180     FunctionOut();
1181
1182     return ret;
1183 }
1184
1185 OMX_ERRORTYPE H264CodecCheckResolutionChange(OMX_COMPONENTTYPE *pOMXComponent)
1186 {
1187     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1188     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1189     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1190     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1191     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
1192     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1193     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1194
1195     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
1196     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
1197
1198     FunctionIn();
1199
1200     /* get geometry for output */
1201     Exynos_OSAL_Memset(&pH264Dec->hMFCH264Handle.codecOutbufConf, 0, sizeof(ExynosVideoGeometry));
1202     if (pOutbufOps->Get_Geometry(hMFCHandle, &pH264Dec->hMFCH264Handle.codecOutbufConf) != VIDEO_ERROR_NONE) {
1203         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get geometry for parsed header info");
1204         ret = OMX_ErrorInsufficientResources;
1205         goto EXIT;
1206     }
1207
1208     /* get dpb count */
1209     pH264Dec->hMFCH264Handle.maxDPBNum = pDecOps->Get_ActualBufferCount(hMFCHandle);
1210     if (pVideoDec->bThumbnailMode == OMX_FALSE)
1211         pH264Dec->hMFCH264Handle.maxDPBNum += EXTRA_DPB_NUM;
1212     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "H264CodecCheckResolutionChange H264CodecSetup nOutbufs: %d", pH264Dec->hMFCH264Handle.maxDPBNum);
1213
1214     pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
1215
1216     pExynosOutputPort->cropRectangle.nTop = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nTop;
1217     pExynosOutputPort->cropRectangle.nLeft = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nLeft;
1218     pExynosOutputPort->cropRectangle.nWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth;
1219     pExynosOutputPort->cropRectangle.nHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight;
1220
1221     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1222         if ((pVideoDec->bDRCProcessing) ||
1223             (pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
1224             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight)) {
1225             pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1226             pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1227             pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
1228             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
1229
1230             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1231                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1232             }
1233             Exynos_UpdateFrameSize(pOMXComponent);
1234             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1235
1236             /** Send Port Settings changed call back **/
1237         (*(pExynosComponent->pCallbacks->EventHandler))
1238             (pOMXComponent,
1239              pExynosComponent->callbackData,
1240              OMX_EventPortSettingsChanged, /* The command was completed */
1241              OMX_DirOutput, /* This is the port index */
1242                  0,
1243              NULL);
1244         }
1245     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1246 #ifndef TIZEN_FEATURE_E3250
1247         /* The input port information has already been updated */
1248         if ((pExynosInputPort->portDefinition.format.video.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth) ||
1249             (pExynosInputPort->portDefinition.format.video.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight) ||
1250             (pExynosOutputPort->portDefinition.nBufferCountActual != pH264Dec->hMFCH264Handle.maxDPBNum)) {
1251             pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1252             pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1253             pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
1254             pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
1255 #endif
1256             if (pVideoDec->bDRCProcessing == OMX_TRUE) {
1257                 pVideoDec->nDRCSavedBufferCount = pExynosOutputPort->portDefinition.nBufferCountActual;
1258             }
1259 #ifdef TIZEN_FEATURE_E3250
1260             pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum;
1261             pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum;
1262 #else
1263             pExynosOutputPort->portDefinition.nBufferCountActual = pH264Dec->hMFCH264Handle.maxDPBNum - 4;
1264             pExynosOutputPort->portDefinition.nBufferCountMin = pH264Dec->hMFCH264Handle.maxDPBNum - 4;
1265 #endif
1266             Exynos_UpdateFrameSize(pOMXComponent);
1267             pExynosOutputPort->exceptionFlag = NEED_PORT_DISABLE;
1268
1269             /** Send Port Settings changed call back **/
1270             (*(pExynosComponent->pCallbacks->EventHandler))
1271                 (pOMXComponent,
1272                  pExynosComponent->callbackData,
1273                  OMX_EventPortSettingsChanged, /* The command was completed */
1274                  OMX_DirOutput, /* This is the port index */
1275                  0,
1276                  NULL);
1277 #ifndef TIZEN_FEATURE_E3250
1278         }
1279 #endif
1280     }
1281
1282     if (((pVideoDec->bDRCProcessing) && (pExynosOutputPort->bufferProcessType & BUFFER_COPY)) ||
1283         (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nWidth) ||
1284         (pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight != pH264Dec->hMFCH264Handle.codecOutbufConf.cropRect.nHeight)) {
1285         /* Check Crop */
1286         pExynosInputPort->portDefinition.format.video.nFrameWidth = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth;
1287         pExynosInputPort->portDefinition.format.video.nFrameHeight = pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight;
1288         pExynosInputPort->portDefinition.format.video.nStride = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameWidth + 15) & (~15));
1289         pExynosInputPort->portDefinition.format.video.nSliceHeight = ((pH264Dec->hMFCH264Handle.codecOutbufConf.nFrameHeight + 15) & (~15));
1290         Exynos_UpdateFrameSize(pOMXComponent);
1291
1292         /** Send crop info call back **/
1293         (*(pExynosComponent->pCallbacks->EventHandler))
1294             (pOMXComponent,
1295              pExynosComponent->callbackData,
1296              OMX_EventPortSettingsChanged, /* The command was completed */
1297              OMX_DirOutput, /* This is the port index */
1298              OMX_IndexConfigCommonOutputCrop,
1299              NULL);
1300     }
1301
1302     ret = OMX_ErrorNone;
1303
1304 EXIT:
1305     FunctionOut();
1306
1307     return ret;
1308 }
1309
1310 OMX_ERRORTYPE Exynos_H264Dec_GetParameter(
1311     OMX_IN OMX_HANDLETYPE hComponent,
1312     OMX_IN OMX_INDEXTYPE  nParamIndex,
1313     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1314 {
1315     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1316     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1317     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1318
1319     FunctionIn();
1320
1321     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1322         ret = OMX_ErrorBadParameter;
1323         goto EXIT;
1324     }
1325     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1326     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1327     if (ret != OMX_ErrorNone) {
1328         goto EXIT;
1329     }
1330     if (pOMXComponent->pComponentPrivate == NULL) {
1331         ret = OMX_ErrorBadParameter;
1332         goto EXIT;
1333     }
1334
1335     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1336     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1337         ret = OMX_ErrorInvalidState;
1338         goto EXIT;
1339     }
1340
1341     switch (nParamIndex) {
1342     case OMX_IndexParamVideoAvc:
1343     {
1344         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1345         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1346         EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
1347
1348         ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1349         if (ret != OMX_ErrorNone) {
1350             goto EXIT;
1351         }
1352
1353         if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1354             ret = OMX_ErrorBadPortIndex;
1355             goto EXIT;
1356         }
1357
1358         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1359         pSrcAVCComponent = &pH264Dec->AVCComponent[pDstAVCComponent->nPortIndex];
1360
1361         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1362     }
1363         break;
1364     case OMX_IndexParamStandardComponentRole:
1365     {
1366         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1367         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1368         if (ret != OMX_ErrorNone) {
1369             goto EXIT;
1370         }
1371
1372         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
1373     }
1374         break;
1375     case OMX_IndexParamVideoProfileLevelQuerySupported:
1376     {
1377         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1378         EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1379         OMX_U32 maxProfileLevelNum = 0;
1380
1381         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1382         if (ret != OMX_ErrorNone) {
1383             goto EXIT;
1384         }
1385
1386         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1387             ret = OMX_ErrorBadPortIndex;
1388             goto EXIT;
1389         }
1390
1391         pProfileLevel = supportedAVCProfileLevels;
1392         maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1393
1394         if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1395             ret = OMX_ErrorNoMore;
1396             goto EXIT;
1397         }
1398
1399         pProfileLevel += pDstProfileLevel->nProfileIndex;
1400         pDstProfileLevel->eProfile = pProfileLevel->profile;
1401         pDstProfileLevel->eLevel = pProfileLevel->level;
1402     }
1403         break;
1404     case OMX_IndexParamVideoProfileLevelCurrent:
1405     {
1406         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1407         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1408         EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
1409
1410         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1411         if (ret != OMX_ErrorNone) {
1412             goto EXIT;
1413         }
1414
1415         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1416             ret = OMX_ErrorBadPortIndex;
1417             goto EXIT;
1418         }
1419
1420         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1421         pSrcAVCComponent = &pH264Dec->AVCComponent[pDstProfileLevel->nPortIndex];
1422
1423         pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1424         pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1425     }
1426         break;
1427     case OMX_IndexParamVideoErrorCorrection:
1428     {
1429         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1430         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1431         EXYNOS_H264DEC_HANDLE      *pH264Dec = NULL;
1432
1433         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1434         if (ret != OMX_ErrorNone) {
1435             goto EXIT;
1436         }
1437
1438         if (pDstErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1439             ret = OMX_ErrorBadPortIndex;
1440             goto EXIT;
1441         }
1442
1443         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1444         pSrcErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1445
1446         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1447         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1448         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1449         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1450         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1451     }
1452         break;
1453     default:
1454         ret = Exynos_OMX_VideoDecodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1455         break;
1456     }
1457 EXIT:
1458     FunctionOut();
1459
1460     return ret;
1461 }
1462
1463 OMX_ERRORTYPE Exynos_H264Dec_SetParameter(
1464     OMX_IN OMX_HANDLETYPE hComponent,
1465     OMX_IN OMX_INDEXTYPE  nIndex,
1466     OMX_IN OMX_PTR        pComponentParameterStructure)
1467 {
1468     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1469     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1470     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1471
1472     FunctionIn();
1473
1474     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1475         ret = OMX_ErrorBadParameter;
1476         goto EXIT;
1477     }
1478     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1479     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1480     if (ret != OMX_ErrorNone) {
1481         goto EXIT;
1482     }
1483     if (pOMXComponent->pComponentPrivate == NULL) {
1484         ret = OMX_ErrorBadParameter;
1485         goto EXIT;
1486     }
1487
1488     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1489     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1490         ret = OMX_ErrorInvalidState;
1491         goto EXIT;
1492     }
1493
1494     switch (nIndex) {
1495     case OMX_IndexParamVideoAvc:
1496     {
1497         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1498         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1499         EXYNOS_H264DEC_HANDLE   *pH264Dec = NULL;
1500
1501         ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1502         if (ret != OMX_ErrorNone) {
1503             goto EXIT;
1504         }
1505
1506         if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1507             ret = OMX_ErrorBadPortIndex;
1508             goto EXIT;
1509         }
1510
1511         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1512         pDstAVCComponent = &pH264Dec->AVCComponent[pSrcAVCComponent->nPortIndex];
1513
1514         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1515     }
1516         break;
1517     case OMX_IndexParamStandardComponentRole:
1518     {
1519         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1520
1521         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1522         if (ret != OMX_ErrorNone) {
1523             goto EXIT;
1524         }
1525
1526         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1527             ret = OMX_ErrorIncorrectStateOperation;
1528             goto EXIT;
1529         }
1530
1531         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE)) {
1532             pExynosComponent->pExynosPort[INPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1533         } else {
1534             ret = OMX_ErrorBadParameter;
1535             goto EXIT;
1536         }
1537     }
1538         break;
1539     case OMX_IndexParamPortDefinition:
1540     {
1541         OMX_PARAM_PORTDEFINITIONTYPE *pPortDefinition = (OMX_PARAM_PORTDEFINITIONTYPE *)pComponentParameterStructure;
1542         OMX_U32                       portIndex       = pPortDefinition->nPortIndex;
1543         EXYNOS_OMX_BASEPORT          *pExynosPort;
1544         OMX_U32 width, height, size;
1545         OMX_U32 realWidth, realHeight;
1546         OMX_PARAM_PORTDEFINITIONTYPE  portDefinition_backup;
1547
1548         if (portIndex >= pExynosComponent->portParam.nPorts) {
1549             ret = OMX_ErrorBadPortIndex;
1550             goto EXIT;
1551         }
1552         ret = Exynos_OMX_Check_SizeVersion(pPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
1553         if (ret != OMX_ErrorNone) {
1554             goto EXIT;
1555         }
1556
1557         pExynosPort = &pExynosComponent->pExynosPort[portIndex];
1558
1559         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1560             if (pExynosPort->portDefinition.bEnabled == OMX_TRUE) {
1561                 ret = OMX_ErrorIncorrectStateOperation;
1562                 goto EXIT;
1563             }
1564         }
1565         if (pPortDefinition->nBufferCountActual < pExynosPort->portDefinition.nBufferCountMin) {
1566             ret = OMX_ErrorBadParameter;
1567             goto EXIT;
1568         }
1569
1570         Exynos_OSAL_Memcpy(&portDefinition_backup, &pExynosPort->portDefinition, pPortDefinition->nSize);
1571         Exynos_OSAL_Memcpy(&pExynosPort->portDefinition, pPortDefinition, pPortDefinition->nSize);
1572         RESTORE_READONLYPARAMETERS_OMX_PARAM_PORTDEFINITIONTYPE(&pExynosPort->portDefinition,&portDefinition_backup);
1573
1574         realWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1575         realHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1576         width = ((realWidth + 15) & (~15));
1577         height = ((realHeight + 15) & (~15));
1578         size = (width * height * 3) / 2;
1579         pExynosPort->portDefinition.format.video.nStride = width;
1580         pExynosPort->portDefinition.format.video.nSliceHeight = height;
1581         pExynosPort->portDefinition.nBufferSize = (size > pExynosPort->portDefinition.nBufferSize) ? size : pExynosPort->portDefinition.nBufferSize;
1582
1583         if (portIndex == INPUT_PORT_INDEX) {
1584             EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1585             pExynosOutputPort->portDefinition.format.video.nFrameWidth = pExynosPort->portDefinition.format.video.nFrameWidth;
1586             pExynosOutputPort->portDefinition.format.video.nFrameHeight = pExynosPort->portDefinition.format.video.nFrameHeight;
1587             pExynosOutputPort->portDefinition.format.video.nStride = width;
1588             pExynosOutputPort->portDefinition.format.video.nSliceHeight = height;
1589
1590             switch ((int)pExynosOutputPort->portDefinition.format.video.eColorFormat) {
1591             case OMX_COLOR_FormatYUV420Planar:
1592             case OMX_COLOR_FormatYUV420SemiPlanar:
1593                 pExynosOutputPort->portDefinition.nBufferSize = (width * height * 3) / 2;
1594                 break;
1595 #ifdef TIZEN_FEATURE_E3250 /* NV12 fd */
1596             case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd:
1597             case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
1598                 pExynosOutputPort->portDefinition.nBufferSize = sizeof(MMVideoBuffer);
1599                 break;
1600 #endif
1601             case OMX_SEC_COLOR_FormatNV12Tiled:
1602                 pExynosOutputPort->portDefinition.nBufferSize =
1603                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1604                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1605                 break;
1606             default:
1607                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Color format is not support!! use default YUV size!!");
1608                 ret = OMX_ErrorUnsupportedSetting;
1609                 break;
1610             }
1611
1612             if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1613                 pExynosOutputPort->portDefinition.nBufferSize =
1614                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight) +
1615                     calc_plane(pExynosPort->portDefinition.format.video.nFrameWidth, pExynosOutputPort->portDefinition.format.video.nFrameHeight >> 1);
1616             }
1617         }
1618     }
1619         break;
1620     case OMX_IndexParamVideoProfileLevelCurrent:
1621     {
1622         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1623         OMX_VIDEO_PARAM_AVCTYPE          *pDstAVCComponent = NULL;
1624         EXYNOS_H264DEC_HANDLE            *pH264Dec = NULL;
1625
1626         ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1627         if (ret != OMX_ErrorNone)
1628             goto EXIT;
1629
1630         if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1631             ret = OMX_ErrorBadPortIndex;
1632             goto EXIT;
1633         }
1634
1635         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1636
1637         pDstAVCComponent = &pH264Dec->AVCComponent[pSrcProfileLevel->nPortIndex];
1638         pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1639         pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1640     }
1641         break;
1642     case OMX_IndexParamVideoErrorCorrection:
1643     {
1644         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1645         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1646         EXYNOS_H264DEC_HANDLE               *pH264Dec = NULL;
1647
1648         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1649         if (ret != OMX_ErrorNone) {
1650             goto EXIT;
1651         }
1652
1653         if (pSrcErrorCorrectionType->nPortIndex != INPUT_PORT_INDEX) {
1654             ret = OMX_ErrorBadPortIndex;
1655             goto EXIT;
1656         }
1657
1658         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1659         pDstErrorCorrectionType = &pH264Dec->errorCorrectionType[INPUT_PORT_INDEX];
1660
1661         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1662         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1663         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1664         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1665         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1666     }
1667         break;
1668     default:
1669         ret = Exynos_OMX_VideoDecodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1670         break;
1671     }
1672 EXIT:
1673     FunctionOut();
1674
1675     return ret;
1676 }
1677
1678 OMX_ERRORTYPE Exynos_H264Dec_GetConfig(
1679     OMX_HANDLETYPE hComponent,
1680     OMX_INDEXTYPE  nIndex,
1681     OMX_PTR        pComponentConfigStructure)
1682 {
1683     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1684     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1685     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1686
1687     FunctionIn();
1688
1689     if (hComponent == NULL) {
1690         ret = OMX_ErrorBadParameter;
1691         goto EXIT;
1692     }
1693     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1694     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1695     if (ret != OMX_ErrorNone) {
1696         goto EXIT;
1697     }
1698     if (pOMXComponent->pComponentPrivate == NULL) {
1699         ret = OMX_ErrorBadParameter;
1700         goto EXIT;
1701     }
1702     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1703     if (pComponentConfigStructure == NULL) {
1704         ret = OMX_ErrorBadParameter;
1705         goto EXIT;
1706     }
1707     if (pExynosComponent->currentState == OMX_StateInvalid) {
1708         ret = OMX_ErrorInvalidState;
1709         goto EXIT;
1710     }
1711
1712     switch (nIndex) {
1713     case OMX_IndexConfigCommonOutputCrop:
1714     {
1715         EXYNOS_H264DEC_HANDLE  *pH264Dec = NULL;
1716         OMX_CONFIG_RECTTYPE    *pSrcRectType = NULL;
1717         OMX_CONFIG_RECTTYPE    *pDstRectType = NULL;
1718         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1719
1720         if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1721             ret = OMX_ErrorNotReady;
1722             break;
1723         }
1724
1725         pDstRectType = (OMX_CONFIG_RECTTYPE *)pComponentConfigStructure;
1726
1727         if ((pDstRectType->nPortIndex != INPUT_PORT_INDEX) &&
1728             (pDstRectType->nPortIndex != OUTPUT_PORT_INDEX)) {
1729             ret = OMX_ErrorBadPortIndex;
1730             goto EXIT;
1731         }
1732
1733         EXYNOS_OMX_BASEPORT *pExynosPort = &pExynosComponent->pExynosPort[pDstRectType->nPortIndex];
1734
1735         pSrcRectType = &(pExynosPort->cropRectangle);
1736
1737         pDstRectType->nTop = pSrcRectType->nTop;
1738         pDstRectType->nLeft = pSrcRectType->nLeft;
1739         pDstRectType->nHeight = pSrcRectType->nHeight;
1740         pDstRectType->nWidth = pSrcRectType->nWidth;
1741     }
1742         break;
1743 #ifdef USE_S3D_SUPPORT
1744     case OMX_IndexVendorS3DMode:
1745     {
1746         EXYNOS_H264DEC_HANDLE  *pH264Dec = NULL;
1747         OMX_U32                *pS3DMode = NULL;
1748         pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1749
1750         pS3DMode = (OMX_U32 *)pComponentConfigStructure;
1751         *pS3DMode = (OMX_U32) pH264Dec->hMFCH264Handle.S3DFPArgmtType;
1752     }
1753         break;
1754 #endif
1755     default:
1756         ret = Exynos_OMX_VideoDecodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1757         break;
1758     }
1759
1760 EXIT:
1761     FunctionOut();
1762
1763     return ret;
1764 }
1765
1766 OMX_ERRORTYPE Exynos_H264Dec_SetConfig(
1767     OMX_HANDLETYPE hComponent,
1768     OMX_INDEXTYPE  nIndex,
1769     OMX_PTR        pComponentConfigStructure)
1770 {
1771     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1772     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1773     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1774
1775     FunctionIn();
1776
1777     if (hComponent == NULL) {
1778         ret = OMX_ErrorBadParameter;
1779         goto EXIT;
1780     }
1781     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1782     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1783     if (ret != OMX_ErrorNone) {
1784         goto EXIT;
1785     }
1786     if (pOMXComponent->pComponentPrivate == NULL) {
1787         ret = OMX_ErrorBadParameter;
1788         goto EXIT;
1789     }
1790     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1791     if (pComponentConfigStructure == NULL) {
1792         ret = OMX_ErrorBadParameter;
1793         goto EXIT;
1794     }
1795     if (pExynosComponent->currentState == OMX_StateInvalid) {
1796         ret = OMX_ErrorInvalidState;
1797         goto EXIT;
1798     }
1799
1800     switch (nIndex) {
1801     default:
1802         ret = Exynos_OMX_VideoDecodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1803         break;
1804     }
1805
1806 EXIT:
1807     FunctionOut();
1808
1809     return ret;
1810 }
1811
1812 OMX_ERRORTYPE Exynos_H264Dec_GetExtensionIndex(
1813     OMX_IN OMX_HANDLETYPE  hComponent,
1814     OMX_IN OMX_STRING      cParameterName,
1815     OMX_OUT OMX_INDEXTYPE *pIndexType)
1816 {
1817     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1818     OMX_COMPONENTTYPE        *pOMXComponent     = NULL;
1819     EXYNOS_OMX_BASECOMPONENT *pExynosComponent  = NULL;
1820
1821     FunctionIn();
1822
1823     if (hComponent == NULL) {
1824         ret = OMX_ErrorBadParameter;
1825         goto EXIT;
1826     }
1827     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1828     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1829     if (ret != OMX_ErrorNone) {
1830         goto EXIT;
1831     }
1832     if (pOMXComponent->pComponentPrivate == NULL) {
1833         ret = OMX_ErrorBadParameter;
1834         goto EXIT;
1835     }
1836     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1837     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1838         ret = OMX_ErrorBadParameter;
1839         goto EXIT;
1840     }
1841     if (pExynosComponent->currentState == OMX_StateInvalid) {
1842         ret = OMX_ErrorInvalidState;
1843         goto EXIT;
1844     }
1845
1846     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENABLE_THUMBNAIL) == 0) {
1847         *pIndexType = OMX_IndexVendorThumbnailMode;
1848         ret = OMX_ErrorNone;
1849     }
1850 #ifdef USE_S3D_SUPPORT
1851     else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_GET_S3D) == 0) {
1852         *pIndexType = OMX_IndexVendorS3DMode;
1853         ret = OMX_ErrorNone;
1854     }
1855 #endif
1856     else {
1857         ret = Exynos_OMX_VideoDecodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1858     }
1859
1860 EXIT:
1861     FunctionOut();
1862
1863     return ret;
1864 }
1865
1866 OMX_ERRORTYPE Exynos_H264Dec_ComponentRoleEnum(
1867     OMX_HANDLETYPE hComponent,
1868     OMX_U8        *cRole,
1869     OMX_U32        nIndex)
1870 {
1871     OMX_ERRORTYPE             ret               = OMX_ErrorNone;
1872
1873     FunctionIn();
1874
1875     if ((hComponent == NULL) || (cRole == NULL)) {
1876         ret = OMX_ErrorBadParameter;
1877         goto EXIT;
1878     }
1879     if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1880         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_DEC_ROLE);
1881         ret = OMX_ErrorNone;
1882     } else {
1883         ret = OMX_ErrorNoMore;
1884     }
1885
1886 EXIT:
1887     FunctionOut();
1888
1889     return ret;
1890 }
1891
1892 /* MFC Init */
1893 OMX_ERRORTYPE Exynos_H264Dec_Init(OMX_COMPONENTTYPE *pOMXComponent)
1894 {
1895     OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
1896     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1897     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
1898     EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1899     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1900     EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
1901
1902     CSC_METHOD csc_method = CSC_METHOD_SW;
1903     int i, plane;
1904
1905     FunctionIn();
1906
1907     pH264Dec->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1908     pH264Dec->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
1909     pExynosComponent->bUseFlagEOF = OMX_TRUE;
1910     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1911
1912     /* H.264 Codec Open */
1913     ret = H264CodecOpen(pH264Dec);
1914     if (ret != OMX_ErrorNone) {
1915         goto EXIT;
1916     }
1917
1918     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1919         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1920         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1921
1922         if (pH264Dec->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1923             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1924                 pVideoDec->pMFCDecInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_DEC_BUFFER));
1925                 Exynos_OSAL_Memset(pVideoDec->pMFCDecInputBuffer[i], 0, sizeof(CODEC_DEC_BUFFER));
1926                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]: 0x%x", i, pVideoDec->pMFCDecInputBuffer[i]);
1927
1928             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1929             /* Use ION Allocator */
1930                 pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoDec->hSharedMemory, DEFAULT_MFC_INPUT_BUFFER_SIZE, NORMAL_MEMORY);
1931                 pVideoDec->pMFCDecInputBuffer[i]->fd[plane] = Exynos_OSAL_SharedMemory_VirtToION(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1932                 pVideoDec->pMFCDecInputBuffer[i]->bufferSize[plane] = DEFAULT_MFC_INPUT_BUFFER_SIZE;
1933             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
1934                 if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] == NULL) {
1935                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1936                 ret = OMX_ErrorInsufficientResources;
1937                 goto EXIT;
1938             }
1939                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoDec->pMFCDecInputBuffer[%d]->pVirAddr[%d]: 0x%x", i, plane, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
1940             }
1941
1942                 Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoDec->pMFCDecInputBuffer[i]);
1943             }
1944         } else {
1945                 ret = H264CodecSrcInit(pOMXComponent);
1946                 if (ret != OMX_ErrorNone)
1947                     goto EXIT;
1948         }
1949     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1950         /*************/
1951         /*    TBD    */
1952         /*************/
1953         /* Does not require any actions. */
1954     }
1955
1956     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1957         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1958         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1959     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1960         /*************/
1961         /*    TBD    */
1962         /*************/
1963         /* Does not require any actions. */
1964     }
1965
1966     pH264Dec->bSourceStart = OMX_FALSE;
1967     Exynos_OSAL_SignalCreate(&pH264Dec->hSourceStartEvent);
1968     pH264Dec->bDestinationStart = OMX_FALSE;
1969     Exynos_OSAL_SignalCreate(&pH264Dec->hDestinationStartEvent);
1970
1971     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1972     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1973     pH264Dec->hMFCH264Handle.indexTimestamp = 0;
1974     pH264Dec->hMFCH264Handle.outputIndexTimestamp = 0;
1975
1976     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1977
1978 #if 0//defined(USE_CSC_GSCALER)
1979     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1980 #endif
1981     if (pVideoDec->bDRMPlayerMode == OMX_TRUE) {
1982         pVideoDec->csc_handle = csc_init(CSC_METHOD_HW);
1983         csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_FIXED_NODE, 2);
1984         csc_set_hw_property(pVideoDec->csc_handle, CSC_HW_PROPERTY_MODE_DRM, pVideoDec->bDRMPlayerMode);
1985     } else {
1986         pVideoDec->csc_handle = csc_init(csc_method);
1987     }
1988
1989     if (pVideoDec->csc_handle == NULL) {
1990         ret = OMX_ErrorInsufficientResources;
1991         goto EXIT;
1992     }
1993     pVideoDec->csc_set_format = OMX_FALSE;
1994
1995 EXIT:
1996     FunctionOut();
1997
1998     return ret;
1999 }
2000
2001 /* MFC Terminate */
2002 OMX_ERRORTYPE Exynos_H264Dec_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
2003 {
2004     OMX_ERRORTYPE                  ret               = OMX_ErrorNone;
2005     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent  = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2006     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec         = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2007     EXYNOS_OMX_BASEPORT           *pExynosInputPort  = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2008     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2009     EXYNOS_H264DEC_HANDLE         *pH264Dec          = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2010
2011     int i;
2012
2013     FunctionIn();
2014
2015     if (pVideoDec->csc_handle != NULL) {
2016         csc_deinit(pVideoDec->csc_handle);
2017         pVideoDec->csc_handle = NULL;
2018     }
2019
2020     Exynos_OSAL_SignalTerminate(pH264Dec->hDestinationStartEvent);
2021     pH264Dec->hDestinationStartEvent = NULL;
2022     pH264Dec->bDestinationStart = OMX_FALSE;
2023     Exynos_OSAL_SignalTerminate(pH264Dec->hSourceStartEvent);
2024     pH264Dec->hSourceStartEvent = NULL;
2025     pH264Dec->bSourceStart = OMX_FALSE;
2026
2027     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2028         H264CodecDstFreeCodecBuffers(pOMXComponent);
2029
2030         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
2031         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
2032     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2033         /*************/
2034         /*    TBD    */
2035         /*************/
2036         /* Does not require any actions. */
2037     }
2038
2039     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2040         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
2041             if (pVideoDec->pMFCDecInputBuffer[i] != NULL) {
2042 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2043                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2044                     if (pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane] != NULL)
2045                         Exynos_OSAL_SharedMemory_Free(pVideoDec->hSharedMemory, pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[plane]);
2046                 }
2047 #endif
2048                 Exynos_OSAL_Free(pVideoDec->pMFCDecInputBuffer[i]);
2049                 pVideoDec->pMFCDecInputBuffer[i] = NULL;
2050             }
2051         }
2052
2053         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
2054         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
2055     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
2056         /*************/
2057         /*    TBD    */
2058         /*************/
2059         /* Does not require any actions. */
2060     }
2061     H264CodecClose(pH264Dec);
2062
2063
2064     FunctionOut();
2065
2066     return ret;
2067 }
2068
2069 OMX_ERRORTYPE Exynos_H264Dec_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2070 {
2071     OMX_ERRORTYPE               ret = OMX_ErrorNone;
2072     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2073     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2074     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2075     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2076     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
2077     OMX_BOOL bInStartCode = OMX_FALSE;
2078     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
2079     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
2080     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2081
2082     FunctionIn();
2083
2084     if (pH264Dec->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
2085         ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
2086         goto EXIT;
2087     }
2088     if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
2089         ret = H264CodecDstSetup(pOMXComponent);
2090     }
2091
2092     if (((pVideoDec->bDRMPlayerMode == OMX_TRUE) ||
2093           ((bInStartCode = Check_H264_StartCode(pSrcInputData->buffer.singlePlaneBuffer.dataBuffer, oneFrameSize)) == OMX_TRUE)) ||
2094         ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2095         pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
2096         pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
2097         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);
2098         pDecOps->Set_FrameTag(hMFCHandle, pH264Dec->hMFCH264Handle.indexTimestamp);
2099         pH264Dec->hMFCH264Handle.indexTimestamp++;
2100         pH264Dec->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
2101
2102 #ifdef USE_IMMEDIATE_DISPLAY
2103     /* Set Immediately display for I Frame*/
2104
2105         if (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp == OMX_TRUE) {
2106             if ( pExynosComponent->checkTimeStamp.bImmediateDisplay == OMX_FALSE) {
2107                 /* Enable Immediately display After seek*/
2108                 pDecOps->Set_ImmediateDisplay(hMFCHandle);
2109                 pExynosComponent->checkTimeStamp.bImmediateDisplay = OMX_TRUE;
2110             }
2111         }
2112 #endif
2113
2114         /*Add First Frame check : */
2115         if((pSrcInputData->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG)
2116         {
2117             Exynos_OSAL_Log(EXYNOS_LOG_TRACE,"Video First Frame Coming");
2118         }
2119
2120         /* queue work for input buffer */
2121         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "oneFrameSize: %d, bufferHeader: 0x%x, dataBuffer: 0x%x", oneFrameSize, pSrcInputData->bufferHeader, pSrcInputData->buffer.singlePlaneBuffer.dataBuffer);
2122         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)&pSrcInputData->buffer.singlePlaneBuffer.dataBuffer,
2123                                     (unsigned int *)&oneFrameSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
2124         if (codecReturn != VIDEO_ERROR_NONE) {
2125             ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2126             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2127             goto EXIT;
2128         }
2129         H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
2130         if (pH264Dec->bSourceStart == OMX_FALSE) {
2131             pH264Dec->bSourceStart = OMX_TRUE;
2132             Exynos_OSAL_SignalSet(pH264Dec->hSourceStartEvent);
2133             Exynos_OSAL_SleepMillisec(0);
2134         }
2135         if (pH264Dec->bDestinationStart == OMX_FALSE) {
2136             pH264Dec->bDestinationStart = OMX_TRUE;
2137             Exynos_OSAL_SignalSet(pH264Dec->hDestinationStartEvent);
2138             Exynos_OSAL_SleepMillisec(0);
2139         }
2140          } else if (bInStartCode == OMX_FALSE) {
2141         ret = OMX_ErrorCorruptedFrame;
2142         goto EXIT;
2143     }
2144
2145     ret = OMX_ErrorNone;
2146
2147 EXIT:
2148     FunctionOut();
2149
2150     return ret;
2151 }
2152
2153 OMX_ERRORTYPE Exynos_H264Dec_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2154 {
2155     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2156     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2157     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2158     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2159     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2160     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2161     ExynosVideoDecBufferOps *pInbufOps  = pH264Dec->hMFCH264Handle.pInbufOps;
2162     ExynosVideoBuffer       *pVideoBuffer;
2163
2164     FunctionIn();
2165
2166     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
2167
2168     pSrcOutputData->dataLen       = 0;
2169     pSrcOutputData->usedDataLen   = 0;
2170     pSrcOutputData->remainDataLen = 0;
2171     pSrcOutputData->nFlags    = 0;
2172     pSrcOutputData->timeStamp = 0;
2173
2174     if (pVideoBuffer == NULL) {
2175         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2176         pSrcOutputData->allocSize  = 0;
2177         pSrcOutputData->pPrivate = NULL;
2178         pSrcOutputData->bufferHeader = NULL;
2179     } else {
2180         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2181         pSrcOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2182         pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize;
2183
2184         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2185             int i = 0;
2186             while (pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer != pVideoDec->pMFCDecInputBuffer[i]->pVirAddr[0]) {
2187                 i++;
2188                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2189                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Can not find buffer");
2190                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2191                     goto EXIT;
2192                 }
2193             }
2194             pVideoDec->pMFCDecInputBuffer[i]->dataSize = 0;
2195             pSrcOutputData->pPrivate = pVideoDec->pMFCDecInputBuffer[i];
2196         }
2197
2198         /* For Share Buffer */
2199         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2200     }
2201
2202     ret = OMX_ErrorNone;
2203
2204 EXIT:
2205     FunctionOut();
2206
2207     return ret;
2208 }
2209
2210 OMX_ERRORTYPE Exynos_H264Dec_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2211 {
2212     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2213     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2214     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2215     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2216     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2217     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2218     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2219     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0,};
2220     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2221
2222     FunctionIn();
2223
2224     if (pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0] == NULL) {
2225         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2226         ret = OMX_ErrorBadParameter;
2227         goto EXIT;
2228     }
2229
2230     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%s : %d => ADDR[0]: 0x%x, ADDR[1]: 0x%x", __FUNCTION__, __LINE__,
2231                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[0],
2232                                         pDstInputData->buffer.multiPlaneBuffer.dataBuffer[1]);
2233
2234     if ((pVideoDec->bDRCProcessing == OMX_TRUE) &&
2235         (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) &&
2236         (pExynosOutputPort->exceptionFlag == GENERAL_STATE)) {
2237         ret = H264CodecDstSetup(pOMXComponent);
2238         if (ret != OMX_ErrorNone) {
2239             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "DRC Reconfig H264CodecDstSetup Failed");
2240             goto EXIT;
2241         }
2242         pVideoDec->bDRCProcessing = OMX_FALSE;
2243     }
2244
2245     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pDstInputData->buffer.multiPlaneBuffer.dataBuffer,
2246                  (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2247
2248     if (codecReturn != VIDEO_ERROR_NONE) {
2249         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s : %d", __FUNCTION__, __LINE__);
2250         ret = (OMX_ERRORTYPE)OMX_ErrorCodecDecode;
2251         goto EXIT;
2252     }
2253     H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2254
2255     ret = OMX_ErrorNone;
2256
2257 EXIT:
2258     FunctionOut();
2259
2260     return ret;
2261 }
2262
2263 OMX_ERRORTYPE Exynos_H264Dec_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2264 {
2265     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2266     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2267     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2268     EXYNOS_H264DEC_HANDLE         *pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2269     void                          *hMFCHandle = pH264Dec->hMFCH264Handle.hMFCHandle;
2270     EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2271     ExynosVideoDecOps       *pDecOps    = pH264Dec->hMFCH264Handle.pDecOps;
2272     ExynosVideoDecBufferOps *pOutbufOps = pH264Dec->hMFCH264Handle.pOutbufOps;
2273     ExynosVideoBuffer       *pVideoBuffer;
2274     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2275     ExynosVideoGeometry *bufferGeometry;
2276     DECODE_CODEC_EXTRA_BUFFERINFO *pBufferInfo = NULL;
2277     OMX_S32 indexTimestamp = 0;
2278     int plane;
2279
2280     FunctionIn();
2281
2282     if (pH264Dec->bDestinationStart == OMX_FALSE) {
2283         ret = OMX_ErrorNone;
2284         goto EXIT;
2285     }
2286
2287     while (1) {
2288         pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle);
2289         if (pVideoBuffer == (ExynosVideoBuffer *)VIDEO_ERROR_DQBUF_EIO) {
2290             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "HW is not available");
2291             ret = OMX_ErrorHardware;
2292             goto EXIT;
2293         }
2294
2295         if (pVideoBuffer == NULL) {
2296             ret = OMX_ErrorNone;
2297             goto EXIT;
2298         }
2299         displayStatus = pVideoBuffer->displayStatus;
2300         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus: 0x%x", displayStatus);
2301
2302         if ((displayStatus == VIDEO_FRAME_STATUS_DISPLAY_DECODING) ||
2303             (displayStatus == VIDEO_FRAME_STATUS_DISPLAY_ONLY) ||
2304             (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2305             (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2306             (CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2307             if (pVideoBuffer != NULL) {
2308                 ret = OMX_ErrorNone;
2309                 break;
2310             } else {
2311                 ret = OMX_ErrorUndefined;
2312                 break;
2313             }
2314         }
2315     }
2316
2317     if (displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) {
2318         if (pVideoDec->bDRCProcessing != OMX_TRUE) {
2319             pExynosOutputPort->exceptionFlag = NEED_PORT_FLUSH;
2320             pVideoDec->bDRCProcessing = OMX_TRUE;
2321             H264CodecCheckResolutionChange(pOMXComponent);
2322             pVideoDec->csc_set_format = OMX_FALSE;
2323         }
2324         ret = OMX_ErrorNone;
2325         goto EXIT;
2326     }
2327
2328     pH264Dec->hMFCH264Handle.outputIndexTimestamp++;
2329     pH264Dec->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2330
2331     pDstOutputData->allocSize = pDstOutputData->dataLen = 0;
2332     for (plane = 0; plane < MFC_OUTPUT_BUFFER_PLANE; plane++) {
2333         pDstOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2334         pDstOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2335         pDstOutputData->buffer.multiPlaneBuffer.tbm_bo[plane] = pVideoBuffer->planes[plane].tbm_bo;
2336         pDstOutputData->allocSize += pVideoBuffer->planes[plane].allocSize;
2337         pDstOutputData->dataLen +=  pVideoBuffer->planes[plane].dataSize;
2338     }
2339     pDstOutputData->usedDataLen = 0;
2340     pDstOutputData->pPrivate = pVideoBuffer;
2341     /* For Share Buffer */
2342     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2343
2344     pBufferInfo = (DECODE_CODEC_EXTRA_BUFFERINFO *)pDstOutputData->extInfo;
2345     bufferGeometry = &pH264Dec->hMFCH264Handle.codecOutbufConf;
2346     pBufferInfo->imageWidth = bufferGeometry->nFrameWidth;
2347     pBufferInfo->imageHeight = bufferGeometry->nFrameHeight;
2348     switch (bufferGeometry->eColorFormat) {
2349     case VIDEO_COLORFORMAT_NV12:
2350 #ifdef TIZEN_FEATURE_E3250 /* NV12 fd */
2351         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2352 #else
2353         pBufferInfo->ColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2354 #endif
2355         break;
2356     case VIDEO_COLORFORMAT_NV12_TILED:
2357     default:
2358         pBufferInfo->ColorFormat = OMX_SEC_COLOR_FormatNV12Tiled;
2359         break;
2360     }
2361
2362 #ifdef USE_S3D_SUPPORT
2363     /* Check Whether frame packing information is available */
2364     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY &&
2365         pVideoDec->bThumbnailMode == OMX_FALSE &&
2366         pH264Dec->hMFCH264Handle.S3DFPArgmtType == OMX_SEC_FPARGMT_NONE) {
2367         H264CodecCheckFramePacking(pOMXComponent);
2368     }
2369 #endif
2370
2371     indexTimestamp = pDecOps->Get_FrameTag(hMFCHandle);
2372     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "out indexTimestamp: %d", indexTimestamp);
2373     if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2374         if ((pExynosComponent->checkTimeStamp.needSetStartTimeStamp != OMX_TRUE) &&
2375             (pExynosComponent->checkTimeStamp.needCheckStartTimeStamp != OMX_TRUE)) {
2376             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2377             pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2378             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "missing out indexTimestamp: %d", indexTimestamp);
2379         } else {
2380             pDstOutputData->timeStamp = 0x00;
2381             pDstOutputData->nFlags = 0x00;
2382         }
2383     } else {
2384         /* For timestamp correction. if mfc support frametype detect */
2385         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "disp_pic_frame_type: %d", pVideoBuffer->frameType);
2386 //#ifdef NEED_TIMESTAMP_REORDER
2387         /* TIZEN_FEATURE_E3250 */
2388         if (pVideoDec->bNeedTimestampReorder == OMX_TRUE) {
2389             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NEED_TIMESTAMP_REORDER ON");
2390             if ((pVideoBuffer->frameType == VIDEO_FRAME_I)) {
2391                 pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2392                 pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2393                 pH264Dec->hMFCH264Handle.outputIndexTimestamp = indexTimestamp;
2394             } else {
2395               pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2396               pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Dec->hMFCH264Handle.outputIndexTimestamp];
2397             }
2398 //#else
2399         } else {
2400           pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2401           pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2402         }
2403 //endif
2404         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "timestamp %lld us (%.2f secs), indexTimestamp: %d, nFlags: 0x%x", pDstOutputData->timeStamp, pDstOutputData->timeStamp / 1E6, indexTimestamp, pDstOutputData->nFlags);
2405     }
2406
2407     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2408         (displayStatus == VIDEO_FRAME_STATUS_DECODING_FINISHED) ||
2409         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2410         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "displayStatus:%d, nFlags0x%x", displayStatus, pDstOutputData->nFlags);
2411         pDstOutputData->remainDataLen = 0;
2412     } else {
2413         pDstOutputData->remainDataLen = bufferGeometry->nFrameWidth * bufferGeometry->nFrameHeight * 3 / 2;
2414     }
2415
2416     ret = OMX_ErrorNone;
2417
2418 EXIT:
2419     FunctionOut();
2420
2421     return ret;
2422 }
2423
2424 OMX_ERRORTYPE Exynos_H264Dec_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2425 {
2426     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2427     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2428
2429     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2430
2431     FunctionIn();
2432
2433     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2434         ret = OMX_ErrorNone;
2435         goto EXIT;
2436     }
2437     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2438         ret = OMX_ErrorNone;
2439         goto EXIT;
2440     }
2441
2442     ret = Exynos_H264Dec_SrcIn(pOMXComponent, pSrcInputData);
2443     if ((ret != OMX_ErrorNone) &&
2444        (ret != (OMX_ERRORTYPE)OMX_ErrorInputDataDecodeYet) &&
2445         (ret != (OMX_ERRORTYPE)OMX_ErrorCorruptedFrame)) {
2446 pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2447                                                 pExynosComponent->callbackData,
2448                                                 OMX_EventError, ret, 0, NULL);
2449     }
2450
2451 EXIT:
2452     FunctionOut();
2453
2454     return ret;
2455 }
2456
2457 OMX_ERRORTYPE Exynos_H264Dec_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2458 {
2459     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2460     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2461     EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2462     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2463
2464     FunctionIn();
2465
2466     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2467         ret = OMX_ErrorNone;
2468         goto EXIT;
2469     }
2470
2471     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2472         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2473             ret = OMX_ErrorNone;
2474             goto EXIT;
2475         }
2476     }
2477     if ((pH264Dec->bSourceStart == OMX_FALSE) &&
2478        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2479         Exynos_OSAL_SignalWait(pH264Dec->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2480         Exynos_OSAL_SignalReset(pH264Dec->hSourceStartEvent);
2481     }
2482
2483     ret = Exynos_H264Dec_SrcOut(pOMXComponent, pSrcOutputData);
2484     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2485         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2486                                                 pExynosComponent->callbackData,
2487                                                 OMX_EventError, ret, 0, NULL);
2488     }
2489
2490 EXIT:
2491     FunctionOut();
2492
2493     return ret;
2494 }
2495
2496 OMX_ERRORTYPE Exynos_H264Dec_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2497 {
2498     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2499     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2500     EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2501     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2502
2503     FunctionIn();
2504
2505     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2506         ret = OMX_ErrorNone;
2507         goto EXIT;
2508     }
2509     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2510         ret = OMX_ErrorNone;
2511         goto EXIT;
2512     }
2513     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2514         if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2515            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2516             Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2517             Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2518         }
2519     }
2520     if (pH264Dec->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2521         ret = Exynos_H264Dec_DstIn(pOMXComponent, pDstInputData);
2522         if (ret != OMX_ErrorNone) {
2523             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2524                                                     pExynosComponent->callbackData,
2525                                                     OMX_EventError, ret, 0, NULL);
2526         }
2527     }
2528
2529 EXIT:
2530     FunctionOut();
2531
2532     return ret;
2533 }
2534
2535 OMX_ERRORTYPE Exynos_H264Dec_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2536 {
2537     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2538     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2539     EXYNOS_H264DEC_HANDLE    *pH264Dec = (EXYNOS_H264DEC_HANDLE *)((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2540     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2541
2542     FunctionIn();
2543
2544     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2545         ret = OMX_ErrorNone;
2546         goto EXIT;
2547     }
2548     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2549         ret = OMX_ErrorNone;
2550         goto EXIT;
2551     }
2552
2553     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2554         if ((pH264Dec->bDestinationStart == OMX_FALSE) &&
2555            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2556             Exynos_OSAL_SignalWait(pH264Dec->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2557             Exynos_OSAL_SignalReset(pH264Dec->hDestinationStartEvent);
2558         }
2559     }
2560     ret = Exynos_H264Dec_DstOut(pOMXComponent, pDstOutputData);
2561     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2562         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2563                                                 pExynosComponent->callbackData,
2564                                                 OMX_EventError, ret, 0, NULL);
2565     }
2566
2567 EXIT:
2568     FunctionOut();
2569
2570     return ret;
2571 }
2572
2573 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2574 {
2575     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2576     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2577     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2578     EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2579     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
2580     EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
2581     OMX_BOOL                       bDRMPlayerMode   = OMX_FALSE;
2582     int i = 0;
2583
2584     FunctionIn();
2585
2586     if ((hComponent == NULL) || (componentName == NULL)) {
2587         ret = OMX_ErrorBadParameter;
2588         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2589         goto EXIT;
2590     }
2591     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DEC, componentName) == 0) {
2592         bDRMPlayerMode = OMX_FALSE;
2593     } else if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_DRM_DEC, componentName) == 0) {
2594         bDRMPlayerMode = OMX_TRUE;
2595     } else {
2596         ret = OMX_ErrorBadParameter;
2597         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2598         goto EXIT;
2599     }
2600
2601     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2602     ret = Exynos_OMX_VideoDecodeComponentInit(pOMXComponent);
2603     if (ret != OMX_ErrorNone) {
2604         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2605         goto EXIT;
2606     }
2607     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2608     pExynosComponent->codecType = HW_VIDEO_DEC_CODEC;
2609
2610     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2611     if (pExynosComponent->componentName == NULL) {
2612         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2613         ret = OMX_ErrorInsufficientResources;
2614         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2615         goto EXIT;
2616     }
2617     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2618
2619     pH264Dec = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264DEC_HANDLE));
2620     if (pH264Dec == NULL) {
2621         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2622         ret = OMX_ErrorInsufficientResources;
2623         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2624         goto EXIT;
2625     }
2626     Exynos_OSAL_Memset(pH264Dec, 0, sizeof(EXYNOS_H264DEC_HANDLE));
2627     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2628     pVideoDec->hCodecHandle = (OMX_HANDLETYPE)pH264Dec;
2629
2630     if (bDRMPlayerMode == OMX_TRUE)
2631         Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DRM_DEC);
2632     else
2633         Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_DEC);
2634
2635     pVideoDec->bDRMPlayerMode = bDRMPlayerMode;
2636     /* In case of BUFFER_COPY mode
2637             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2638             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2639          In case of BUFFER_SHARE
2640             bShareableBuf should be TRUE, FALSE is ignored
2641     */
2642     pH264Dec->hMFCH264Handle.bShareableBuf = OMX_FALSE;
2643 #ifdef USE_S3D_SUPPORT
2644     pH264Dec->hMFCH264Handle.S3DFPArgmtType = OMX_SEC_FPARGMT_NONE;
2645 #endif
2646
2647     /* Set componentVersion */
2648     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2649     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2650     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2651     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2652     /* Set specVersion */
2653     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2654     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2655     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2656     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2657
2658     /* Input port */
2659     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2660     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2661     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2662     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2663     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2664     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2665     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2666     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2667     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2668     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2669     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2670     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2671     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2672     pExynosPort->bufferProcessType = BUFFER_COPY;
2673     if (bDRMPlayerMode == OMX_TRUE)
2674         pExynosPort->bufferProcessType = BUFFER_SHARE;
2675     pExynosPort->portWayType = WAY2_PORT;
2676
2677     /* Output port */
2678     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2679     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2680     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2681     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2682     pExynosPort->portDefinition.format.video.nSliceHeight = 0;
2683     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2684     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2685     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2686     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2687     pExynosPort->portDefinition.format.video.pNativeRender = 0;
2688     pExynosPort->portDefinition.format.video.bFlagErrorConcealment = OMX_FALSE;
2689 #ifdef TIZEN_FEATURE_E3250
2690     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2691 #else
2692     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
2693 #endif
2694     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2695 #ifdef TIZEN_FEATURE_E3250
2696     pExynosPort->bufferProcessType = BUFFER_SHARE;
2697 #else
2698     pExynosPort->bufferProcessType = BUFFER_COPY;
2699 #endif
2700     pExynosPort->portWayType = WAY2_PORT;
2701
2702     for(i = 0; i < ALL_PORT_NUM; i++) {
2703         INIT_SET_SIZE_VERSION(&pH264Dec->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2704         pH264Dec->AVCComponent[i].nPortIndex = i;
2705         pH264Dec->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2706         pH264Dec->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel4;
2707     }
2708
2709     pOMXComponent->GetParameter      = &Exynos_H264Dec_GetParameter;
2710     pOMXComponent->SetParameter      = &Exynos_H264Dec_SetParameter;
2711     pOMXComponent->GetConfig         = &Exynos_H264Dec_GetConfig;
2712     pOMXComponent->SetConfig         = &Exynos_H264Dec_SetConfig;
2713     pOMXComponent->GetExtensionIndex = &Exynos_H264Dec_GetExtensionIndex;
2714     pOMXComponent->ComponentRoleEnum = &Exynos_H264Dec_ComponentRoleEnum;
2715     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2716
2717     pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Dec_Init;
2718     pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Dec_Terminate;
2719
2720     pVideoDec->exynos_codec_srcInputProcess  = &Exynos_H264Dec_srcInputBufferProcess;
2721     pVideoDec->exynos_codec_srcOutputProcess = &Exynos_H264Dec_srcOutputBufferProcess;
2722     pVideoDec->exynos_codec_dstInputProcess  = &Exynos_H264Dec_dstInputBufferProcess;
2723     pVideoDec->exynos_codec_dstOutputProcess = &Exynos_H264Dec_dstOutputBufferProcess;
2724
2725     pVideoDec->exynos_codec_start            = &H264CodecStart;
2726     pVideoDec->exynos_codec_stop             = &H264CodecStop;
2727     pVideoDec->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2728     pVideoDec->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
2729     pVideoDec->exynos_codec_resetupAllElement = &H264CodecResetupAllElement;
2730
2731     pVideoDec->exynos_checkInputFrame                 = NULL;
2732     pVideoDec->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2733     pVideoDec->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2734
2735 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2736     pVideoDec->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2737     if (pVideoDec->hSharedMemory == NULL) {
2738         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2739         Exynos_OSAL_Free(pH264Dec);
2740         pH264Dec = ((EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2741         Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2742         ret = OMX_ErrorInsufficientResources;
2743         goto EXIT;
2744     }
2745 #endif
2746     pExynosComponent->currentState = OMX_StateLoaded;
2747
2748     ret = OMX_ErrorNone;
2749
2750 EXIT:
2751     FunctionOut();
2752
2753     return ret;
2754 }
2755
2756 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2757 {
2758     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2759     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2760     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2761     EXYNOS_OMX_VIDEODEC_COMPONENT *pVideoDec        = NULL;
2762     EXYNOS_H264DEC_HANDLE         *pH264Dec         = NULL;
2763
2764     FunctionIn();
2765
2766     if (hComponent == NULL) {
2767         ret = OMX_ErrorBadParameter;
2768         goto EXIT;
2769     }
2770     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2771     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2772     pVideoDec = (EXYNOS_OMX_VIDEODEC_COMPONENT *)pExynosComponent->hComponentHandle;
2773
2774 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2775     Exynos_OSAL_SharedMemory_Close(pVideoDec->hSharedMemory);
2776 #endif
2777     Exynos_OSAL_Free(pExynosComponent->componentName);
2778     pExynosComponent->componentName = NULL;
2779
2780     pH264Dec = (EXYNOS_H264DEC_HANDLE *)pVideoDec->hCodecHandle;
2781     if (pH264Dec != NULL) {
2782         Exynos_OSAL_Free(pH264Dec);
2783         pH264Dec = pVideoDec->hCodecHandle = NULL;
2784     }
2785
2786     ret = Exynos_OMX_VideoDecodeComponentDeinit(pOMXComponent);
2787     if (ret != OMX_ErrorNone) {
2788         goto EXIT;
2789     }
2790
2791     ret = OMX_ErrorNone;
2792
2793 EXIT:
2794     FunctionOut();
2795
2796     return ret;
2797 }