fixed coverity issues
[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 ALLOC_FAILED:
1085     for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1086         if (pVideoEnc->pMFCEncOutputBuffer[i])
1087             Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
1088     }
1089     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to allocate buffers");
1090     FunctionOut();
1091
1092     return ret;
1093 }
1094
1095 OMX_ERRORTYPE Exynos_H264Enc_GetParameter(
1096     OMX_IN OMX_HANDLETYPE hComponent,
1097     OMX_IN OMX_INDEXTYPE  nParamIndex,
1098     OMX_INOUT OMX_PTR     pComponentParameterStructure)
1099 {
1100     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1101     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1102     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1103
1104     FunctionIn();
1105
1106     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1107         ret = OMX_ErrorBadParameter;
1108         goto EXIT;
1109     }
1110     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1111     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1112     if (ret != OMX_ErrorNone) {
1113         goto EXIT;
1114     }
1115     if (pOMXComponent->pComponentPrivate == NULL) {
1116         ret = OMX_ErrorBadParameter;
1117         goto EXIT;
1118     }
1119
1120     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1121     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1122         ret = OMX_ErrorInvalidState;
1123         goto EXIT;
1124     }
1125
1126     switch (nParamIndex) {
1127     case OMX_IndexParamVideoAvc:
1128     {
1129         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1130         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1131         EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
1132
1133         ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1134         if (ret != OMX_ErrorNone) {
1135             goto EXIT;
1136         }
1137
1138         if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1139             ret = OMX_ErrorBadPortIndex;
1140             goto EXIT;
1141         }
1142
1143         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1144         pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
1145
1146         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1147     }
1148         break;
1149
1150     case  OMX_IndexParamVideoSliceFMO:
1151     {
1152         OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
1153         OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = NULL;
1154         EXYNOS_H264ENC_HANDLE       *pH264Enc = NULL;
1155
1156         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1157         pSrcSliceFmo = &pH264Enc->AVCSliceFmo;
1158
1159         Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
1160     }
1161         break;
1162
1163     case OMX_IndexParamStandardComponentRole:
1164     {
1165         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
1166         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1167         if (ret != OMX_ErrorNone) {
1168             goto EXIT;
1169         }
1170
1171         Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1172     }
1173         break;
1174     case OMX_IndexParamVideoProfileLevelQuerySupported:
1175     {
1176         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1177         EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
1178         OMX_U32 maxProfileLevelNum = 0;
1179
1180         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1181         if (ret != OMX_ErrorNone) {
1182             goto EXIT;
1183         }
1184
1185         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1186             ret = OMX_ErrorBadPortIndex;
1187             goto EXIT;
1188         }
1189
1190         pProfileLevel = supportedAVCProfileLevels;
1191         maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
1192
1193         if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
1194             ret = OMX_ErrorNoMore;
1195             goto EXIT;
1196         }
1197
1198         pProfileLevel += pDstProfileLevel->nProfileIndex;
1199         pDstProfileLevel->eProfile = pProfileLevel->profile;
1200         pDstProfileLevel->eLevel = pProfileLevel->level;
1201     }
1202         break;
1203     case OMX_IndexParamVideoProfileLevelCurrent:
1204     {
1205         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
1206         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
1207         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1208
1209         ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1210         if (ret != OMX_ErrorNone) {
1211             goto EXIT;
1212         }
1213
1214         if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1215             ret = OMX_ErrorBadPortIndex;
1216             goto EXIT;
1217         }
1218
1219         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1220         pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
1221
1222         pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
1223         pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
1224     }
1225         break;
1226     case OMX_IndexParamVideoErrorCorrection:
1227     {
1228         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1229         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
1230         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1231
1232         ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1233         if (ret != OMX_ErrorNone) {
1234             goto EXIT;
1235         }
1236
1237         if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1238             ret = OMX_ErrorBadPortIndex;
1239             goto EXIT;
1240         }
1241
1242         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1243         pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1244
1245         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1246         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1247         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1248         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1249         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1250     }
1251         break;
1252     default:
1253         ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1254         break;
1255     }
1256 EXIT:
1257     FunctionOut();
1258
1259     return ret;
1260 }
1261
1262 OMX_ERRORTYPE Exynos_H264Enc_SetParameter(
1263     OMX_IN OMX_HANDLETYPE hComponent,
1264     OMX_IN OMX_INDEXTYPE  nIndex,
1265     OMX_IN OMX_PTR        pComponentParameterStructure)
1266 {
1267     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1268     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1269     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1270
1271     FunctionIn();
1272
1273     if (hComponent == NULL || pComponentParameterStructure == NULL) {
1274         ret = OMX_ErrorBadParameter;
1275         goto EXIT;
1276     }
1277     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1278     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1279     if (ret != OMX_ErrorNone) {
1280         goto EXIT;
1281     }
1282     if (pOMXComponent->pComponentPrivate == NULL) {
1283         ret = OMX_ErrorBadParameter;
1284         goto EXIT;
1285     }
1286
1287     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1288     if (pExynosComponent->currentState == OMX_StateInvalid ) {
1289         ret = OMX_ErrorInvalidState;
1290         goto EXIT;
1291     }
1292
1293     switch ((int)nIndex) {
1294     case OMX_IndexParamVideoAvc:
1295     {
1296         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1297         OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1298         EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
1299
1300         ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1301         if (ret != OMX_ErrorNone) {
1302             goto EXIT;
1303         }
1304
1305         if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1306             ret = OMX_ErrorBadPortIndex;
1307             goto EXIT;
1308         }
1309
1310         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1311         pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
1312
1313         Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1314     }
1315         break;
1316     case  OMX_IndexParamVideoSliceFMO:
1317     {
1318         OMX_VIDEO_PARAM_AVCSLICEFMO *pDstSliceFmo = NULL;
1319         OMX_VIDEO_PARAM_AVCSLICEFMO *pSrcSliceFmo = (OMX_VIDEO_PARAM_AVCSLICEFMO *)pComponentParameterStructure;
1320         EXYNOS_H264ENC_HANDLE       *pH264Enc = NULL;
1321
1322         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1323         pDstSliceFmo = &pH264Enc->AVCSliceFmo;
1324
1325         Exynos_OSAL_Memcpy(pDstSliceFmo, pSrcSliceFmo, sizeof(OMX_VIDEO_PARAM_AVCSLICEFMO));
1326     }
1327         break;
1328
1329     case OMX_IndexParamStandardComponentRole:
1330     {
1331         OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1332
1333         ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1334         if (ret != OMX_ErrorNone) {
1335             goto EXIT;
1336         }
1337
1338         if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1339             ret = OMX_ErrorIncorrectStateOperation;
1340             goto EXIT;
1341         }
1342
1343         if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE)) {
1344             pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1345         } else {
1346             ret = OMX_ErrorBadParameter;
1347             goto EXIT;
1348         }
1349     }
1350         break;
1351     case OMX_IndexParamVideoProfileLevelCurrent:
1352     {
1353         OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1354         OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1355         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1356
1357         ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1358         if (ret != OMX_ErrorNone)
1359             goto EXIT;
1360
1361         if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1362             ret = OMX_ErrorBadPortIndex;
1363             goto EXIT;
1364         }
1365
1366         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1367
1368         pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
1369         pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1370         pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1371     }
1372         break;
1373     case OMX_IndexParamVideoErrorCorrection:
1374     {
1375         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1376         OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1377         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1378
1379         ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1380         if (ret != OMX_ErrorNone) {
1381             goto EXIT;
1382         }
1383
1384         if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1385             ret = OMX_ErrorBadPortIndex;
1386             goto EXIT;
1387         }
1388
1389         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1390         pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1391
1392         pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1393         pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1394         pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1395         pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1396         pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1397     }
1398         break;
1399 #ifdef USE_H264_PREPEND_SPS_PPS
1400     case OMX_IndexParamPrependSPSPPSToIDR:
1401     {
1402         EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1403
1404         pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1405         pH264Enc->hMFCH264Handle.bPrependSpsPpsToIdr = OMX_TRUE;
1406     }
1407         break;
1408 #endif
1409 #ifdef TIZEN_FEATURE_E3250
1410     case OMX_IndexParamSharedOutputFD:
1411     {
1412         EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
1413         pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1414
1415         pVideoEnc->bSharedOutputFD = OMX_TRUE;
1416     }
1417         break;
1418 #endif
1419
1420     default:
1421         ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1422         break;
1423     }
1424 EXIT:
1425     FunctionOut();
1426
1427     return ret;
1428 }
1429
1430 OMX_ERRORTYPE Exynos_H264Enc_GetConfig(
1431     OMX_HANDLETYPE hComponent,
1432     OMX_INDEXTYPE nIndex,
1433     OMX_PTR pComponentConfigStructure)
1434 {
1435     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1436     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1437     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1438     EXYNOS_H264ENC_HANDLE    *pH264Enc         = NULL;
1439
1440     FunctionIn();
1441
1442     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1443         ret = OMX_ErrorBadParameter;
1444         goto EXIT;
1445     }
1446     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1447     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1448     if (ret != OMX_ErrorNone) {
1449         goto EXIT;
1450     }
1451     if (pOMXComponent->pComponentPrivate == NULL) {
1452         ret = OMX_ErrorBadParameter;
1453         goto EXIT;
1454     }
1455     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1456     if (pExynosComponent->currentState == OMX_StateInvalid) {
1457         ret = OMX_ErrorInvalidState;
1458         goto EXIT;
1459     }
1460     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1461
1462     switch (nIndex) {
1463     case OMX_IndexConfigVideoAVCIntraPeriod:
1464     {
1465         OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1466         OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1467
1468         if ((portIndex != OUTPUT_PORT_INDEX)) {
1469             ret = OMX_ErrorBadPortIndex;
1470             goto EXIT;
1471         } else {
1472             pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
1473             pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
1474         }
1475     }
1476         break;
1477     default:
1478         ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1479         break;
1480     }
1481
1482 EXIT:
1483     FunctionOut();
1484
1485     return ret;
1486 }
1487
1488 OMX_ERRORTYPE Exynos_H264Enc_SetConfig(
1489     OMX_HANDLETYPE hComponent,
1490     OMX_INDEXTYPE nIndex,
1491     OMX_PTR pComponentConfigStructure)
1492 {
1493     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1494     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
1495     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
1496     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
1497     EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
1498
1499     FunctionIn();
1500
1501     if (hComponent == NULL || pComponentConfigStructure == NULL) {
1502         ret = OMX_ErrorBadParameter;
1503         goto EXIT;
1504     }
1505     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1506     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1507     if (ret != OMX_ErrorNone) {
1508         goto EXIT;
1509     }
1510     if (pOMXComponent->pComponentPrivate == NULL) {
1511         ret = OMX_ErrorBadParameter;
1512         goto EXIT;
1513     }
1514     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1515     if (pExynosComponent->currentState == OMX_StateInvalid) {
1516         ret = OMX_ErrorInvalidState;
1517         goto EXIT;
1518     }
1519
1520     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1521     pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1522
1523     switch ((int)nIndex) {
1524     case OMX_IndexConfigVideoIntraPeriod:
1525     {
1526         OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
1527
1528         pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
1529
1530         ret = OMX_ErrorNone;
1531     }
1532         break;
1533     case OMX_IndexConfigVideoAVCIntraPeriod:
1534     {
1535         OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1536         OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1537
1538         if ((portIndex != OUTPUT_PORT_INDEX)) {
1539             ret = OMX_ErrorBadPortIndex;
1540             goto EXIT;
1541         } else {
1542             if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1))
1543                 pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
1544             else {
1545                 ret = OMX_ErrorBadParameter;
1546                 goto EXIT;
1547             }
1548         }
1549     }
1550         break;
1551     default:
1552         ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1553         break;
1554     }
1555
1556 EXIT:
1557     if (ret == OMX_ErrorNone)
1558         pVideoEnc->configChange = OMX_TRUE;
1559
1560     FunctionOut();
1561
1562     return ret;
1563 }
1564
1565 OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex(
1566     OMX_IN OMX_HANDLETYPE  hComponent,
1567     OMX_IN OMX_STRING      cParameterName,
1568     OMX_OUT OMX_INDEXTYPE *pIndexType)
1569 {
1570     OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1571     OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1572     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1573
1574     FunctionIn();
1575
1576     if (hComponent == NULL) {
1577         ret = OMX_ErrorBadParameter;
1578         goto EXIT;
1579     }
1580     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1581     ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1582     if (ret != OMX_ErrorNone) {
1583         goto EXIT;
1584     }
1585     if (pOMXComponent->pComponentPrivate == NULL) {
1586         ret = OMX_ErrorBadParameter;
1587         goto EXIT;
1588     }
1589     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1590     if ((cParameterName == NULL) || (pIndexType == NULL)) {
1591         ret = OMX_ErrorBadParameter;
1592         goto EXIT;
1593     }
1594     if (pExynosComponent->currentState == OMX_StateInvalid) {
1595         ret = OMX_ErrorInvalidState;
1596         goto EXIT;
1597     }
1598     if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
1599         *pIndexType = OMX_IndexConfigVideoIntraPeriod;
1600         ret = OMX_ErrorNone;
1601 #ifdef TIZEN_FEATURE_E3250
1602     } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_ENC_SHARED_OUTPUT_FD) == 0) {
1603         *pIndexType = (OMX_INDEXTYPE) OMX_IndexParamSharedOutputFD;
1604         goto EXIT;
1605 #endif
1606 #ifdef USE_H264_PREPEND_SPS_PPS
1607     } else if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_PARAM_PREPEND_SPSPPS_TO_IDR) == 0) {
1608         *pIndexType = OMX_IndexParamPrependSPSPPSToIDR;
1609         goto EXIT;
1610 #endif
1611     } else {
1612         ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1613     }
1614
1615 EXIT:
1616     FunctionOut();
1617
1618     return ret;
1619 }
1620
1621 OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex)
1622 {
1623     OMX_ERRORTYPE               ret              = OMX_ErrorNone;
1624
1625     FunctionIn();
1626
1627     if ((hComponent == NULL) || (cRole == NULL)) {
1628         ret = OMX_ErrorBadParameter;
1629         goto EXIT;
1630     }
1631     if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1632         Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1633         ret = OMX_ErrorNone;
1634     } else {
1635         ret = OMX_ErrorNoMore;
1636     }
1637
1638 EXIT:
1639     FunctionOut();
1640
1641     return ret;
1642 }
1643
1644 /* MFC Init */
1645 OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
1646 {
1647     OMX_ERRORTYPE             ret = OMX_ErrorNone;
1648     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1649     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1650     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1651     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1652     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;;
1653     OMX_COLOR_FORMATTYPE      eColorFormat;
1654
1655     int i = 0;
1656
1657     FunctionIn();
1658
1659     CSC_METHOD csc_method = CSC_METHOD_SW;
1660     pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1661     pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
1662     pVideoEnc->bFirstOutput = OMX_FALSE;
1663     pExynosComponent->bUseFlagEOF = OMX_TRUE;
1664     pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1665
1666     eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
1667     if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
1668 #ifndef TIZEN_FEATURE_E3250 /* we do not use OMX_COLOR_FormatAndroidOpaque */
1669         if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
1670             pExynosInputPort->bufferProcessType = BUFFER_COPY;
1671         } else {
1672             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1673         }
1674 #endif
1675     } else {
1676         if (eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd ||
1677             eColorFormat == (OMX_COLOR_FORMATTYPE)OMX_SEC_COLOR_FormatNV12T_DmaBuf_Fd) {
1678             pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1679         } else {
1680             pExynosInputPort->bufferProcessType = BUFFER_COPY;
1681         }
1682     }
1683
1684 #ifdef TIZEN_FEATURE_E3250
1685     if (pVideoEnc->bSharedOutputFD == OMX_TRUE) {
1686         pExynosOutputPort->bufferProcessType = BUFFER_SHARE;
1687     } else {
1688         pExynosOutputPort->bufferProcessType = BUFFER_COPY;
1689     }
1690 #endif
1691
1692     /* H.264 Codec Open */
1693     ret = H264CodecOpen(pH264Enc);
1694     if (ret != OMX_ErrorNone) {
1695         goto EXIT;
1696     }
1697
1698     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1699         Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1700         Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1701
1702         if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1703             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1704                 pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_BUFFER));
1705                 /* Use ION Allocator */
1706                 /*Alloc Y-Buffer */
1707                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY);
1708                 pVideoEnc->pMFCEncInputBuffer[i]->fd[0] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
1709                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[0] = DEFAULT_MFC_INPUT_YBUFFER_SIZE;
1710                 /*Alloc C-Buffer */
1711                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY);
1712                 pVideoEnc->pMFCEncInputBuffer[i]->fd[1] = Exynos_OSAL_SharedMemory_VirtToION(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
1713                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[1] = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
1714
1715                 pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
1716
1717                 if ((pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0] == NULL) ||
1718                     (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1] == NULL)) {
1719                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1720                     ret = OMX_ErrorInsufficientResources;
1721                     goto EXIT;
1722                 }
1723
1724                 /* MFC input buffers are 1 plane. */
1725                 pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[2] = NULL;
1726                 pVideoEnc->pMFCEncInputBuffer[i]->fd[2] = -1;
1727                 pVideoEnc->pMFCEncInputBuffer[i]->bufferSize[2] = 0;
1728
1729                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
1730                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[0]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]);
1731                 Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->pVirAddr[1]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[1]);
1732
1733                 Exynos_CodecBufferEnqueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
1734             }
1735         } else {
1736             ret = H264CodecSrcInit(pOMXComponent);
1737             if (ret != OMX_ErrorNone)
1738                 goto EXIT;
1739         }
1740     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1741         /*************/
1742         /*    TBD    */
1743         /*************/
1744         /* Does not require any actions. */
1745     }
1746
1747     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1748         Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1749         Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1750     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1751         /*************/
1752         /*    TBD    */
1753         /*************/
1754         /* Does not require any actions. */
1755     }
1756
1757     pH264Enc->bSourceStart = OMX_FALSE;
1758     Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
1759     pH264Enc->bDestinationStart = OMX_FALSE;
1760     Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent);
1761
1762     Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1763     Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1764     pH264Enc->hMFCH264Handle.indexTimestamp = 0;
1765     pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
1766
1767     pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1768
1769 #if 0//defined(USE_CSC_GSCALER)
1770
1771     csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1772 #endif
1773     pVideoEnc->csc_handle = csc_init(csc_method);
1774     if (pVideoEnc->csc_handle == NULL) {
1775         ret = OMX_ErrorInsufficientResources;
1776         goto EXIT;
1777     }
1778     pVideoEnc->csc_set_format = OMX_FALSE;
1779
1780 EXIT:
1781     FunctionOut();
1782
1783     return ret;
1784 }
1785
1786 /* MFC Terminate */
1787 OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1788 {
1789     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1790     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1791     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1792     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1793     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1794     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1795
1796     int i = 0;
1797
1798     FunctionIn();
1799
1800     if (pVideoEnc->csc_handle != NULL) {
1801         csc_deinit(pVideoEnc->csc_handle);
1802         pVideoEnc->csc_handle = NULL;
1803     }
1804
1805     Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
1806     pH264Enc->hDestinationStartEvent = NULL;
1807     pH264Enc->bDestinationStart = OMX_FALSE;
1808     Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
1809     pH264Enc->hSourceStartEvent = NULL;
1810     pH264Enc->bSourceStart = OMX_FALSE;
1811
1812     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
1813         for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1814             if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
1815 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1816                 if (pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0] != NULL)
1817                     Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->pVirAddr[0]);
1818 #endif
1819                 Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
1820                 pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
1821             }
1822         }
1823
1824         Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1825         Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1826     } else if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
1827         /*************/
1828         /*    TBD    */
1829         /*************/
1830         /* Does not require any actions. */
1831     }
1832
1833     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
1834         if (pH264Enc->hMFCH264Handle.bShareableBuf == OMX_TRUE) {
1835             for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1836                 if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) {
1837 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
1838                     for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1839                         if (pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane] != NULL)
1840                             Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[plane]);
1841                     }
1842 #endif
1843                     Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]);
1844                     pVideoEnc->pMFCEncInputBuffer[i] = NULL;
1845                 }
1846             }
1847         }
1848
1849         Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1850         Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1851     } else if (pExynosInputPort->bufferProcessType & BUFFER_SHARE) {
1852         /*************/
1853         /*    TBD    */
1854         /*************/
1855         /* Does not require any actions. */
1856     }
1857     H264CodecClose(pH264Enc);
1858
1859     FunctionOut();
1860
1861     return ret;
1862 }
1863
1864 OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1865 {
1866     OMX_ERRORTYPE               ret = OMX_ErrorNone;
1867     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1868     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1869     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1870     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1871     EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1872     OMX_U32  oneFrameSize = pSrcInputData->dataLen;
1873     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1874     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1875     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1876
1877     FunctionIn();
1878
1879     if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1880         ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1881 //        if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)
1882         if (ret != OMX_ErrorNone)
1883             goto EXIT;
1884     }
1885     if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1886         ret = H264CodecDstSetup(pOMXComponent);
1887
1888         if (ret != OMX_ErrorNone)
1889             goto EXIT;
1890     }
1891     if (pVideoEnc->configChange == OMX_TRUE) {
1892         Change_H264Enc_Param(pExynosComponent);
1893         pVideoEnc->configChange = OMX_FALSE;
1894     }
1895
1896     if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
1897         OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE]  = {0, };
1898         ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
1899         int plane;
1900
1901         pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1902         pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1903         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);
1904         pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
1905         pH264Enc->hMFCH264Handle.indexTimestamp++;
1906         pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1907
1908         /* queue work for input buffer */
1909         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
1910             pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
1911             pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
1912
1913 //#define INPUT_FILE_DUMP
1914 #ifdef INPUT_FILE_DUMP
1915             {
1916                 FILE *pf;
1917                 char filename[100];
1918                 static int tmp_cnt=0;
1919                 int w = pExynosInputPort->portDefinition.format.video.nFrameWidth;
1920                 int h = pExynosInputPort->portDefinition.format.video.nFrameHeight;
1921
1922                 memset(filename, 0x00, sizeof(filename));
1923                 sprintf(filename, "/tmp/enc_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt);
1924                 pf = fopen(filename, "wb");
1925                 if (pf == NULL) {
1926                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] filepoint NULL!");
1927                 } else {
1928                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] fwrite[%d] ", tmp_cnt);
1929                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0], sizeof(char), h * w, pf);
1930                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1], sizeof(char), h * w / 2, pf);
1931                 }
1932                 fclose(pf);
1933             }
1934 #endif
1935
1936         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1937                                     (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1938 //#ifdef USE_METADATABUFFERTYPE
1939         if ((codecReturn == VIDEO_ERROR_NOBUFFERS) &&
1940             /*(pExynosInputPort->bStoreMetaData == OMX_TRUE) &&*/
1941             (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) {
1942             OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
1943             nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
1944                                 ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
1945             nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
1946             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1947                 planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane];
1948                 planes[plane].allocSize = nAllocLen[plane];
1949                 planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane];
1950             }
1951
1952             /* Register input buffer */
1953             if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1954                         planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1955                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1956                 ret = OMX_ErrorInsufficientResources;
1957                 goto EXIT;
1958             }
1959
1960             codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1961                                         (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1962
1963         }
1964 //#endif
1965         if (codecReturn != VIDEO_ERROR_NONE) {
1966             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
1967             ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1968             goto EXIT;
1969         }
1970         H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1971         if (pH264Enc->bSourceStart == OMX_FALSE) {
1972             pH264Enc->bSourceStart = OMX_TRUE;
1973             Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
1974             Exynos_OSAL_SleepMillisec(0);
1975         }
1976         if (pH264Enc->bDestinationStart == OMX_FALSE) {
1977             pH264Enc->bDestinationStart = OMX_TRUE;
1978             Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
1979             Exynos_OSAL_SleepMillisec(0);
1980         }
1981     }
1982
1983     ret = OMX_ErrorNone;
1984
1985 EXIT:
1986     FunctionOut();
1987
1988     return ret;
1989 }
1990
1991 OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1992 {
1993     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1994     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1995     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1996     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1997     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1998     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1999     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
2000     ExynosVideoBuffer       *pVideoBuffer;
2001
2002     FunctionIn();
2003
2004     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
2005
2006     pSrcOutputData->dataLen       = 0;
2007     pSrcOutputData->usedDataLen   = 0;
2008     pSrcOutputData->remainDataLen = 0;
2009     pSrcOutputData->nFlags    = 0;
2010     pSrcOutputData->timeStamp = 0;
2011
2012     if (pVideoBuffer == NULL) {
2013         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2014         pSrcOutputData->allocSize  = 0;
2015         pSrcOutputData->pPrivate = NULL;
2016         pSrcOutputData->bufferHeader = NULL;
2017     } else {
2018         int plane = 0;
2019         for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2020             pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2021             pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2022         }
2023         pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
2024                                         pVideoBuffer->planes[1].allocSize +
2025                                         pVideoBuffer->planes[2].allocSize;
2026
2027         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2028             int i = 0;
2029             while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
2030                 i++;
2031                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2032                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
2033                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2034                     goto EXIT;
2035                 }
2036             }
2037             pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
2038             pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
2039         }
2040
2041         /* For Share Buffer */
2042         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2043     }
2044
2045     ret = OMX_ErrorNone;
2046
2047 EXIT:
2048     FunctionOut();
2049
2050     return ret;
2051 }
2052
2053 OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2054 {
2055     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2056     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2057     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2058     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2059     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2060     OMX_U32 dataLen = 0;
2061     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2062
2063     FunctionIn();
2064
2065     if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) {
2066         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2067         ret = OMX_ErrorBadParameter;
2068         goto EXIT;
2069     }
2070
2071     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
2072                      (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2073
2074     if (codecReturn != VIDEO_ERROR_NONE) {
2075         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
2076         ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2077         goto EXIT;
2078     }
2079     H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2080
2081     ret = OMX_ErrorNone;
2082
2083 EXIT:
2084     FunctionOut();
2085
2086     return ret;
2087 }
2088
2089 OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2090 {
2091     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2092     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2093     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2094     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2095     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2096     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
2097     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2098     ExynosVideoBuffer       *pVideoBuffer;
2099     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2100     OMX_S32 indexTimestamp = 0;
2101
2102     FunctionIn();
2103
2104     if (pH264Enc->bDestinationStart == OMX_FALSE) {
2105         ret = OMX_ErrorNone;
2106         goto EXIT;
2107     }
2108
2109     if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
2110         ret = OMX_ErrorNone;
2111         goto EXIT;
2112     }
2113
2114     pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
2115     pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2116
2117     pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2118     pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2119     pDstOutputData->allocSize   = pVideoBuffer->planes[0].allocSize;
2120     pDstOutputData->dataLen     = pVideoBuffer->planes[0].dataSize;
2121     pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize;
2122     pDstOutputData->usedDataLen = 0;
2123     pDstOutputData->pPrivate = pVideoBuffer;
2124     /* For Share Buffer */
2125     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2126
2127     if (pVideoEnc->bFirstOutput == OMX_FALSE) {
2128         if (pVideoEnc->bSharedOutputFD == OMX_FALSE) {
2129             OMX_U8 *p = NULL;
2130             int iSpsSize = 0;
2131             int iPpsSize = 0;
2132
2133             /* Calculate sps/pps size if needed */
2134             p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4),
2135                                 pDstOutputData->dataLen - 4);
2136
2137             iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2138             pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
2139                 (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2140             pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
2141
2142             iPpsSize = pDstOutputData->dataLen - iSpsSize;
2143             pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
2144                 (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize;
2145             pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
2146         }
2147         pDstOutputData->timeStamp = 0;
2148         pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
2149         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2150         pVideoEnc->bFirstOutput = OMX_TRUE;
2151     } else {
2152         indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
2153         if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2154             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2155             pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2156         } else {
2157             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2158             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2159         }
2160
2161         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2162         if (pVideoBuffer->frameType == VIDEO_FRAME_I)
2163             pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2164     }
2165
2166     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2167         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2168         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags);
2169         pDstOutputData->remainDataLen = 0;
2170     }
2171
2172     ret = OMX_ErrorNone;
2173
2174 EXIT:
2175     FunctionOut();
2176
2177     return ret;
2178 }
2179
2180 OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2181 {
2182     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2183     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2184     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2185
2186     FunctionIn();
2187
2188     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2189         ret = OMX_ErrorNone;
2190         goto EXIT;
2191     }
2192     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2193         ret = OMX_ErrorNone;
2194         goto EXIT;
2195     }
2196
2197     ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
2198     if (ret != OMX_ErrorNone) {
2199         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
2200         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2201                                                 pExynosComponent->callbackData,
2202                                                 OMX_EventError, ret, 0, NULL);
2203     }
2204
2205 EXIT:
2206     FunctionOut();
2207
2208     return ret;
2209 }
2210
2211 OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2212 {
2213     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2214     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2215     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2216     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2217
2218     FunctionIn();
2219
2220     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2221         ret = OMX_ErrorNone;
2222         goto EXIT;
2223     }
2224
2225     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2226         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2227             ret = OMX_ErrorNone;
2228             goto EXIT;
2229         }
2230     }
2231     if ((pH264Enc->bSourceStart == OMX_FALSE) &&
2232        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2233         Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2234         Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
2235     }
2236
2237     ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
2238     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2239         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
2240         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2241                                                 pExynosComponent->callbackData,
2242                                                 OMX_EventError, ret, 0, NULL);
2243     }
2244
2245 EXIT:
2246     FunctionOut();
2247
2248     return ret;
2249 }
2250
2251 OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2252 {
2253     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2254     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2255     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2256     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2257
2258     FunctionIn();
2259
2260     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2261         ret = OMX_ErrorNone;
2262         goto EXIT;
2263     }
2264     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2265         ret = OMX_ErrorNone;
2266         goto EXIT;
2267     }
2268     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2269         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2270            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2271             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2272             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2273         }
2274     }
2275     if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2276         ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
2277         if (ret != OMX_ErrorNone) {
2278             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
2279             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2280                                                 pExynosComponent->callbackData,
2281                                                 OMX_EventError, ret, 0, NULL);
2282         }
2283     }
2284
2285 EXIT:
2286     FunctionOut();
2287
2288     return ret;
2289 }
2290
2291 OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2292 {
2293     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2294     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2295     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2296     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2297
2298     FunctionIn();
2299
2300     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2301         ret = OMX_ErrorNone;
2302         goto EXIT;
2303     }
2304     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2305         ret = OMX_ErrorNone;
2306         goto EXIT;
2307     }
2308
2309     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2310         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2311            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2312             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2313             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2314         }
2315     }
2316     ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
2317     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2318         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
2319         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2320                                                 pExynosComponent->callbackData,
2321                                                 OMX_EventError, ret, 0, NULL);
2322     }
2323
2324 EXIT:
2325     FunctionOut();
2326
2327     return ret;
2328 }
2329
2330 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2331     OMX_HANDLETYPE hComponent,
2332     OMX_STRING     componentName)
2333 {
2334     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2335     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2336     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2337     EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2338     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
2339     EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
2340     int i = 0;
2341
2342     FunctionIn();
2343
2344     if ((hComponent == NULL) || (componentName == NULL)) {
2345         ret = OMX_ErrorBadParameter;
2346         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2347         goto EXIT;
2348     }
2349     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) {
2350         ret = OMX_ErrorBadParameter;
2351         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2352         goto EXIT;
2353     }
2354
2355     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2356     ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
2357     if (ret != OMX_ErrorNone) {
2358         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2359         goto EXIT;
2360     }
2361     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2362     pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
2363
2364     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2365     if (pExynosComponent->componentName == NULL) {
2366         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2367         ret = OMX_ErrorInsufficientResources;
2368         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2369         goto EXIT;
2370     }
2371     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2372
2373     pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
2374     if (pH264Enc == NULL) {
2375         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2376         ret = OMX_ErrorInsufficientResources;
2377         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2378         goto EXIT;
2379     }
2380     Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
2381     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2382     pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
2383     pVideoEnc->quantization.nQpI = 20;
2384     pVideoEnc->quantization.nQpP = 20;
2385     pVideoEnc->quantization.nQpB = 20;
2386     pVideoEnc->bSharedOutputFD = OMX_FALSE;
2387
2388     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
2389
2390     /* In case of BUFFER_COPY mode
2391             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2392             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2393          In case of BUFFER_SHARE
2394             bShareableBuf should be TRUE, FALSE is ignored
2395     */
2396     pH264Enc->hMFCH264Handle.bShareableBuf = OMX_FALSE; //Check bStoreMetaData in Init function
2397     /* Set componentVersion */
2398     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2399     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2400     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2401     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2402     /* Set specVersion */
2403     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2404     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2405     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2406     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2407
2408     /* Input port */
2409     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2410     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2411     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2412     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2413     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2414     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2415     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2416     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2417 #ifdef TIZEN_FEATURE_E3250
2418     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2419 #else
2420     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2421 #endif
2422     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2423     pExynosPort->bufferProcessType = BUFFER_COPY;
2424     pExynosPort->portWayType = WAY2_PORT;
2425
2426     /* Output port */
2427     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2428     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2429     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2430     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2431     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2432     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2433     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2434     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2435     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2436     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2437     pExynosPort->bufferProcessType = BUFFER_COPY;
2438     pExynosPort->portWayType = WAY2_PORT;
2439
2440     for(i = 0; i < ALL_PORT_NUM; i++) {
2441         INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2442         pH264Enc->AVCComponent[i].nPortIndex = i;
2443         pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2444         pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
2445
2446         pH264Enc->AVCComponent[i].nPFrames = 20;
2447     }
2448
2449     pOMXComponent->GetParameter      = &Exynos_H264Enc_GetParameter;
2450     pOMXComponent->SetParameter      = &Exynos_H264Enc_SetParameter;
2451     pOMXComponent->GetConfig         = &Exynos_H264Enc_GetConfig;
2452     pOMXComponent->SetConfig         = &Exynos_H264Enc_SetConfig;
2453     pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
2454     pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
2455     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2456
2457     pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Enc_Init;
2458     pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
2459
2460     pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_H264Enc_srcInputBufferProcess;
2461     pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
2462     pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_H264Enc_dstInputBufferProcess;
2463     pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
2464
2465     pVideoEnc->exynos_codec_start         = &H264CodecStart;
2466     pVideoEnc->exynos_codec_stop          = &H264CodecStop;
2467     pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2468     pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnqueueAllBuffer;
2469
2470     pVideoEnc->exynos_checkInputFrame        = NULL;
2471     pVideoEnc->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2472     pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2473
2474 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2475     pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2476     if (pVideoEnc->hSharedMemory == NULL) {
2477         Exynos_OSAL_Free(pH264Enc);
2478         pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2479         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2480         ret = OMX_ErrorInsufficientResources;
2481         goto EXIT;
2482     }
2483 #endif
2484     pExynosComponent->currentState = OMX_StateLoaded;
2485
2486     ret = OMX_ErrorNone;
2487
2488 EXIT:
2489     FunctionOut();
2490
2491     return ret;
2492 }
2493
2494 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2495 {
2496     OMX_ERRORTYPE            ret = OMX_ErrorNone;
2497     OMX_COMPONENTTYPE          *pOMXComponent = NULL;
2498     EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
2499     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
2500     EXYNOS_H264ENC_HANDLE      *pH264Enc         = NULL;
2501
2502     FunctionIn();
2503
2504     if (hComponent == NULL) {
2505         ret = OMX_ErrorBadParameter;
2506         goto EXIT;
2507     }
2508     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2509     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2510     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2511 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2512     Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
2513 #endif
2514     Exynos_OSAL_Free(pExynosComponent->componentName);
2515     pExynosComponent->componentName = NULL;
2516
2517     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
2518     if (pH264Enc != NULL) {
2519         Exynos_OSAL_Free(pH264Enc);
2520         pH264Enc = pVideoEnc->hCodecHandle = NULL;
2521     }
2522
2523     ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2524     if (ret != OMX_ErrorNone) {
2525         goto EXIT;
2526     }
2527
2528     ret = OMX_ErrorNone;
2529
2530 EXIT:
2531     FunctionOut();
2532
2533     return ret;
2534 }