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