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