fixed svace isues
[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 (pVideoEnc->configChange == OMX_TRUE) {
1889         Change_H264Enc_Param(pExynosComponent);
1890         pVideoEnc->configChange = OMX_FALSE;
1891     }
1892
1893     if ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS) {
1894         OMX_U32 pMFCYUVDataSize[MFC_INPUT_BUFFER_PLANE]  = {0, };
1895         ExynosVideoPlane planes[MFC_INPUT_BUFFER_PLANE];
1896         int plane;
1897
1898         pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1899         pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1900         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);
1901         pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
1902         pH264Enc->hMFCH264Handle.indexTimestamp++;
1903         pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1904
1905         /* queue work for input buffer */
1906         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
1907             pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight;
1908             pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
1909
1910 //#define INPUT_FILE_DUMP
1911 #ifdef INPUT_FILE_DUMP
1912             {
1913                 FILE *pf;
1914                 char filename[100];
1915                 static int tmp_cnt=0;
1916                 int w = pExynosInputPort->portDefinition.format.video.nFrameWidth;
1917                 int h = pExynosInputPort->portDefinition.format.video.nFrameHeight;
1918
1919                 memset(filename, 0x00, sizeof(filename));
1920                 sprintf(filename, "/tmp/enc_dump_%d_%d_%d.yuv", w, h, ++tmp_cnt);
1921                 pf = fopen(filename, "wb");
1922                 if (pf == NULL) {
1923                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] filepoint NULL!");
1924                 } else {
1925                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "[input dump] fwrite[%d] ", tmp_cnt);
1926                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0], sizeof(char), h * w, pf);
1927                     fwrite(pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1], sizeof(char), h * w / 2, pf);
1928                 }
1929                 fclose(pf);
1930             }
1931 #endif
1932
1933         codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1934                                     (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1935 //#ifdef USE_METADATABUFFERTYPE
1936         if ((codecReturn == VIDEO_ERROR_NOBUFFERS) &&
1937             /*(pExynosInputPort->bStoreMetaData == OMX_TRUE) &&*/
1938             (pExynosInputPort->bufferProcessType & BUFFER_SHARE)) {
1939             OMX_U32 nAllocLen[MFC_INPUT_BUFFER_PLANE] = {0, 0};
1940             nAllocLen[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) *
1941                                 ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
1942             nAllocLen[1] = ALIGN(nAllocLen[0]/2,256);
1943             for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
1944                 planes[plane].addr = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[plane];
1945                 planes[plane].allocSize = nAllocLen[plane];
1946                 planes[plane].fd = pSrcInputData->buffer.multiPlaneBuffer.fd[plane];
1947             }
1948
1949             /* Register input buffer */
1950             if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1951                         planes, MFC_INPUT_BUFFER_PLANE) != VIDEO_ERROR_NONE) {
1952                 Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1953                 ret = OMX_ErrorInsufficientResources;
1954                 goto EXIT;
1955             }
1956
1957             codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pSrcInputData->buffer.multiPlaneBuffer.dataBuffer,
1958                                         (unsigned int *)pMFCYUVDataSize, MFC_INPUT_BUFFER_PLANE, pSrcInputData->bufferHeader);
1959
1960         }
1961 //#endif
1962         if (codecReturn != VIDEO_ERROR_NONE) {
1963             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
1964             ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1965             goto EXIT;
1966         }
1967         H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1968         if (pH264Enc->bSourceStart == OMX_FALSE) {
1969             pH264Enc->bSourceStart = OMX_TRUE;
1970             Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
1971             Exynos_OSAL_SleepMillisec(0);
1972         }
1973         if (pH264Enc->bDestinationStart == OMX_FALSE) {
1974             pH264Enc->bDestinationStart = OMX_TRUE;
1975             Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
1976             Exynos_OSAL_SleepMillisec(0);
1977         }
1978     }
1979
1980     ret = OMX_ErrorNone;
1981
1982 EXIT:
1983     FunctionOut();
1984
1985     return ret;
1986 }
1987
1988 OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1989 {
1990     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1991     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1992     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1993     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1994     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1995     EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1996     ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1997     ExynosVideoBuffer       *pVideoBuffer;
1998
1999     FunctionIn();
2000
2001     pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
2002
2003     pSrcOutputData->dataLen       = 0;
2004     pSrcOutputData->usedDataLen   = 0;
2005     pSrcOutputData->remainDataLen = 0;
2006     pSrcOutputData->nFlags    = 0;
2007     pSrcOutputData->timeStamp = 0;
2008
2009     if (pVideoBuffer == NULL) {
2010         pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
2011         pSrcOutputData->allocSize  = 0;
2012         pSrcOutputData->pPrivate = NULL;
2013         pSrcOutputData->bufferHeader = NULL;
2014     } else {
2015         int plane = 0;
2016         for (plane = 0; plane < MFC_INPUT_BUFFER_PLANE; plane++) {
2017             pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[plane] = pVideoBuffer->planes[plane].addr;
2018             pSrcOutputData->buffer.multiPlaneBuffer.fd[plane] = pVideoBuffer->planes[plane].fd;
2019         }
2020         pSrcOutputData->allocSize = pVideoBuffer->planes[0].allocSize +
2021                                         pVideoBuffer->planes[1].allocSize +
2022                                         pVideoBuffer->planes[2].allocSize;
2023
2024         if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2025             int i = 0;
2026             while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->pVirAddr[0]) {
2027                 i++;
2028                 if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
2029                     Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
2030                     ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2031                     goto EXIT;
2032                 }
2033             }
2034             pVideoEnc->pMFCEncInputBuffer[i]->dataSize = 0;
2035             pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
2036         }
2037
2038         /* For Share Buffer */
2039         pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
2040     }
2041
2042     ret = OMX_ErrorNone;
2043
2044 EXIT:
2045     FunctionOut();
2046
2047     return ret;
2048 }
2049
2050 OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2051 {
2052     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2053     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2054     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2055     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2056     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2057     OMX_U32 dataLen = 0;
2058     ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
2059
2060     FunctionIn();
2061
2062     if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) {
2063         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
2064         ret = OMX_ErrorBadParameter;
2065         goto EXIT;
2066     }
2067
2068     codecReturn = pOutbufOps->Enqueue(hMFCHandle, (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
2069                      (unsigned int *)&dataLen, MFC_OUTPUT_BUFFER_PLANE, pDstInputData->bufferHeader);
2070
2071     if (codecReturn != VIDEO_ERROR_NONE) {
2072         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
2073         ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
2074         goto EXIT;
2075     }
2076     H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
2077
2078     ret = OMX_ErrorNone;
2079
2080 EXIT:
2081     FunctionOut();
2082
2083     return ret;
2084 }
2085
2086 OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2087 {
2088     OMX_ERRORTYPE                  ret = OMX_ErrorNone;
2089     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2090     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2091     EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2092     void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
2093     ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
2094     ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
2095     ExynosVideoBuffer       *pVideoBuffer;
2096     ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
2097     OMX_S32 indexTimestamp = 0;
2098
2099     FunctionIn();
2100
2101     if (pH264Enc->bDestinationStart == OMX_FALSE) {
2102         ret = OMX_ErrorNone;
2103         goto EXIT;
2104     }
2105
2106     if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
2107         ret = OMX_ErrorNone;
2108         goto EXIT;
2109     }
2110
2111     pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
2112     pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
2113
2114     pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
2115     pDstOutputData->buffer.singlePlaneBuffer.fd = pVideoBuffer->planes[0].fd;
2116     pDstOutputData->allocSize   = pVideoBuffer->planes[0].allocSize;
2117     pDstOutputData->dataLen     = pVideoBuffer->planes[0].dataSize;
2118     pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize;
2119     pDstOutputData->usedDataLen = 0;
2120     pDstOutputData->pPrivate = pVideoBuffer;
2121     /* For Share Buffer */
2122     pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
2123
2124     if (pVideoEnc->bFirstOutput == OMX_FALSE) {
2125         if (pVideoEnc->bSharedOutputFD == OMX_FALSE) {
2126             OMX_U8 *p = NULL;
2127             int iSpsSize = 0;
2128             int iPpsSize = 0;
2129
2130             /* Calculate sps/pps size if needed */
2131             p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4),
2132                                 pDstOutputData->dataLen - 4);
2133
2134             iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2135             pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
2136                 (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
2137             pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
2138
2139             iPpsSize = pDstOutputData->dataLen - iSpsSize;
2140             pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
2141                 (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize;
2142             pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
2143         }
2144         pDstOutputData->timeStamp = 0;
2145         pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
2146         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2147         pVideoEnc->bFirstOutput = OMX_TRUE;
2148     } else {
2149         indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
2150         if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
2151             pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2152             pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
2153         } else {
2154             pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
2155             pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
2156         }
2157
2158         pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
2159         if (pVideoBuffer->frameType == VIDEO_FRAME_I)
2160             pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
2161     }
2162
2163     if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
2164         ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
2165         Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "%x displayStatus:%d, nFlags0x%x", pExynosComponent, displayStatus, pDstOutputData->nFlags);
2166         pDstOutputData->remainDataLen = 0;
2167     }
2168
2169     ret = OMX_ErrorNone;
2170
2171 EXIT:
2172     FunctionOut();
2173
2174     return ret;
2175 }
2176
2177 OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2178 {
2179     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2180     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2181     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2182
2183     FunctionIn();
2184
2185     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2186         ret = OMX_ErrorNone;
2187         goto EXIT;
2188     }
2189     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2190         ret = OMX_ErrorNone;
2191         goto EXIT;
2192     }
2193
2194     ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
2195     if (ret != OMX_ErrorNone) {
2196         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
2197         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2198                                                 pExynosComponent->callbackData,
2199                                                 OMX_EventError, ret, 0, NULL);
2200     }
2201
2202 EXIT:
2203     FunctionOut();
2204
2205     return ret;
2206 }
2207
2208 OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2209 {
2210     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2211     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2212     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2213     EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2214
2215     FunctionIn();
2216
2217     if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2218         ret = OMX_ErrorNone;
2219         goto EXIT;
2220     }
2221
2222     if (pExynosInputPort->bufferProcessType & BUFFER_COPY) {
2223         if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2224             ret = OMX_ErrorNone;
2225             goto EXIT;
2226         }
2227     }
2228     if ((pH264Enc->bSourceStart == OMX_FALSE) &&
2229        (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2230         Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2231         Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
2232     }
2233
2234     ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
2235     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2236         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
2237         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2238                                                 pExynosComponent->callbackData,
2239                                                 OMX_EventError, ret, 0, NULL);
2240     }
2241
2242 EXIT:
2243     FunctionOut();
2244
2245     return ret;
2246 }
2247
2248 OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2249 {
2250     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2251     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2252     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2253     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2254
2255     FunctionIn();
2256
2257     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2258         ret = OMX_ErrorNone;
2259         goto EXIT;
2260     }
2261     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2262         ret = OMX_ErrorNone;
2263         goto EXIT;
2264     }
2265     if (pExynosOutputPort->bufferProcessType & BUFFER_SHARE) {
2266         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2267            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2268             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2269             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2270         }
2271     }
2272     if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2273         ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
2274         if (ret != OMX_ErrorNone) {
2275             Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
2276             pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2277                                                 pExynosComponent->callbackData,
2278                                                 OMX_EventError, ret, 0, NULL);
2279         }
2280     }
2281
2282 EXIT:
2283     FunctionOut();
2284
2285     return ret;
2286 }
2287
2288 OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2289 {
2290     OMX_ERRORTYPE             ret = OMX_ErrorNone;
2291     EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2292     EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2293     EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2294
2295     FunctionIn();
2296
2297     if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2298         ret = OMX_ErrorNone;
2299         goto EXIT;
2300     }
2301     if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2302         ret = OMX_ErrorNone;
2303         goto EXIT;
2304     }
2305
2306     if (pExynosOutputPort->bufferProcessType & BUFFER_COPY) {
2307         if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2308            (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2309             Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2310             Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2311         }
2312     }
2313     ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
2314     if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2315         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
2316         pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2317                                                 pExynosComponent->callbackData,
2318                                                 OMX_EventError, ret, 0, NULL);
2319     }
2320
2321 EXIT:
2322     FunctionOut();
2323
2324     return ret;
2325 }
2326
2327 OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(
2328     OMX_HANDLETYPE hComponent,
2329     OMX_STRING     componentName)
2330 {
2331     OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2332     OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2333     EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2334     EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2335     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
2336     EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
2337     int i = 0;
2338
2339     FunctionIn();
2340
2341     if ((hComponent == NULL) || (componentName == NULL)) {
2342         ret = OMX_ErrorBadParameter;
2343         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2344         goto EXIT;
2345     }
2346     if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) {
2347         ret = OMX_ErrorBadParameter;
2348         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2349         goto EXIT;
2350     }
2351
2352     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2353     ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
2354     if (ret != OMX_ErrorNone) {
2355         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2356         goto EXIT;
2357     }
2358     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2359     pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
2360
2361     pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2362     if (pExynosComponent->componentName == NULL) {
2363         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2364         ret = OMX_ErrorInsufficientResources;
2365         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2366         goto EXIT;
2367     }
2368     Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2369
2370     pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
2371     if (pH264Enc == NULL) {
2372         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2373         ret = OMX_ErrorInsufficientResources;
2374         Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2375         goto EXIT;
2376     }
2377     Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
2378     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2379     pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
2380     pVideoEnc->quantization.nQpI = 20;
2381     pVideoEnc->quantization.nQpP = 20;
2382     pVideoEnc->quantization.nQpB = 20;
2383     pVideoEnc->bSharedOutputFD = OMX_FALSE;
2384
2385     Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
2386
2387     /* In case of BUFFER_COPY mode
2388             bShareableBuf = TRUE means MemoryType is V4L2_MEMORY_USERPTR
2389             bShareableBuf = FALSE means MemoryType is V4L2_MEMORY_MMAP
2390          In case of BUFFER_SHARE
2391             bShareableBuf should be TRUE, FALSE is ignored
2392     */
2393     pH264Enc->hMFCH264Handle.bShareableBuf = OMX_FALSE; //Check bStoreMetaData in Init function
2394     /* Set componentVersion */
2395     pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2396     pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2397     pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2398     pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2399     /* Set specVersion */
2400     pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2401     pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2402     pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2403     pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2404
2405     /* Input port */
2406     pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2407     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2408     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2409     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2410     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2411     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2412     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2413     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2414 #ifdef TIZEN_FEATURE_E3250
2415     pExynosPort->portDefinition.format.video.eColorFormat = OMX_SEC_COLOR_FormatNV12L_DmaBuf_Fd;
2416 #else
2417     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2418 #endif
2419     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2420     pExynosPort->bufferProcessType = BUFFER_COPY;
2421     pExynosPort->portWayType = WAY2_PORT;
2422
2423     /* Output port */
2424     pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2425     pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2426     pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2427     pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2428     pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2429     pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2430     Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2431     Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2432     pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2433     pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2434     pExynosPort->bufferProcessType = BUFFER_COPY;
2435     pExynosPort->portWayType = WAY2_PORT;
2436
2437     for(i = 0; i < ALL_PORT_NUM; i++) {
2438         INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2439         pH264Enc->AVCComponent[i].nPortIndex = i;
2440         pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2441         pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
2442
2443         pH264Enc->AVCComponent[i].nPFrames = 20;
2444     }
2445
2446     pOMXComponent->GetParameter      = &Exynos_H264Enc_GetParameter;
2447     pOMXComponent->SetParameter      = &Exynos_H264Enc_SetParameter;
2448     pOMXComponent->GetConfig         = &Exynos_H264Enc_GetConfig;
2449     pOMXComponent->SetConfig         = &Exynos_H264Enc_SetConfig;
2450     pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
2451     pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
2452     pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2453
2454     pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Enc_Init;
2455     pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
2456
2457     pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_H264Enc_srcInputBufferProcess;
2458     pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
2459     pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_H264Enc_dstInputBufferProcess;
2460     pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
2461
2462     pVideoEnc->exynos_codec_start         = &H264CodecStart;
2463     pVideoEnc->exynos_codec_stop          = &H264CodecStop;
2464     pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2465     pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnqueueAllBuffer;
2466
2467     pVideoEnc->exynos_checkInputFrame        = NULL;
2468     pVideoEnc->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2469     pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2470
2471 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2472     pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2473     if (pVideoEnc->hSharedMemory == NULL) {
2474         Exynos_OSAL_Free(pH264Enc);
2475         pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2476         Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2477         ret = OMX_ErrorInsufficientResources;
2478         goto EXIT;
2479     }
2480 #endif
2481     pExynosComponent->currentState = OMX_StateLoaded;
2482
2483     ret = OMX_ErrorNone;
2484
2485 EXIT:
2486     FunctionOut();
2487
2488     return ret;
2489 }
2490
2491 OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2492 {
2493     OMX_ERRORTYPE            ret = OMX_ErrorNone;
2494     OMX_COMPONENTTYPE          *pOMXComponent = NULL;
2495     EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
2496     EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
2497     EXYNOS_H264ENC_HANDLE      *pH264Enc         = NULL;
2498
2499     FunctionIn();
2500
2501     if (hComponent == NULL) {
2502         ret = OMX_ErrorBadParameter;
2503         goto EXIT;
2504     }
2505     pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2506     pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2507     pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2508 #ifndef TIZEN_FEATURE_E3250 /* do not use ion */
2509     Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
2510 #endif
2511     Exynos_OSAL_Free(pExynosComponent->componentName);
2512     pExynosComponent->componentName = NULL;
2513
2514     pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
2515     if (pH264Enc != NULL) {
2516         Exynos_OSAL_Free(pH264Enc);
2517         pH264Enc = pVideoEnc->hCodecHandle = NULL;
2518     }
2519
2520     ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2521     if (ret != OMX_ErrorNone) {
2522         goto EXIT;
2523     }
2524
2525     ret = OMX_ErrorNone;
2526
2527 EXIT:
2528     FunctionOut();
2529
2530     return ret;
2531 }