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