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