41cd3f281cc90f0f703da8b62b05d5458d58ccdf
[platform/adaptation/ap_samsung/libomxil-e3250-v4l2.git] / openmax / component / video / enc / h264 / Exynos_OMX_H264enc.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_H264enc.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_Venc.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_H264enc.h"
40 //#include "ExynosVideoApi.h"
41 #include "Exynos_OSAL_SharedMemory.h"
42 #include "Exynos_OSAL_Event.h"
43 #include "Exynos_OMX_VencControl.h"
44
45 /* To use CSC_METHOD_HW in EXYNOS OMX, gralloc should allocate physical memory using FIMC */
46 /* It means GRALLOC_USAGE_HW_FIMC1 should be set on Native Window usage */
47 #include "csc.h"
48
49 #undef  EXYNOS_LOG_TAG
50 #define EXYNOS_LOG_TAG    "EXYNOS_H264_ENC"
51 #define EXYNOS_LOG_OFF
52 //#define EXYNOS_TRACE_ON
53 #include "Exynos_OSAL_Log.h"
54
55 /* H.264 Encoder Supported Levels & profiles */
56 EXYNOS_OMX_VIDEO_PROFILELEVEL supportedAVCProfileLevels[] ={
57     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1},
58     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel1b},
59     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel11},
60     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel12},
61     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13},
62     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel2},
63     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel21},
64     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel22},
65     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel3},
66     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel31},
67     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32},
68     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4},
69     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41},
70     {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
71
72     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1},
73     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b},
74     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11},
75     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12},
76     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13},
77     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2},
78     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21},
79     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22},
80     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3},
81     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31},
82     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32},
83     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4},
84     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41},
85     {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
86
87     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1},
88     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel1b},
89     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel11},
90     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel12},
91     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel13},
92     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel2},
93     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel21},
94     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel22},
95     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel3},
96     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel31},
97     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel32},
98     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel4},
99     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
100     {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}};
101
102 static OMX_U32 OMXAVCProfileToProfileIDC(OMX_VIDEO_AVCPROFILETYPE profile)
103 {
104     OMX_U32 ret = 0;
105
106     if (profile == OMX_VIDEO_AVCProfileBaseline)
107         ret = 0;
108     else if (profile == OMX_VIDEO_AVCProfileMain)
109         ret = 2;
110     else if (profile == OMX_VIDEO_AVCProfileHigh)
111         ret = 4;
112
113     return ret;
114 }
115
116 static OMX_U32 OMXAVCLevelToLevelIDC(OMX_VIDEO_AVCLEVELTYPE level)
117 {
118     OMX_U32 ret = 11; //default OMX_VIDEO_AVCLevel4
119
120     if (level == OMX_VIDEO_AVCLevel1)
121         ret = 0;
122     else if (level == OMX_VIDEO_AVCLevel1b)
123         ret = 1;
124     else if (level == OMX_VIDEO_AVCLevel11)
125         ret = 2;
126     else if (level == OMX_VIDEO_AVCLevel12)
127         ret = 3;
128     else if (level == OMX_VIDEO_AVCLevel13)
129         ret = 4;
130     else if (level == OMX_VIDEO_AVCLevel2)
131         ret = 5;
132     else if (level == OMX_VIDEO_AVCLevel21)
133         ret = 6;
134     else if (level == OMX_VIDEO_AVCLevel22)
135         ret = 7;
136     else if (level == OMX_VIDEO_AVCLevel3)
137         ret = 8;
138     else if (level == OMX_VIDEO_AVCLevel31)
139         ret = 9;
140     else if (level == OMX_VIDEO_AVCLevel32)
141         ret = 10;
142     else if (level == OMX_VIDEO_AVCLevel4)
143         ret = 11;
144     else if (level == OMX_VIDEO_AVCLevel41)
145         ret = 12;
146     else if (level == OMX_VIDEO_AVCLevel42)
147         ret = 13;
148
149     return ret;
150 }
151
152 static OMX_U8 *FindDelimiter(OMX_U8 *pBuffer, OMX_U32 size)
153 {
154     OMX_U32 i;
155
156     for (i = 0; i < size - 3; i++) {
157         if ((pBuffer[i] == 0x00)   &&
158             (pBuffer[i + 1] == 0x00) &&
159             (pBuffer[i + 2] == 0x00) &&
160             (pBuffer[i + 3] == 0x01))
161             return (pBuffer + i);
162     }
163
164     return NULL;
165 }
166
167 static void Print_H264Enc_Param(ExynosVideoEncParam *pEncParam)
168 {
169     ExynosVideoEncCommonParam *pCommonParam = &pEncParam->commonParam;
170     ExynosVideoEncH264Param   *pH264Param   = &pEncParam->codecParam.h264;
171
172     /* common parameters */
173     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceWidth             : %d", pCommonParam->SourceWidth);
174     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SourceHeight            : %d", pCommonParam->SourceHeight);
175     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "IDRPeriod               : %d", pCommonParam->IDRPeriod);
176     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceMode               : %d", pCommonParam->SliceMode);
177     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "RandomIntraMBRefresh    : %d", pCommonParam->RandomIntraMBRefresh);
178     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Bitrate                 : %d", pCommonParam->Bitrate);
179     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp                 : %d", pCommonParam->FrameQp);
180     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_P               : %d", pCommonParam->FrameQp_P);
181     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMax              : %d", pCommonParam->QSCodeMax);
182     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "QSCodeMin               : %d", pCommonParam->QSCodeMin);
183     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PadControlOn            : %d", pCommonParam->PadControlOn);
184     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LumaPadVal              : %d", pCommonParam->LumaPadVal);
185     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CbPadVal                : %d", pCommonParam->CbPadVal);
186     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CrPadVal                : %d", pCommonParam->CrPadVal);
187     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameMap                : %d", pCommonParam->FrameMap);
188
189     /* H.264 specific parameters */
190     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ProfileIDC              : %d", pH264Param->ProfileIDC);
191     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LevelIDC                : %d", pH264Param->LevelIDC);
192     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameQp_B               : %d", pH264Param->FrameQp_B);
193     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "FrameRate               : %d", pH264Param->FrameRate);
194     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SliceArgument           : %d", pH264Param->SliceArgument);
195     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberBFrames           : %d", pH264Param->NumberBFrames);
196     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberReferenceFrames   : %d", pH264Param->NumberReferenceFrames);
197     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "NumberRefForPframes     : %d", pH264Param->NumberRefForPframes);
198     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterDisable       : %d", pH264Param->LoopFilterDisable);
199     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterAlphaC0Offset : %d", pH264Param->LoopFilterAlphaC0Offset);
200     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "LoopFilterBetaOffset    : %d", pH264Param->LoopFilterBetaOffset);
201     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SymbolMode              : %d", pH264Param->SymbolMode);
202     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "PictureInterlace        : %d", pH264Param->PictureInterlace);
203     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Transform8x8Mode        : %d", pH264Param->Transform8x8Mode);
204     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "DarkDisable             : %d", pH264Param->DarkDisable);
205     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SmoothDisable           : %d", pH264Param->SmoothDisable);
206     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "StaticDisable           : %d", pH264Param->StaticDisable);
207     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "ActivityDisable         : %d", pH264Param->ActivityDisable);
208
209     /* rate control related parameters */
210     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableFRMRateControl    : %d", pCommonParam->EnableFRMRateControl);
211     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "EnableMBRateControl     : %d", pCommonParam->EnableMBRateControl);
212     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "CBRPeriodRf             : %d", pCommonParam->CBRPeriodRf);
213 }
214
215 static void Set_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
216 {
217     EXYNOS_OMX_BASEPORT           *pExynosInputPort  = NULL;
218     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = NULL;
219     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
220     EXYNOS_H264ENC_HANDLE         *pH264Enc          = NULL;
221     EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = NULL;
222
223     ExynosVideoEncParam       *pEncParam    = NULL;
224     ExynosVideoEncCommonParam *pCommonParam = NULL;
225     ExynosVideoEncH264Param   *pH264Param   = NULL;
226
227     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
228     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
229     pMFCH264Handle = &pH264Enc->hMFCH264Handle;
230     pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
231     pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
232
233     pEncParam = &pMFCH264Handle->encParam;
234     pCommonParam = &pEncParam->commonParam;
235     pH264Param = &pEncParam->codecParam.h264;
236     pEncParam->eCompressionFormat = VIDEO_CODING_AVC;
237     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "eCompressionFormat: %d", pEncParam->eCompressionFormat);
238
239     /* common parameters */
240     pCommonParam->SourceWidth  = pExynosOutputPort->portDefinition.format.video.nFrameWidth;
241     pCommonParam->SourceHeight = pExynosOutputPort->portDefinition.format.video.nFrameHeight;
242     pCommonParam->IDRPeriod    = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
243     pCommonParam->SliceMode = pH264Enc->AVCSliceFmo.eSliceMode;
244     pCommonParam->RandomIntraMBRefresh = 0;
245     pCommonParam->Bitrate      = pExynosOutputPort->portDefinition.format.video.nBitrate;
246     pCommonParam->FrameQp      = pVideoEnc->quantization.nQpI;
247     pCommonParam->FrameQp_P    = pVideoEnc->quantization.nQpP;
248     pCommonParam->QSCodeMax    = 51;
249     pCommonParam->QSCodeMin    = 10;
250     pCommonParam->PadControlOn = 0;    /* 0: disable, 1: enable */
251     pCommonParam->LumaPadVal   = 0;
252     pCommonParam->CbPadVal     = 0;
253     pCommonParam->CrPadVal     = 0;
254
255     switch ((int)pExynosInputPort->portDefinition.format.video.eColorFormat) {
256     case OMX_COLOR_FormatYUV420SemiPlanar:
257     case OMX_COLOR_FormatYUV420Planar: /* Converted to NV12 in Exynos_Preprocessor_InputData */
258     case OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd:
259 #ifdef USE_METADATABUFFERTYPE
260     case OMX_COLOR_FormatAndroidOpaque:
261 #endif
262         pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12;
263         break;
264     case OMX_SEC_COLOR_FormatNV12Tiled:
265     case OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd:
266         pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED;
267         break;
268     case OMX_SEC_COLOR_FormatNV21Linear:
269         pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV21;
270         break;
271     default:
272         pCommonParam->FrameMap = VIDEO_COLORFORMAT_NV12_TILED;
273         break;
274     }
275
276     /* H.264 specific parameters */
277     pH264Param->ProfileIDC   = OMXAVCProfileToProfileIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eProfile);    /*0: OMX_VIDEO_AVCProfileMain */
278     pH264Param->LevelIDC     = OMXAVCLevelToLevelIDC(pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].eLevel);    /*40: OMX_VIDEO_AVCLevel4 */
279     pH264Param->FrameQp_B    = pVideoEnc->quantization.nQpB;
280     pH264Param->FrameRate    = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16;
281     if (pH264Enc->AVCSliceFmo.eSliceMode == OMX_VIDEO_SLICEMODE_AVCDefault)
282         pH264Param->SliceArgument = 0;    /* Slice mb/byte size number */
283     else
284         pH264Param->SliceArgument = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nSliceHeaderSpacing;
285
286     pH264Param->NumberBFrames = 0;    /* 0 ~ 2 */
287     pH264Param->NumberReferenceFrames = 1;
288     pH264Param->NumberRefForPframes   = 1;
289 #ifdef TIZEN_FEATURE_E3250 /* for B2 camera */
290     pH264Param->LoopFilterDisable     = 0;    /* 1: Loop Filter Disable, 0: Filter Enable */
291 #else
292     pH264Param->LoopFilterDisable     = 1;    /* 1: Loop Filter Disable, 0: Filter Enable */
293 #endif
294     pH264Param->LoopFilterAlphaC0Offset = 0;
295     pH264Param->LoopFilterBetaOffset    = 0;
296     pH264Param->SymbolMode       = 0;    /* 0: CAVLC, 1: CABAC */
297     pH264Param->PictureInterlace = 0;
298     pH264Param->Transform8x8Mode = 0;    /* 0: 4x4, 1: allow 8x8 */
299     pH264Param->DarkDisable     = 1;
300     pH264Param->SmoothDisable   = 1;
301     pH264Param->StaticDisable   = 1;
302     pH264Param->ActivityDisable = 1;
303
304     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]: 0x%x", pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]);
305     /* rate control related parameters */
306     switch (pVideoEnc->eControlRate[OUTPUT_PORT_INDEX]) {
307     case OMX_Video_ControlRateDisable:
308         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode DBR");
309         pCommonParam->EnableFRMRateControl = 0;    /* 0: Disable, 1: Frame level RC */
310         pCommonParam->EnableMBRateControl  = 0;    /* 0: Disable, 1:MB level RC */
311         pCommonParam->CBRPeriodRf          = 100;
312         break;
313     case OMX_Video_ControlRateConstant:
314         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode CBR");
315         pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
316         pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
317         pCommonParam->CBRPeriodRf          = 9;
318         break;
319     case OMX_Video_ControlRateVariable:
320     default: /*Android default */
321         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Video Encode VBR");
322         pCommonParam->EnableFRMRateControl = 1;    /* 0: Disable, 1: Frame level RC */
323         pCommonParam->EnableMBRateControl  = 1;    /* 0: Disable, 1:MB level RC */
324         pCommonParam->CBRPeriodRf          = 100;
325         break;
326     }
327
328     Print_H264Enc_Param(pEncParam);
329 }
330
331 static void Change_H264Enc_Param(EXYNOS_OMX_BASECOMPONENT *pExynosComponent)
332 {
333     EXYNOS_OMX_BASEPORT           *pExynosInputPort  = NULL;
334     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = NULL;
335     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc         = NULL;
336     EXYNOS_H264ENC_HANDLE         *pH264Enc          = NULL;
337     EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = NULL;
338
339     ExynosVideoEncOps         *pEncOps      = NULL;
340     ExynosVideoEncParam       *pEncParam    = NULL;
341     ExynosVideoEncCommonParam *pCommonParam = NULL;
342     ExynosVideoEncH264Param   *pH264Param   = NULL;
343
344     int setParam = 0;
345
346     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
347     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
348     pMFCH264Handle = &pH264Enc->hMFCH264Handle;
349     pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
350     pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
351     pEncOps = pMFCH264Handle->pEncOps;
352
353     pEncParam = &pMFCH264Handle->encParam;
354     pCommonParam = &pEncParam->commonParam;
355     pH264Param = &pEncParam->codecParam.h264;
356
357     if (pVideoEnc->IntraRefreshVOP == OMX_TRUE) {
358         setParam = VIDEO_FRAME_I;
359         pEncOps->Set_FrameType(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
360         pVideoEnc->IntraRefreshVOP = OMX_FALSE;
361     }
362     if (pCommonParam->IDRPeriod != (int)pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1) {
363         setParam = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
364         pEncOps->Set_IDRPeriod(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
365     }
366     if (pCommonParam->Bitrate != (int)pExynosOutputPort->portDefinition.format.video.nBitrate) {
367         setParam = pExynosOutputPort->portDefinition.format.video.nBitrate;
368         pEncOps->Set_BitRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
369     }
370     if (pH264Param->FrameRate != (int)((pExynosInputPort->portDefinition.format.video.xFramerate) >> 16)) {
371         setParam = (pExynosInputPort->portDefinition.format.video.xFramerate) >> 16;
372         pEncOps->Set_FrameRate(pH264Enc->hMFCH264Handle.hMFCHandle, setParam);
373     }
374
375     Set_H264Enc_Param(pExynosComponent);
376 }
377
378 OMX_ERRORTYPE GetCodecInputPrivateData(OMX_PTR codecBuffer, OMX_PTR addr[], OMX_U32 size[])
379 {
380     return OMX_ErrorNone;
381 }
382
383 OMX_ERRORTYPE GetCodecOutputPrivateData(OMX_PTR codecBuffer, OMX_PTR *pVirtAddr, OMX_U32 *dataSize)
384 {
385     OMX_ERRORTYPE       ret = OMX_ErrorNone;
386     ExynosVideoBuffer  *pCodecBuffer;
387
388     if (codecBuffer == NULL) {
389         ret = OMX_ErrorBadParameter;
390         goto EXIT;
391     }
392
393     pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
394
395     if (pVirtAddr != NULL)
396         *pVirtAddr = pCodecBuffer->planes[0].addr;
397
398     if (dataSize != NULL)
399         *dataSize = pCodecBuffer->planes[0].allocSize;
400
401     pCodecBuffer = (ExynosVideoBuffer *)codecBuffer;
402
403 EXIT:
404     return ret;
405 }
406
407 OMX_ERRORTYPE H264CodecOpen(EXYNOS_H264ENC_HANDLE *pH264Enc)
408 {
409     OMX_ERRORTYPE           ret = OMX_ErrorNone;
410
411     ExynosVideoEncOps       *pEncOps    = NULL;
412     ExynosVideoEncBufferOps *pInbufOps  = NULL;
413     ExynosVideoEncBufferOps *pOutbufOps = NULL;
414     enum v4l2_memory         v4l2MemoryType = V4L2_MEMORY_USERPTR;
415
416     FunctionIn();
417
418     if (pH264Enc == NULL) {
419         ret = OMX_ErrorBadParameter;
420         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
421         goto EXIT;
422     }
423
424     /* alloc ops structure */
425     pEncOps = (ExynosVideoEncOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncOps));
426     pInbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
427     pOutbufOps = (ExynosVideoEncBufferOps *)Exynos_OSAL_Malloc(sizeof(ExynosVideoEncBufferOps));
428
429     if ((pEncOps == NULL) || (pInbufOps == NULL) || (pOutbufOps == NULL)) {
430         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate encoder ops buffer");
431         ret = OMX_ErrorInsufficientResources;
432         goto EXIT;
433     }
434
435     pH264Enc->hMFCH264Handle.pEncOps = pEncOps;
436     pH264Enc->hMFCH264Handle.pInbufOps = pInbufOps;
437     pH264Enc->hMFCH264Handle.pOutbufOps = pOutbufOps;
438
439     /* function pointer mapping */
440     pEncOps->nSize = sizeof(ExynosVideoEncOps);
441     pInbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
442     pOutbufOps->nSize = sizeof(ExynosVideoEncBufferOps);
443
444     Exynos_Video_Register_Encoder(pEncOps, pInbufOps, pOutbufOps);
445
446     /* check mandatory functions for encoder ops */
447     if ((pEncOps->Init == NULL) || (pEncOps->Finalize == NULL) ||
448         (pEncOps->Set_FrameTag == NULL) || (pEncOps->Get_FrameTag == NULL)) {
449         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
450         ret = OMX_ErrorInsufficientResources;
451         goto EXIT;
452     }
453
454     /* check mandatory functions for buffer ops */
455     if ((pInbufOps->Setup == NULL) || (pOutbufOps->Setup == NULL) ||
456         (pInbufOps->Run == NULL) || (pOutbufOps->Run == NULL) ||
457         (pInbufOps->Stop == NULL) || (pOutbufOps->Stop == NULL) ||
458         (pInbufOps->Enqueue == NULL) || (pOutbufOps->Enqueue == NULL) ||
459         (pInbufOps->Dequeue == NULL) || (pOutbufOps->Dequeue == NULL)) {
460         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Mandatory functions must be supplied");
461         ret = OMX_ErrorInsufficientResources;
462         goto EXIT;
463     }
464
465     if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
466 #ifdef USE_DMA_BUF
467         v4l2MemoryType = V4L2_MEMORY_DMABUF;
468         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_DMABUF");
469 #else
470         v4l2MemoryType = V4L2_MEMORY_USERPTR;
471         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY_USEPTR");
472 #endif
473     } else {
474         //v4l2MemoryType = V4L2_MEMORY_MMAP;
475         v4l2MemoryType = V4L2_MEMORY_DMABUF; //if input port is using Buffer-share mode
476         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "using Enc V4L2_MEMORY - DMABUF & MMAP");
477     }
478
479     /* alloc context, open, querycap */
480     pH264Enc->hMFCH264Handle.hMFCHandle = pH264Enc->hMFCH264Handle.pEncOps->Init(v4l2MemoryType);
481     if (pH264Enc->hMFCH264Handle.hMFCHandle == NULL) {
482         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate context buffer");
483         ret = OMX_ErrorInsufficientResources;
484         goto EXIT;
485     }
486
487     ret = OMX_ErrorNone;
488
489 EXIT:
490     if (ret != OMX_ErrorNone) {
491         if (pEncOps != NULL) {
492             Exynos_OSAL_Free(pEncOps);
493             pH264Enc->hMFCH264Handle.pEncOps = NULL;
494         }
495         if (pInbufOps != NULL) {
496             Exynos_OSAL_Free(pInbufOps);
497             pH264Enc->hMFCH264Handle.pInbufOps = NULL;
498         }
499         if (pOutbufOps != NULL) {
500             Exynos_OSAL_Free(pOutbufOps);
501             pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
502         }
503     }
504
505     FunctionOut();
506
507     return ret;
508 }
509
510 OMX_ERRORTYPE H264CodecClose(EXYNOS_H264ENC_HANDLE *pH264Enc)
511 {
512     OMX_ERRORTYPE            ret = OMX_ErrorNone;
513     void                    *hMFCHandle = NULL;
514     ExynosVideoEncOps       *pEncOps    = NULL;
515     ExynosVideoEncBufferOps *pInbufOps  = NULL;
516     ExynosVideoEncBufferOps *pOutbufOps = NULL;
517
518     FunctionIn();
519
520     if (pH264Enc == NULL) {
521         ret = OMX_ErrorBadParameter;
522         goto EXIT;
523     }
524
525     hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
526     pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
527     pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
528     pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
529
530     if (hMFCHandle != NULL) {
531         pEncOps->Finalize(hMFCHandle);
532         hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle = NULL;
533     }
534     if (pOutbufOps != NULL) {
535         Exynos_OSAL_Free(pOutbufOps);
536         pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps = NULL;
537     }
538     if (pInbufOps != NULL) {
539         Exynos_OSAL_Free(pInbufOps);
540         pInbufOps = pH264Enc->hMFCH264Handle.pInbufOps = NULL;
541     }
542     if (pEncOps != NULL) {
543         Exynos_OSAL_Free(pEncOps);
544         pEncOps = pH264Enc->hMFCH264Handle.pEncOps = NULL;
545     }
546
547     ret = OMX_ErrorNone;
548
549 EXIT:
550     FunctionOut();
551
552     return ret;
553 }
554
555 OMX_ERRORTYPE H264CodecStart(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
556 {
557     OMX_ERRORTYPE            ret = OMX_ErrorNone;
558     void                    *hMFCHandle = NULL;
559     ExynosVideoEncBufferOps *pInbufOps  = NULL;
560     ExynosVideoEncBufferOps *pOutbufOps = NULL;
561     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
562     EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
563
564     FunctionIn();
565
566     if (pOMXComponent == NULL) {
567         ret = OMX_ErrorBadParameter;
568         goto EXIT;
569     }
570
571     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
572     if (pVideoEnc == NULL) {
573         ret = OMX_ErrorBadParameter;
574         goto EXIT;
575     }
576
577     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
578     if (pH264Enc == NULL) {
579         ret = OMX_ErrorBadParameter;
580         goto EXIT;
581     }
582
583     hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
584     pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
585     pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
586
587     if (nPortIndex == INPUT_PORT_INDEX)
588         pInbufOps->Run(hMFCHandle);
589     else if (nPortIndex == OUTPUT_PORT_INDEX)
590         pOutbufOps->Run(hMFCHandle);
591
592     ret = OMX_ErrorNone;
593
594 EXIT:
595     FunctionOut();
596
597     return ret;
598 }
599
600 OMX_ERRORTYPE H264CodecStop(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
601 {
602     OMX_ERRORTYPE            ret = OMX_ErrorNone;
603
604         void                    *hMFCHandle = NULL;
605     ExynosVideoEncBufferOps *pOutbufOps = NULL;
606     ExynosVideoEncBufferOps *pInbufOps  = NULL;
607     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
608     EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
609
610     FunctionIn();
611
612     if (pOMXComponent == NULL) {
613         ret = OMX_ErrorBadParameter;
614         goto EXIT;
615     }
616
617     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
618     if (pVideoEnc == NULL) {
619         ret = OMX_ErrorBadParameter;
620         goto EXIT;
621     }
622     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
623     if (pH264Enc == NULL) {
624         ret = OMX_ErrorBadParameter;
625         goto EXIT;
626     }
627     hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
628     pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
629     pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
630
631     if ((nPortIndex == INPUT_PORT_INDEX) && (pInbufOps != NULL))
632         pInbufOps->Stop(hMFCHandle);
633     else if ((nPortIndex == OUTPUT_PORT_INDEX) && (pOutbufOps != NULL))
634         pOutbufOps->Stop(hMFCHandle);
635
636     ret = OMX_ErrorNone;
637
638 EXIT:
639     FunctionOut();
640
641     return ret;
642 }
643
644 OMX_ERRORTYPE H264CodecSrcInit(OMX_COMPONENTTYPE *pOMXComponent)
645 {
646     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
647     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
648     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
649     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
650     EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
651     void                          *hMFCHandle = pMFCH264Handle->hMFCHandle;
652     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
653
654     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
655     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
656     ExynosVideoEncParam     *pEncParam    = NULL;
657
658     ExynosVideoGeometry      bufferConf;
659     OMX_U32                  inputBufferNumber = 0;
660     int i;
661
662     FunctionIn();
663
664     Set_H264Enc_Param(pExynosComponent);
665     pEncParam = &pMFCH264Handle->encParam;
666     if (pEncOps->Set_EncParam) {
667         if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
668             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
669             ret = OMX_ErrorInsufficientResources;
670             goto EXIT;
671         }
672     }
673
674     if (pMFCH264Handle->bPrependSpsPpsToIdr == OMX_TRUE) {
675         if (pEncOps->Enable_PrependSpsPpsToIdr)
676             pEncOps->Enable_PrependSpsPpsToIdr(pH264Enc->hMFCH264Handle.hMFCHandle);
677     }
678
679     /* input buffer info: only 3 config values needed */
680     Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
681     bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;;
682     bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
683     bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
684
685     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "bufferConf, eColorFormat=%d, w=%d, h=%d", bufferConf.eColorFormat, bufferConf.nFrameWidth, bufferConf.nFrameHeight);
686
687     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE
688         ||pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE)
689         pInbufOps->Set_Shareable(hMFCHandle);
690
691     if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
692         inputBufferNumber = MAX_CAMERA_INPUTBUFFER_NUM; /* Need change to number of camera buffer */
693     } else if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
694         inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
695     }
696
697     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
698         /* should be done before prepare input buffer */
699         if (pInbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
700             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set Enable_Cacheable for input buffer");
701             ret = OMX_ErrorInsufficientResources;
702             goto EXIT;
703         }
704     }
705
706     /* set input buffer geometry */
707     if (pInbufOps->Set_Geometry) {
708
709         if (pInbufOps->Set_Geometry(hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
710             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
711             ret = OMX_ErrorInsufficientResources;
712             goto EXIT;
713         }
714     }
715
716     /* setup input buffer */
717     if (pInbufOps->Setup(hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
718         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
719         ret = OMX_ErrorInsufficientResources;
720         goto EXIT;
721     }
722
723     ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
724     int plane;
725
726     if (pExynosInputPort->bufferProcessType & BUFFER_COPY &&
727         pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
728        /* Register input buffer */
729         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
730             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
731                 planes[plane].addr = pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane];
732                 planes[plane].allocSize = pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane];
733                 planes[plane].fd = pVideoEnc->pMFCEncInputBuffer[i]->fd[plane];
734             }
735             if (pInbufOps->Register(hMFCHandle, planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
736                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
737                 ret = OMX_ErrorInsufficientResources;
738                 goto EXIT;
739             }
740         }
741     } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
742         pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE) {
743         ExynosVideoBuffer *pBuffer = NULL;
744
745         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
746                 pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
747                 /* get input buffer info */
748                 if (pInbufOps->Get_Buffer) {
749                     if (pInbufOps->Get_Buffer(pH264Enc->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
750                         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info");
751                         ret = OMX_ErrorInsufficientResources;
752                         goto EXIT;
753                     }
754                 }
755
756                 for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
757                      pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] = (void *)pBuffer->planes[plane].addr;
758                     pVideoEnc->pMFCEncInputBuffer[i]->fd[plane] = pBuffer->planes[plane].fd;
759                     pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[plane] = pBuffer->planes[plane].allocSize;
760                     pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
761                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]);
762                 }
763
764                 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
765             }
766     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
767         if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
768             /*************/
769             /*    TBD    */
770             /*************/
771             /* Does not require any actions. */
772         } else {
773 #ifndef TIZEN_FEATURE_E3250 /* slp platform can go into here */
774             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get input buffer info");
775             ret = OMX_ErrorNotImplemented;
776             goto EXIT;
777 #endif
778         }
779     }
780
781 EXIT:
782     FunctionOut();
783
784     return ret;
785 }
786
787 OMX_ERRORTYPE H264CodecOutputBufferProcessRun(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
788 {
789     OMX_ERRORTYPE            ret = OMX_ErrorNone;
790     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
791     EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
792
793     FunctionIn();
794
795     if (pOMXComponent == NULL) {
796         ret = OMX_ErrorBadParameter;
797         goto EXIT;
798     }
799
800     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)((EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate)->hComponentHandle;
801     if (pVideoEnc == NULL) {
802         ret = OMX_ErrorBadParameter;
803         goto EXIT;
804     }
805     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
806     if (pH264Enc == NULL) {
807         ret = OMX_ErrorBadParameter;
808         goto EXIT;
809     }
810
811     if (nPortIndex == INPUT_PORT_INDEX) {
812         if (pH264Enc->bSourceStart == OMX_FALSE) {
813             Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
814             Exynos_OSAL_SleepMillisec(0);
815         }
816     }
817
818     if (nPortIndex == OUTPUT_PORT_INDEX) {
819         if (pH264Enc->bDestinationStart == OMX_FALSE) {
820             Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
821             Exynos_OSAL_SleepMillisec(0);
822         }
823     }
824
825     ret = OMX_ErrorNone;
826
827 EXIT:
828     FunctionOut();
829
830     return ret;
831 }
832
833 OMX_ERRORTYPE H264CodecEnqueueAllBuffer(OMX_COMPONENTTYPE *pOMXComponent, OMX_U32 nPortIndex)
834 {
835     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
836     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
837     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
838     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
839     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
840     int i;
841
842     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
843     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
844
845     FunctionIn();
846
847     if ((nPortIndex != INPUT_PORT_INDEX) && (nPortIndex != OUTPUT_PORT_INDEX)) {
848         ret = OMX_ErrorBadPortIndex;
849         goto EXIT;
850     }
851
852     if ((nPortIndex == INPUT_PORT_INDEX) &&
853         (pH264Enc->bSourceStart == OMX_TRUE)) {
854         Exynos_CodecBufferReset(pExynosComponent, INPUT_PORT_INDEX);
855
856         for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++)  {
857             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
858             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
859             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
860
861             Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
862         }
863
864         pInbufOps->Clear_Queue(hMFCHandle);
865     } else if ((nPortIndex == OUTPUT_PORT_INDEX) &&
866                (pH264Enc->bDestinationStart == OMX_TRUE)) {
867         ExynosVideoBuffer *pBuffer = NULL;
868
869         Exynos_CodecBufferReset(pExynosComponent, OUTPUT_PORT_INDEX);
870
871         for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
872             pOutbufOps->Get_Buffer(hMFCHandle, i, &pBuffer);
873             Exynos_CodecBufferEnqueue(pExynosComponent, OUTPUT_PORT_INDEX, (OMX_PTR)pBuffer);
874             Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncOutputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]);
875 //            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
876 //            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
877         }
878         pOutbufOps->Clear_Queue(hMFCHandle);
879     }
880
881 EXIT:
882     FunctionOut();
883
884     return ret;
885 }
886
887 OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
888 {
889     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
890     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
891     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
892     EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
893     OMX_U32                        oneFrameSize = pSrcInputData->dataLen;
894
895     FunctionIn();
896
897     if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
898         OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
899         OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
900         if (OMXBuffer == NULL) {
901             ret = OMX_ErrorUndefined;
902             goto EXIT;
903         }
904
905         OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
906         OMXBuffer->nFlags = pSrcInputData->nFlags;
907         Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
908
909         ret = OMX_ErrorNone;
910         goto EXIT;
911     }
912
913     if (!((pExynosInputPort->bufferProcessType & BUFFER_COPY) &&
914         pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE)) {
915         ret = H264CodecSrcInit(pOMXComponent);
916         if (ret != OMX_ErrorNone)
917             goto EXIT;
918     }
919
920
921     pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
922     ret = OMX_ErrorNone;
923
924 EXIT:
925     FunctionOut();
926
927     return ret;
928 }
929
930 OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
931 {
932     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
933     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
934     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
935     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
936     EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
937     void                          *hMFCHandle = pMFCH264Handle->hMFCHandle;
938     EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
939
940     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
941     ExynosVideoGeometry      bufferConf;
942     int i,nPlanes, OutBufferSize;
943
944     FunctionIn();
945
946     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
947 /*For memory Optimization */
948         OutBufferSize = 1024*1024*2;//pExynosOutputPort->portDefinition.format.video.nFrameWidth * pExynosOutputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
949     } else {
950         OutBufferSize = pExynosOutputPort->extendBufferHeader[0].OMXBufferHeader->nAllocLen;
951     }
952
953     /* set geometry for output (dst) */
954     if (pOutbufOps->Set_Geometry) {
955         /* output buffer info: only 2 config values needed */
956         bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
957         bufferConf.nSizeImage = OutBufferSize;
958
959         if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
960             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
961             ret = OMX_ErrorInsufficientResources;
962             goto EXIT;
963         }
964     }
965
966     /* should be done before prepare output buffer */
967     if (pOutbufOps->Enable_Cacheable(hMFCHandle) != VIDEO_ERROR_NONE) {
968         ret = OMX_ErrorInsufficientResources;
969         goto EXIT;
970     }
971
972     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE
973         ||pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE)
974         pOutbufOps->Set_Shareable(hMFCHandle);
975
976     int SetupBufferNumber = 0;
977     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY)
978         SetupBufferNumber = MFC_OUTPUT_BUFFER_NUM_MAX;
979     else
980         SetupBufferNumber = pExynosOutputPort->portDefinition.nBufferCountActual;
981     Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "SetupBufferNumber:%d", SetupBufferNumber);
982
983     if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, SetupBufferNumber) != VIDEO_ERROR_NONE) {
984         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
985         ret = OMX_ErrorInsufficientResources;
986         goto EXIT;
987     }
988
989     OMX_U32 dataLen[MFC_OUTPUT_BUFFER_PLANE] = {0};
990     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
991         if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
992             /* Register input buffer */
993             for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
994                 ExynosVideoPlane plane;
995                 pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
996                 pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] =
997                     (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
998                 if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] == NULL) {
999                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
1000                     ret = OMX_ErrorInsufficientResources;
1001                     goto EXIT;
1002                 }
1003                 pVideoEnc->pMFCEncOutputBuffer[i]->fd[0] =
1004                     Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
1005                 pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0] = OutBufferSize;
1006
1007                 plane.addr = pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0];
1008                 plane.fd = pVideoEnc->pMFCEncOutputBuffer[i]->fd[0];
1009                 plane.allocSize = pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[0];
1010
1011                 if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1012                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1013                     ret = OMX_ErrorInsufficientResources;
1014                     goto EXIT;
1015                 }
1016                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
1017                                     (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1018             }
1019         }else if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_FALSE) {
1020             /* Register input buffer */
1021             for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1022                 ExynosVideoBuffer *pBuffer = NULL;
1023
1024                 pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
1025
1026                 if (!pVideoEnc->pMFCEncOutputBuffer[i]) {
1027                     ret = OMX_ErrorInsufficientResources;
1028                     goto ALLOC_FAILED;
1029                 }
1030
1031                 if (pOutbufOps->Get_Buffer) {
1032                      if (pOutbufOps->Get_Buffer(pH264Enc->hMFCH264Handle.hMFCHandle, i, &pBuffer) != VIDEO_ERROR_NONE) {
1033                          Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to get Output buffer info");
1034                          ret = OMX_ErrorInsufficientResources;
1035                          goto EXIT;
1036                      }
1037                 }
1038
1039                 for (nPlanes = 0; nPlanes < MFC_OUTPUT_BUFFER_PLANE; nPlanes++) {
1040                     pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes] = (void *)pBuffer->planes[nPlanes].addr;
1041                     pVideoEnc->pMFCEncOutputBuffer[i]->fd[nPlanes] = pBuffer->planes[nPlanes].fd;
1042                     pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize[nPlanes] = pBuffer->planes[nPlanes].allocSize;
1043                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "pVideoEnc->pMFCEncOutputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[nPlanes]);
1044                 }
1045
1046                 pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr,
1047                                     (unsigned int *)dataLen, MFC_OUTPUT_BUFFER_PLANE, NULL);
1048             }
1049         }
1050
1051         /* start header encoding */
1052         if (pOutbufOps->Run(hMFCHandle) != VIDEO_ERROR_NONE) {
1053             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer");
1054             ret = OMX_ErrorInsufficientResources;
1055             goto EXIT;
1056         }
1057     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1058         /* Register input buffer */
1059         /*************/
1060         /*    TBD    */
1061         /*************/
1062         ExynosVideoPlane plane;
1063         for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
1064             plane.addr = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer;
1065             plane.fd = pExynosOutputPort->extendBufferHeader[i].buf_fd[0];
1066             plane.allocSize = pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen;
1067             if (pOutbufOps->Register(hMFCHandle, &plane, MFC_OUTPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1068                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1069                 ret = OMX_ErrorInsufficientResources;
1070                 goto EXIT;
1071             }
1072         }
1073     }
1074
1075     pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
1076
1077     ret = OMX_ErrorNone;
1078
1079 EXIT:
1080     FunctionOut();
1081
1082     return ret;
1083 }
1084
1085 OMX_ERRORTYPE Exynos_H264Enc_GetParameter(
1086     OMX_IN OMX_HANDLETYPE hComponent,
1087     OMX_IN OMX_INDEXTYPE  nParamIndex,
1088     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1089 {
1090     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1091     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1092     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1093
1094     FunctionIn();
1095
1096     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1097         ret = OMX_ErrorBadParameter;
1098         goto EXIT;
1099     }
1100     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1101     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1102     if (ret != OMX_ErrorNone) {
1103         goto EXIT;
1104     }
1105     if (pOMXComponent->pComponentPrivate == NULL) {
1106         ret = OMX_ErrorBadParameter;
1107         goto EXIT;
1108     }
1109
1110     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1111     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1112         ret = OMX_ErrorInvalidState;
1113         goto EXIT;
1114     }
1115
1116     switch (nParamIndex) {
1117     case OMX_IndexParamVideoAvc:
1118     {
1119         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1120         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1121         EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
1122
1123         ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1124         if (ret != OMX_ErrorNone) {
1125             goto EXIT;
1126         }
1127
1128         if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1129             ret = OMX_ErrorBadPortIndex;
1130             goto EXIT;
1131         }
1132
1133         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1134         pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
1135
1136         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1137     }
1138         break;
1139
1140     case  OMX_IndexParamVideoSliceFMO:
1141     {
1142         OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
1143         OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL;
1144         EXYNOS_H264ENC_HANDLE       *pH264Enc = NULL;
1145
1146         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1147         pSrcSliceFmo = &pH264Enc->AVCSliceFmo;
1148
1149         Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
1150     }
1151         break;
1152
1153     case OMX_IndexParamStandardComponentRole:
1154     {
1155         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1156         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1157         if (ret != OMX_ErrorNone) {
1158             goto EXIT;
1159         }
1160
1161         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1162     }
1163         break;
1164     case OMX_IndexParamVideoProfileLevelQuerySupported:
1165     {
1166         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1167         EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1168         OMX_U32 maxProfileLevelNum = 0;
1169
1170         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1171         if (ret != OMX_ErrorNone) {
1172             goto EXIT;
1173         }
1174
1175         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1176             ret = OMX_ErrorBadPortIndex;
1177             goto EXIT;
1178         }
1179
1180         pProfileLevel = supportedAVCProfileLevels;
1181         maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1182
1183         if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1184             ret = OMX_ErrorNoMore;
1185             goto EXIT;
1186         }
1187
1188         pProfileLevel += pDstProfileLevel->nProfileIndex;
1189         pDstProfileLevel->eProfile = pProfileLevel->profile;
1190         pDstProfileLevel->eLevel = pProfileLevel->level;
1191     }
1192         break;
1193     case OMX_IndexParamVideoProfileLevelCurrent:
1194     {
1195         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1196         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1197         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1198
1199         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1200         if (ret != OMX_ErrorNone) {
1201             goto EXIT;
1202         }
1203
1204         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1205             ret = OMX_ErrorBadPortIndex;
1206             goto EXIT;
1207         }
1208
1209         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1210         pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
1211
1212         pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1213         pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1214     }
1215         break;
1216     case OMX_IndexParamVideoErrorCorrection:
1217     {
1218         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1219         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1220         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1221
1222         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1223         if (ret != OMX_ErrorNone) {
1224             goto EXIT;
1225         }
1226
1227         if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1228             ret = OMX_ErrorBadPortIndex;
1229             goto EXIT;
1230         }
1231
1232         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1233         pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1234
1235         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1236         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1237         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1238         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1239         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1240     }
1241         break;
1242     default:
1243         ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1244         break;
1245     }
1246 EXIT:
1247     FunctionOut();
1248
1249     return ret;
1250 }
1251
1252 OMX_ERRORTYPE Exynos_H264Enc_SetParameter(
1253     OMX_IN OMX_HANDLETYPE hComponent,
1254     OMX_IN OMX_INDEXTYPE  nIndex,
1255     OMX_IN OMX_PTR        pComponentParameterStructure)
1256 {
1257     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1258     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1259     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1260
1261     FunctionIn();
1262
1263     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1264         ret = OMX_ErrorBadParameter;
1265         goto EXIT;
1266     }
1267     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1268     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1269     if (ret != OMX_ErrorNone) {
1270         goto EXIT;
1271     }
1272     if (pOMXComponent->pComponentPrivate == NULL) {
1273         ret = OMX_ErrorBadParameter;
1274         goto EXIT;
1275     }
1276
1277     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1278     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1279         ret = OMX_ErrorInvalidState;
1280         goto EXIT;
1281     }
1282
1283     switch ((int)nIndex) {
1284     case OMX_IndexParamVideoAvc:
1285     {
1286         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1287         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1288         EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
1289
1290         ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1291         if (ret != OMX_ErrorNone) {
1292             goto EXIT;
1293         }
1294
1295         if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1296             ret = OMX_ErrorBadPortIndex;
1297             goto EXIT;
1298         }
1299
1300         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1301         pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
1302
1303         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1304     }
1305         break;
1306     case  OMX_IndexParamVideoSliceFMO:
1307     {
1308         OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL;
1309         OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
1310         EXYNOS_H264ENC_HANDLE       *pH264Enc = NULL;
1311
1312         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1313         pDstSliceFmo = &pH264Enc->AVCSliceFmo;
1314
1315         Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
1316     }
1317         break;
1318
1319     case OMX_IndexParamStandardComponentRole:
1320     {
1321         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1322
1323         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1324         if (ret != OMX_ErrorNone) {
1325             goto EXIT;
1326         }
1327
1328         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1329             ret = OMX_ErrorIncorrectStateOperation;
1330             goto EXIT;
1331         }
1332
1333         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE)) {
1334             pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1335         } else {
1336             ret = OMX_ErrorBadParameter;
1337             goto EXIT;
1338         }
1339     }
1340         break;
1341     case OMX_IndexParamVideoProfileLevelCurrent:
1342     {
1343         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1344         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1345         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1346
1347         ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1348         if (ret != OMX_ErrorNone)
1349             goto EXIT;
1350
1351         if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1352             ret = OMX_ErrorBadPortIndex;
1353             goto EXIT;
1354         }
1355
1356         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1357
1358         pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
1359         pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1360         pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1361     }
1362         break;
1363     case OMX_IndexParamVideoErrorCorrection:
1364     {
1365         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1366         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1367         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1368
1369         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1370         if (ret != OMX_ErrorNone) {
1371             goto EXIT;
1372         }
1373
1374         if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1375             ret = OMX_ErrorBadPortIndex;
1376             goto EXIT;
1377         }
1378
1379         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1380         pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1381
1382         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1383         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1384         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1385         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1386         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1387     }
1388         break;
1389 #ifdef USE_H264_PREPEND_SPS_PPS
1390     case OMX_IndexParamPrependSPSPPSToIDR:
1391     {
1392         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1393
1394         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1395         pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr = OMX_TRUE;
1396     }
1397         break;
1398 #endif
1399 #ifdef TIZEN_FEATURE_E3250
1400     case OMX_IndexParamSharedOutputFD:
1401     {
1402         EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1403         pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1404
1405         pVideoEnc->bSharedOutputFD = OMX_TRUE;
1406     }
1407         break;
1408 #endif
1409
1410     default:
1411         ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1412         break;
1413     }
1414 EXIT:
1415     FunctionOut();
1416
1417     return ret;
1418 }
1419
1420 OMX_ERRORTYPE Exynos_H264Enc_GetConfig(
1421     OMX_HANDLETYPE hComponent,
1422     OMX_INDEXTYPE nIndex,
1423     OMX_PTR pComponentConfigStructure)
1424 {
1425     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1426     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1427     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1428     EXYNOS_H264ENC_HANDLE    *pH264Enc         = NULL;
1429
1430     FunctionIn();
1431
1432     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1433         ret = OMX_ErrorBadParameter;
1434         goto EXIT;
1435     }
1436     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1437     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1438     if (ret != OMX_ErrorNone) {
1439         goto EXIT;
1440     }
1441     if (pOMXComponent->pComponentPrivate == NULL) {
1442         ret = OMX_ErrorBadParameter;
1443         goto EXIT;
1444     }
1445     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1446     if (pExynosComponent->currentState == OMX_StateInvalid) {
1447         ret = OMX_ErrorInvalidState;
1448         goto EXIT;
1449     }
1450     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1451
1452     switch (nIndex) {
1453     case OMX_IndexConfigVideoAVCIntraPeriod:
1454     {
1455         OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1456         OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1457
1458         if ((portIndex != OUTPUT_PORT_INDEX)) {
1459             ret = OMX_ErrorBadPortIndex;
1460             goto EXIT;
1461         } else {
1462             pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
1463             pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
1464         }
1465     }
1466         break;
1467     default:
1468         ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1469         break;
1470     }
1471
1472 EXIT:
1473     FunctionOut();
1474
1475     return ret;
1476 }
1477
1478 OMX_ERRORTYPE Exynos_H264Enc_SetConfig(
1479     OMX_HANDLETYPE hComponent,
1480     OMX_INDEXTYPE nIndex,
1481     OMX_PTR pComponentConfigStructure)
1482 {
1483     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1484     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
1485     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
1486     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
1487     EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
1488
1489     FunctionIn();
1490
1491     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1492         ret = OMX_ErrorBadParameter;
1493         goto EXIT;
1494     }
1495     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1496     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1497     if (ret != OMX_ErrorNone) {
1498         goto EXIT;
1499     }
1500     if (pOMXComponent->pComponentPrivate == NULL) {
1501         ret = OMX_ErrorBadParameter;
1502         goto EXIT;
1503     }
1504     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1505     if (pExynosComponent->currentState == OMX_StateInvalid) {
1506         ret = OMX_ErrorInvalidState;
1507         goto EXIT;
1508     }
1509
1510     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1511     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1512
1513     switch ((int)nIndex) {
1514     case OMX_IndexConfigVideoIntraPeriod:
1515     {
1516         OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
1517
1518         pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
1519
1520         ret = OMX_ErrorNone;
1521     }
1522         break;
1523     case OMX_IndexConfigVideoAVCIntraPeriod:
1524     {
1525         OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1526         OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1527
1528         if ((portIndex != OUTPUT_PORT_INDEX)) {
1529             ret = OMX_ErrorBadPortIndex;
1530             goto EXIT;
1531         } else {
1532             if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1))
1533                 pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
1534             else {
1535                 ret = OMX_ErrorBadParameter;
1536                 goto EXIT;
1537             }
1538         }
1539     }
1540         break;
1541     default:
1542         ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1543         break;
1544     }
1545
1546 EXIT:
1547     if (ret == OMX_ErrorNone)
1548         pVideoEnc->configChange = OMX_TRUE;
1549
1550     FunctionOut();
1551
1552     return ret;
1553 }
1554
1555 OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex(
1556     OMX_IN OMX_HANDLETYPE  hComponent,
1557     OMX_IN OMX_STRING      cParameterName,
1558     OMX_OUT OMX_INDEXTYPE *pIndexType)
1559 {
1560     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1561     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1562     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1563
1564     FunctionIn();
1565
1566     if (hComponent == NULL) {
1567         ret = OMX_ErrorBadParameter;
1568         goto EXIT;
1569     }
1570     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1571     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1572     if (ret != OMX_ErrorNone) {
1573         goto EXIT;
1574     }
1575     if (pOMXComponent->pComponentPrivate == NULL) {
1576         ret = OMX_ErrorBadParameter;
1577         goto EXIT;
1578     }
1579     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1580     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1581         ret = OMX_ErrorBadParameter;
1582         goto EXIT;
1583     }
1584     if (pExynosComponent->currentState == OMX_StateInvalid) {
1585         ret = OMX_ErrorInvalidState;
1586         goto EXIT;
1587     }
1588     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
1589         *pIndexType = OMX_IndexConfigVideoIntraPeriod;
1590         ret = OMX_ErrorNone;
1591 #ifdef TIZEN_FEATURE_E3250
1592     } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENC_SHARED_OUTPUT_FD) == 0) {
1593         *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamSharedOutputFD;
1594         goto EXIT;
1595 #endif
1596 #ifdef USE_H264_PREPEND_SPS_PPS
1597     } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
1598         *pIndexType = OMX_IndexParamPrependSPSPPSToIDR;
1599         goto EXIT;
1600 #endif
1601     } else {
1602         ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1603     }
1604
1605 EXIT:
1606     FunctionOut();
1607
1608     return ret;
1609 }
1610
1611 OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex)
1612 {
1613     OMX_ERRORTYPE               ret              = OMX_ErrorNone;
1614
1615     FunctionIn();
1616
1617     if ((hComponent == NULL) || (cRole == NULL)) {
1618         ret = OMX_ErrorBadParameter;
1619         goto EXIT;
1620     }
1621     if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1622         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1623         ret = OMX_ErrorNone;
1624     } else {
1625         ret = OMX_ErrorNoMore;
1626     }
1627
1628 EXIT:
1629     FunctionOut();
1630
1631     return ret;
1632 }
1633
1634 /* MFC Init */
1635 OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
1636 {
1637     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1638     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1639     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1640     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1641     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1642     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;;
1643     OMX_COLOR_FORMATTYPE      eColorFormat;
1644
1645     int i = 0;
1646
1647     FunctionIn();
1648
1649     CSC_METHOD csc_method = CSC_METHOD_SW;
1650     pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1651     pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
1652     pVideoEnc->bFirstOutput = OMX_FALSE;
1653     pExynosComponent->bUseFlagEOF = OMX_TRUE;
1654     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1655
1656     eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
1657     if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
1658 #ifndef TIZEN_FEATURE_E3250 /* we do not use OMX_COLOR_FormatAndroidOpaque */
1659         if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
1660             pExynosInputPort->bufferProcessType = BUFFER_COPY;
1661         } else {
1662             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1663         }
1664 #endif
1665     } else {
1666         if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd ||
1667             eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd) {
1668             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1669         } else {
1670             pExynosInputPort->bufferProcessType = BUFFER_COPY;
1671         }
1672     }
1673
1674 #ifdef TIZEN_FEATURE_E3250
1675     if (pVideoEnc->bSharedOutputFD == OMX_TRUE) {
1676         pExynosOutputPort->bufferProcessType = BUFFER_SHARE;
1677     } else {
1678         pExynosOutputPort->bufferProcessType = BUFFER_COPY;
1679     }
1680 #endif
1681
1682     /* H.264 Codec Open */
1683     ret = H264CodecOpen(pH264Enc);
1684     if (ret != OMX_ErrorNone) {
1685         goto EXIT;
1686     }
1687
1688     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1689         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1690         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1691
1692         if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1693             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1694                 pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
1695                 /* Use ION Allocator */
1696                 /*Alloc Y-Buffer */
1697                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY);
1698                 pVideoEnc->pMFCEncInputBuffer[i]->fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
1699                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE;
1700                 /*Alloc C-Buffer */
1701                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY);
1702                 pVideoEnc->pMFCEncInputBuffer[i]->fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
1703                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
1704
1705                 pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
1706
1707                 if ((pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] == NULL) ||
1708                     (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] == NULL)) {
1709                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1710                     ret = OMX_ErrorInsufficientResources;
1711                     goto EXIT;
1712                 }
1713
1714                 /* MFC input buffers are 1 plane. */
1715                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[2] = NULL;
1716                 pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1;
1717                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0;
1718
1719                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
1720                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
1721                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
1722
1723                 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
1724             }
1725         } else {
1726             ret = H264CodecSrcInit(pOMXComponent);
1727             if (ret != OMX_ErrorNone)
1728                 goto EXIT;
1729         }
1730     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1731         /*************/
1732         /*    TBD    */
1733         /*************/
1734         /* Does not require any actions. */
1735     }
1736
1737     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1738         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1739         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1740     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1741         /*************/
1742         /*    TBD    */
1743         /*************/
1744         /* Does not require any actions. */
1745     }
1746
1747     pH264Enc->bSourceStart = OMX_FALSE;
1748     Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
1749     pH264Enc->bDestinationStart = OMX_FALSE;
1750     Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent);
1751
1752     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1753     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1754     pH264Enc->hMFCH264Handle.indexTimestamp = 0;
1755     pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
1756
1757     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1758
1759 #if 0//defined(USE_CSC_GSCALER)
1760
1761     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1762 #endif
1763     pVideoEnc->csc_handle = csc_init(csc_method);
1764     if (pVideoEnc->csc_handle == NULL) {
1765         ret = OMX_ErrorInsufficientResources;
1766         goto EXIT;
1767     }
1768     pVideoEnc->csc_set_format = OMX_FALSE;
1769
1770 EXIT:
1771     FunctionOut();
1772
1773     return ret;
1774 }
1775
1776 /* MFC Terminate */
1777 OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1778 {
1779     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1780     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1781     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1782     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1783     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1784     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1785
1786     int i = 0;
1787
1788     FunctionIn();
1789
1790     if (pVideoEnc->csc_handle != NULL) {
1791         csc_deinit(pVideoEnc->csc_handle);
1792         pVideoEnc->csc_handle = NULL;
1793     }
1794
1795     Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
1796     pH264Enc->hDestinationStartEvent = NULL;
1797     pH264Enc->bDestinationStart = OMX_FALSE;
1798     Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
1799     pH264Enc->hSourceStartEvent = NULL;
1800     pH264Enc->bSourceStart = OMX_FALSE;
1801
1802     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1803         for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1804             if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
1805 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1806                 if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] != NULL)
1807                     Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
1808 #endif
1809                 Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
1810                 pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
1811             }
1812         }
1813
1814         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1815         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1816     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1817         /*************/
1818         /*    TBD    */
1819         /*************/
1820         /* Does not require any actions. */
1821     }
1822
1823     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1824         if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1825             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1826                 if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) {
1827 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1828                     for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1829                         if (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] != NULL)
1830                             Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]);
1831                     }
1832 #endif
1833                     Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]);
1834                     pVideoEnc->pMFCEncInputBuffer[i] = NULL;
1835                 }
1836             }
1837         }
1838
1839         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1840         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1841     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1842         /*************/
1843         /*    TBD    */
1844         /*************/
1845         /* Does not require any actions. */
1846     }
1847     H264CodecClose(pH264Enc);
1848
1849     FunctionOut();
1850
1851     return ret;
1852 }
1853
1854 OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1855 {
1856     OMX_ERRORTYPE               ret = OMX_ErrorNone;
1857     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1858     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1859     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1860     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1861     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1862     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
1863     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1864     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1865     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1866
1867     FunctionIn();
1868
1869     if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1870         ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1871 //        if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
1872         if (ret != OMX_ErrorNone)
1873             goto EXIT;
1874     }
1875     if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1876         ret = H264CodecDstSetup(pOMXComponent);
1877     }
1878     if (pVideoEnc->configChange == OMX_TRUE) {
1879         Change_H264Enc_Param(pExynosComponent);
1880         pVideoEnc->configChange = OMX_FALSE;
1881     }
1882
1883     if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
1884         OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE]  = {0, };
1885         ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
1886         int plane;
1887
1888         pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1889         pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1890         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags);
1891         pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
1892         pH264Enc->hMFCH264Handle.indexTimestamp++;
1893         pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1894
1895         /* queue work for input buffer */
1896         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
1897             pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
1898             pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
1899
1900 //#define INPUT_FILE_DUMP
1901 #ifdef INPUT_FILE_DUMP
1902             {
1903                 FILE *pf;
1904                 char filename[100];
1905                 static int tmp_cnt=0;
1906                 int w = pExynosInputPort->portDefinition.format.video.nFrameWidth;
1907                 int h = pExynosInputPort->portDefinition.format.video.nFrameHeight;
1908
1909                 memset(filename, 0x00, sizeof(filename));
1910                 sprintf(filename, "/tmp/enc_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt);
1911                 pf = fopen(filename, "wb");
1912                 if (pf == NULL) {
1913                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] filepoint NULL!");
1914                 } else {
1915                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] fwrite[%d] ", tmp_cnt);
1916                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0], sizeof(char), h * w, pf);
1917                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1], sizeof(char), h * w / 2, pf);
1918                 }
1919                 fclose(pf);
1920             }
1921 #endif
1922
1923         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1924                                     (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1925 //#ifdef USE_METADATABUFFERTYPE
1926         if ((codecReturn == VIDEO_ERROR_NOBUFFERS) &&
1927             /*(pExynosInputPort->bStoreMetaData == OMX_TRUE) &&*/
1928             (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) {
1929             OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
1930             nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
1931                                 ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
1932             nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
1933             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1934                 planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane];
1935                 planes[plane].allocSize = nAllocLen[plane];
1936                 planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane];
1937             }
1938
1939             /* Register input buffer */
1940             if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1941                         planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1942                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1943                 ret = OMX_ErrorInsufficientResources;
1944                 goto EXIT;
1945             }
1946
1947             codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1948                                         (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1949
1950         }
1951 //#endif
1952         if (codecReturn != VIDEO_ERROR_NONE) {
1953             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
1954             ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1955             goto EXIT;
1956         }
1957         H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1958         if (pH264Enc->bSourceStart == OMX_FALSE) {
1959             pH264Enc->bSourceStart = OMX_TRUE;
1960             Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
1961             Exynos_OSAL_SleepMillisec(0);
1962         }
1963         if (pH264Enc->bDestinationStart == OMX_FALSE) {
1964             pH264Enc->bDestinationStart = OMX_TRUE;
1965             Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
1966             Exynos_OSAL_SleepMillisec(0);
1967         }
1968     }
1969
1970     ret = OMX_ErrorNone;
1971
1972 EXIT:
1973     FunctionOut();
1974
1975     return ret;
1976 }
1977
1978 OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1979 {
1980     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1981     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1982     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1983     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1984     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1985     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1986     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1987     ExynosVideoBuffer       *pVideoBuffer;
1988
1989     FunctionIn();
1990
1991     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1992
1993     pSrcOutputData->dataLen       = 0;
1994     pSrcOutputData->usedDataLen   = 0;
1995     pSrcOutputData->remainDataLen = 0;
1996     pSrcOutputData->nFlags    = 0;
1997     pSrcOutputData->timeStamp = 0;
1998
1999     if (pVideoBuffer == NULL) {
2000         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2001         pSrcOutputData->allocSize  = 0;
2002         pSrcOutputData->pPrivate = NULL;
2003         pSrcOutputData->bufferHeader = NULL;
2004     } else {
2005         int plane = 0;
2006         for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2007             pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2008             pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2009         }
2010         pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
2011                                         pVideoBuffer->planes[1].allocSize +
2012                                         pVideoBuffer->planes[2].allocSize;
2013
2014         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2015             int i = 0;
2016             while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
2017                 i++;
2018                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2019                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
2020                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2021                     goto EXIT;
2022                 }
2023             }
2024             pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
2025             pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
2026         }
2027
2028         /* For Share Buffer */
2029         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2030     }
2031
2032     ret = OMX_ErrorNone;
2033
2034 EXIT:
2035     FunctionOut();
2036
2037     return ret;
2038 }
2039
2040 OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2041 {
2042     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2043     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2044     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2045     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2046     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2047     OMX_U32 dataLen = 0;
2048     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2049
2050     FunctionIn();
2051
2052     if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) {
2053         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2054         ret = OMX_ErrorBadParameter;
2055         goto EXIT;
2056     }
2057
2058     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
2059                      (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2060
2061     if (codecReturn != VIDEO_ERROR_NONE) {
2062         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
2063         ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2064         goto EXIT;
2065     }
2066     H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2067
2068     ret = OMX_ErrorNone;
2069
2070 EXIT:
2071     FunctionOut();
2072
2073     return ret;
2074 }
2075
2076 OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2077 {
2078     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2079     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2080     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2081     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2082     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2083     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
2084     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2085     ExynosVideoBuffer       *pVideoBuffer;
2086     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2087     OMX_S32 indexTimestamp = 0;
2088
2089     FunctionIn();
2090
2091     if (pH264Enc->bDestinationStart == OMX_FALSE) {
2092         ret = OMX_ErrorNone;
2093         goto EXIT;
2094     }
2095
2096     if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
2097         ret = OMX_ErrorNone;
2098         goto EXIT;
2099     }
2100
2101     pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
2102     pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2103
2104     pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2105     pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2106     pDstOutputData->allocSize   = pVideoBuffer->planes[0].allocSize;
2107     pDstOutputData->dataLen     = pVideoBuffer->planes[0].dataSize;
2108     pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize;
2109     pDstOutputData->usedDataLen = 0;
2110     pDstOutputData->pPrivate = pVideoBuffer;
2111     /* For Share Buffer */
2112     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2113
2114     if (pVideoEnc->bFirstOutput == OMX_FALSE) {
2115         if (pVideoEnc->bSharedOutputFD == OMX_FALSE) {
2116             OMX_U8 *p = NULL;
2117             int iSpsSize = 0;
2118             int iPpsSize = 0;
2119
2120             /* Calculate sps/pps size if needed */
2121             p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4),
2122                                 pDstOutputData->dataLen - 4);
2123
2124             iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2125             pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
2126                 (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2127             pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
2128
2129             iPpsSize = pDstOutputData->dataLen - iSpsSize;
2130             pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
2131                 (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize;
2132             pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
2133         }
2134         pDstOutputData->timeStamp = 0;
2135         pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
2136         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2137         pVideoEnc->bFirstOutput = OMX_TRUE;
2138     } else {
2139         indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
2140         if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2141             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2142             pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2143         } else {
2144             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2145             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2146         }
2147
2148         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2149         if (pVideoBuffer->frameType == VIDEO_FRAME_I)
2150             pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2151     }
2152
2153     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2154         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2155         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags);
2156         pDstOutputData->remainDataLen = 0;
2157     }
2158
2159     ret = OMX_ErrorNone;
2160
2161 EXIT:
2162     FunctionOut();
2163
2164     return ret;
2165 }
2166
2167 OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2168 {
2169     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2170     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2171     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2172
2173     FunctionIn();
2174
2175     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2176         ret = OMX_ErrorNone;
2177         goto EXIT;
2178     }
2179     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2180         ret = OMX_ErrorNone;
2181         goto EXIT;
2182     }
2183
2184     ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
2185     if (ret != OMX_ErrorNone) {
2186         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
2187         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2188                                                 pExynosComponent->callbackData,
2189                                                 OMX_EventError, ret, 0, NULL);
2190     }
2191
2192 EXIT:
2193     FunctionOut();
2194
2195     return ret;
2196 }
2197
2198 OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2199 {
2200     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2201     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2202     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2203     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2204
2205     FunctionIn();
2206
2207     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2208         ret = OMX_ErrorNone;
2209         goto EXIT;
2210     }
2211
2212     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2213         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2214             ret = OMX_ErrorNone;
2215             goto EXIT;
2216         }
2217     }
2218     if ((pH264Enc->bSourceStart == OMX_FALSE) &&
2219        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2220         Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2221         Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
2222     }
2223
2224     ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
2225     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2226         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
2227         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2228                                                 pExynosComponent->callbackData,
2229                                                 OMX_EventError, ret, 0, NULL);
2230     }
2231
2232 EXIT:
2233     FunctionOut();
2234
2235     return ret;
2236 }
2237
2238 OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2239 {
2240     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2241     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2242     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2243     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2244
2245     FunctionIn();
2246
2247     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2248         ret = OMX_ErrorNone;
2249         goto EXIT;
2250     }
2251     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2252         ret = OMX_ErrorNone;
2253         goto EXIT;
2254     }
2255     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2256         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2257            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2258             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2259             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2260         }
2261     }
2262     if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2263         ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
2264         if (ret != OMX_ErrorNone) {
2265             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
2266             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2267                                                 pExynosComponent->callbackData,
2268                                                 OMX_EventError, ret, 0, NULL);
2269         }
2270     }
2271
2272 EXIT:
2273     FunctionOut();
2274
2275     return ret;
2276 }
2277
2278 OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2279 {
2280     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2281     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2282     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2283     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2284
2285     FunctionIn();
2286
2287     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2288         ret = OMX_ErrorNone;
2289         goto EXIT;
2290     }
2291     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2292         ret = OMX_ErrorNone;
2293         goto EXIT;
2294     }
2295
2296     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2297         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2298            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2299             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2300             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2301         }
2302     }
2303     ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
2304     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2305         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
2306         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2307                                                 pExynosComponent->callbackData,
2308                                                 OMX_EventError, ret, 0, NULL);
2309     }
2310
2311 EXIT:
2312     FunctionOut();
2313
2314     return ret;
2315 }
2316
2317 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2318     OMX_HANDLETYPE hComponent,
2319     OMX_STRING     componentName)
2320 {
2321     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2322     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2323     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2324     EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2325     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
2326     EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
2327     int i = 0;
2328
2329     FunctionIn();
2330
2331     if ((hComponent == NULL) || (componentName == NULL)) {
2332         ret = OMX_ErrorBadParameter;
2333         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2334         goto EXIT;
2335     }
2336     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) {
2337         ret = OMX_ErrorBadParameter;
2338         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2339         goto EXIT;
2340     }
2341
2342     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2343     ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
2344     if (ret != OMX_ErrorNone) {
2345         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2346         goto EXIT;
2347     }
2348     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2349     pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
2350
2351     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2352     if (pExynosComponent->componentName == NULL) {
2353         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2354         ret = OMX_ErrorInsufficientResources;
2355         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2356         goto EXIT;
2357     }
2358     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2359
2360     pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
2361     if (pH264Enc == NULL) {
2362         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2363         ret = OMX_ErrorInsufficientResources;
2364         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2365         goto EXIT;
2366     }
2367     Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
2368     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2369     pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
2370     pVideoEnc->quantization.nQpI = 20;
2371     pVideoEnc->quantization.nQpP = 20;
2372     pVideoEnc->quantization.nQpB = 20;
2373     pVideoEnc->bSharedOutputFD = OMX_FALSE;
2374
2375     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
2376
2377     /* In case of BUFFER_COPY mode
2378             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2379             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2380          In case of BUFFER_SHARE
2381             bShareableBuf should be TRUE, FALSE is ignored
2382     */
2383     pH264Enc->hMFCH264Handle.bShareableBuf = OMX_FALSE; //Check bStoreMetaData in Init function
2384     /* Set componentVersion */
2385     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2386     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2387     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2388     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2389     /* Set specVersion */
2390     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2391     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2392     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2393     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2394
2395     /* Input port */
2396     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2397     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2398     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2399     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2400     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2401     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2402     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2403     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2404 #ifdef TIZEN_FEATURE_E3250
2405     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2406 #else
2407     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2408 #endif
2409     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2410     pExynosPort->bufferProcessType = BUFFER_COPY;
2411     pExynosPort->portWayType = WAY2_PORT;
2412
2413     /* Output port */
2414     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2415     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2416     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2417     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2418     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2419     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2420     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2421     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2422     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2423     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2424     pExynosPort->bufferProcessType = BUFFER_COPY;
2425     pExynosPort->portWayType = WAY2_PORT;
2426
2427     for(i = 0; i < ALL_PORT_NUM; i++) {
2428         INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2429         pH264Enc->AVCComponent[i].nPortIndex = i;
2430         pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2431         pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
2432
2433         pH264Enc->AVCComponent[i].nPFrames = 20;
2434     }
2435
2436     pOMXComponent->GetParameter      = &Exynos_H264Enc_GetParameter;
2437     pOMXComponent->SetParameter      = &Exynos_H264Enc_SetParameter;
2438     pOMXComponent->GetConfig         = &Exynos_H264Enc_GetConfig;
2439     pOMXComponent->SetConfig         = &Exynos_H264Enc_SetConfig;
2440     pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
2441     pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
2442     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2443
2444     pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Enc_Init;
2445     pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
2446
2447     pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_H264Enc_srcInputBufferProcess;
2448     pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
2449     pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_H264Enc_dstInputBufferProcess;
2450     pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
2451
2452     pVideoEnc->exynos_codec_start         = &H264CodecStart;
2453     pVideoEnc->exynos_codec_stop          = &H264CodecStop;
2454     pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2455     pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnqueueAllBuffer;
2456
2457     pVideoEnc->exynos_checkInputFrame        = NULL;
2458     pVideoEnc->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2459     pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2460
2461 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2462     pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2463     if (pVideoEnc->hSharedMemory == NULL) {
2464         Exynos_OSAL_Free(pH264Enc);
2465         pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2466         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2467         ret = OMX_ErrorInsufficientResources;
2468         goto EXIT;
2469     }
2470 #endif
2471     pExynosComponent->currentState = OMX_StateLoaded;
2472
2473     ret = OMX_ErrorNone;
2474
2475 EXIT:
2476     FunctionOut();
2477
2478     return ret;
2479 }
2480
2481 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2482 {
2483     OMX_ERRORTYPE            ret = OMX_ErrorNone;
2484     OMX_COMPONENTTYPE          *pOMXComponent = NULL;
2485     EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
2486     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
2487     EXYNOS_H264ENC_HANDLE      *pH264Enc         = NULL;
2488
2489     FunctionIn();
2490
2491     if (hComponent == NULL) {
2492         ret = OMX_ErrorBadParameter;
2493         goto EXIT;
2494     }
2495     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2496     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2497     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2498 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2499     Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
2500 #endif
2501     Exynos_OSAL_Free(pExynosComponent->componentName);
2502     pExynosComponent->componentName = NULL;
2503
2504     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
2505     if (pH264Enc != NULL) {
2506         Exynos_OSAL_Free(pH264Enc);
2507         pH264Enc = pVideoEnc->hCodecHandle = NULL;
2508     }
2509
2510     ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2511     if (ret != OMX_ErrorNone) {
2512         goto EXIT;
2513     }
2514
2515     ret = OMX_ErrorNone;
2516
2517 EXIT:
2518     FunctionOut();
2519
2520     return ret;
2521 }