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