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