Exynos_OMX_H264enc.c revision 54cbf397a1e177ea34b304b6951d4f7eb571c259
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]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
705            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->CVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
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->pMFCEncOutputBuffer[%d]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
723        }
724        pOutbufOps->Clear_Queue(hMFCHandle);
725    } else {
726        ret = OMX_ErrorBadParameter;
727        goto EXIT;
728    }
729
730EXIT:
731    FunctionOut();
732
733    return ret;
734}
735
736OMX_ERRORTYPE H264CodecSrcSetup(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
737{
738    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
739    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
740    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
741    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
742    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
743    void                          *hMFCHandle = pMFCH264Handle->hMFCHandle;
744    EXYNOS_OMX_BASEPORT           *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
745    EXYNOS_OMX_BASEPORT           *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
746    OMX_U32                        oneFrameSize = pSrcInputData->dataLen;
747
748    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
749    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
750    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
751
752    FunctionIn();
753
754    if ((oneFrameSize <= 0) && (pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS)) {
755        OMX_BUFFERHEADERTYPE *OMXBuffer = NULL;
756        OMXBuffer = Exynos_OutputBufferGetQueue_Direct(pExynosComponent);
757        if (OMXBuffer == NULL) {
758            ret = OMX_ErrorUndefined;
759            goto EXIT;
760        }
761
762        OMXBuffer->nTimeStamp = pSrcInputData->timeStamp;
763        OMXBuffer->nFlags = pSrcInputData->nFlags;
764        Exynos_OMX_OutputBufferReturn(pOMXComponent, OMXBuffer);
765
766        ret = OMX_ErrorNone;
767        goto EXIT;
768    }
769
770    OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
771    OMX_U32 pMFCYUVDataSize[2]  = {0, 0};
772
773    pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
774    pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
775    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "input timestamp %lld us (%.2f secs), Tag: %d, nFlags: 0x%x", pSrcInputData->timeStamp, pSrcInputData->timeStamp / 1E6, pH264Enc->hMFCH264Handle.indexTimestamp, pSrcInputData->nFlags);
776    pEncOps->Set_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
777    pH264Enc->hMFCH264Handle.indexTimestamp++;
778    pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
779
780    /* queue work for input buffer */
781    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d H264CodecSetup(): oneFrameSize: %d, bufferHeader: 0x%x",  __FUNCTION__, __LINE__, oneFrameSize, pSrcInputData->bufferHeader);
782    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
783        CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
784        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d codecInputBuffer:0x%x",  __FUNCTION__, __LINE__, codecInputBuffer);
785        pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
786        pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
787    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
788        pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
789        pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
790        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d Ysize:%d CSize %d",  __FUNCTION__, __LINE__, pMFCYUVDataSize[0], pMFCYUVDataSize[1]);
791    }
792
793    pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
794    pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
795
796    if (pInbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
797                          (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader) != VIDEO_ERROR_NONE) {
798        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to enqueue input buffer");
799        ret = OMX_ErrorUndefined;
800        goto EXIT;
801    }
802    /* input start */
803    if (pInbufOps->Run(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
804        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run input buffer for header parsing");
805        ret = OMX_ErrorCodecInit;
806        goto EXIT;
807    }
808
809    pH264Enc->bSourceStart = OMX_TRUE;
810    Exynos_OSAL_SignalSet(pH264Enc->hSourceStartEvent);
811    Exynos_OSAL_SleepMillisec(0);
812
813    pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_TRUE;
814    ret = OMX_ErrorNone;
815
816EXIT:
817    FunctionOut();
818
819    return ret;
820}
821
822OMX_ERRORTYPE H264CodecDstSetup(OMX_COMPONENTTYPE *pOMXComponent)
823{
824    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
825    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
826    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
827    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
828    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
829    void                          *hMFCHandle = pMFCH264Handle->hMFCHandle;
830
831    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
832    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
833    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
834
835    FunctionIn();
836
837    /* start header encoding */
838    if (pOutbufOps->Run) {
839        if (pOutbufOps->Run(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
840            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to run output buffer for header parsing");
841            ret = OMX_ErrorInsufficientResources;
842            goto EXIT;
843        }
844    }
845
846    pH264Enc->bDestinationStart = OMX_TRUE;
847    Exynos_OSAL_SignalSet(pH264Enc->hDestinationStartEvent);
848    Exynos_OSAL_SleepMillisec(0);
849
850    /* bConfiguredMFCDst should be set true before waiting headerGeneratedEvent event.
851     * To make sure that the first dequeued destination buffer is enqueued before H264CodecDstSetup returns.
852     * If bConfiguredMFCDst is not set to be true,
853     * Exynos_H264Enc_dstInputBufferProcess returns without enqueuing the first dequeued destination buffer.
854     */
855    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_TRUE;
856
857    Exynos_OSAL_SignalWait(pVideoEnc->headerGeneratedEvent, DEF_MAX_WAIT_TIME);
858    Exynos_OSAL_SignalReset(pVideoEnc->headerGeneratedEvent);
859
860    ret = OMX_ErrorNone;
861
862EXIT:
863    FunctionOut();
864
865    return ret;
866}
867
868OMX_ERRORTYPE Exynos_H264Enc_GetParameter(
869    OMX_IN OMX_HANDLETYPE hComponent,
870    OMX_IN OMX_INDEXTYPE  nParamIndex,
871    OMX_INOUT OMX_PTR     pComponentParameterStructure)
872{
873    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
874    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
875    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
876
877    FunctionIn();
878
879    if (hComponent == NULL || pComponentParameterStructure == NULL) {
880        ret = OMX_ErrorBadParameter;
881        goto EXIT;
882    }
883    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
884    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
885    if (ret != OMX_ErrorNone) {
886        goto EXIT;
887    }
888    if (pOMXComponent->pComponentPrivate == NULL) {
889        ret = OMX_ErrorBadParameter;
890        goto EXIT;
891    }
892
893    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
894    if (pExynosComponent->currentState == OMX_StateInvalid ) {
895        ret = OMX_ErrorInvalidState;
896        goto EXIT;
897    }
898
899    switch (nParamIndex) {
900    case OMX_IndexParamVideoAvc:
901    {
902        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
903        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
904        EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
905
906        ret = Exynos_OMX_Check_SizeVersion(pDstAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
907        if (ret != OMX_ErrorNone) {
908            goto EXIT;
909        }
910
911        if (pDstAVCComponent->nPortIndex >= ALL_PORT_NUM) {
912            ret = OMX_ErrorBadPortIndex;
913            goto EXIT;
914        }
915
916        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
917        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstAVCComponent->nPortIndex];
918
919        Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
920    }
921        break;
922    case OMX_IndexParamStandardComponentRole:
923    {
924        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE *)pComponentParameterStructure;
925        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
926        if (ret != OMX_ErrorNone) {
927            goto EXIT;
928        }
929
930        Exynos_OSAL_Strcpy((char *)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
931    }
932        break;
933    case OMX_IndexParamVideoProfileLevelQuerySupported:
934    {
935        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
936        EXYNOS_OMX_VIDEO_PROFILELEVEL *pProfileLevel = NULL;
937        OMX_U32 maxProfileLevelNum = 0;
938
939        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
940        if (ret != OMX_ErrorNone) {
941            goto EXIT;
942        }
943
944        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
945            ret = OMX_ErrorBadPortIndex;
946            goto EXIT;
947        }
948
949        pProfileLevel = supportedAVCProfileLevels;
950        maxProfileLevelNum = sizeof(supportedAVCProfileLevels) / sizeof(EXYNOS_OMX_VIDEO_PROFILELEVEL);
951
952        if (pDstProfileLevel->nProfileIndex >= maxProfileLevelNum) {
953            ret = OMX_ErrorNoMore;
954            goto EXIT;
955        }
956
957        pProfileLevel += pDstProfileLevel->nProfileIndex;
958        pDstProfileLevel->eProfile = pProfileLevel->profile;
959        pDstProfileLevel->eLevel = pProfileLevel->level;
960    }
961        break;
962    case OMX_IndexParamVideoProfileLevelCurrent:
963    {
964        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pDstProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)pComponentParameterStructure;
965        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = NULL;
966        EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
967
968        ret = Exynos_OMX_Check_SizeVersion(pDstProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
969        if (ret != OMX_ErrorNone) {
970            goto EXIT;
971        }
972
973        if (pDstProfileLevel->nPortIndex >= ALL_PORT_NUM) {
974            ret = OMX_ErrorBadPortIndex;
975            goto EXIT;
976        }
977
978        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
979        pSrcAVCComponent = &pH264Enc->AVCComponent[pDstProfileLevel->nPortIndex];
980
981        pDstProfileLevel->eProfile = pSrcAVCComponent->eProfile;
982        pDstProfileLevel->eLevel = pSrcAVCComponent->eLevel;
983    }
984        break;
985    case OMX_IndexParamVideoErrorCorrection:
986    {
987        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
988        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = NULL;
989        EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
990
991        ret = Exynos_OMX_Check_SizeVersion(pDstErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
992        if (ret != OMX_ErrorNone) {
993            goto EXIT;
994        }
995
996        if (pDstErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
997            ret = OMX_ErrorBadPortIndex;
998            goto EXIT;
999        }
1000
1001        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1002        pSrcErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1003
1004        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1005        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1006        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1007        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1008        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1009    }
1010        break;
1011    default:
1012        ret = Exynos_OMX_VideoEncodeGetParameter(hComponent, nParamIndex, pComponentParameterStructure);
1013        break;
1014    }
1015EXIT:
1016    FunctionOut();
1017
1018    return ret;
1019}
1020
1021OMX_ERRORTYPE Exynos_H264Enc_SetParameter(
1022    OMX_IN OMX_HANDLETYPE hComponent,
1023    OMX_IN OMX_INDEXTYPE  nIndex,
1024    OMX_IN OMX_PTR        pComponentParameterStructure)
1025{
1026    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1027    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1028    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1029
1030    FunctionIn();
1031
1032    if (hComponent == NULL || pComponentParameterStructure == NULL) {
1033        ret = OMX_ErrorBadParameter;
1034        goto EXIT;
1035    }
1036    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1037    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1038    if (ret != OMX_ErrorNone) {
1039        goto EXIT;
1040    }
1041    if (pOMXComponent->pComponentPrivate == NULL) {
1042        ret = OMX_ErrorBadParameter;
1043        goto EXIT;
1044    }
1045
1046    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1047    if (pExynosComponent->currentState == OMX_StateInvalid ) {
1048        ret = OMX_ErrorInvalidState;
1049        goto EXIT;
1050    }
1051
1052    switch (nIndex) {
1053    case OMX_IndexParamVideoAvc:
1054    {
1055        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1056        OMX_VIDEO_PARAM_AVCTYPE *pSrcAVCComponent = (OMX_VIDEO_PARAM_AVCTYPE *)pComponentParameterStructure;
1057        EXYNOS_H264ENC_HANDLE   *pH264Enc = NULL;
1058
1059        ret = Exynos_OMX_Check_SizeVersion(pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1060        if (ret != OMX_ErrorNone) {
1061            goto EXIT;
1062        }
1063
1064        if (pSrcAVCComponent->nPortIndex >= ALL_PORT_NUM) {
1065            ret = OMX_ErrorBadPortIndex;
1066            goto EXIT;
1067        }
1068
1069        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1070        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcAVCComponent->nPortIndex];
1071
1072        Exynos_OSAL_Memcpy(pDstAVCComponent, pSrcAVCComponent, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
1073    }
1074        break;
1075    case OMX_IndexParamStandardComponentRole:
1076    {
1077        OMX_PARAM_COMPONENTROLETYPE *pComponentRole = (OMX_PARAM_COMPONENTROLETYPE*)pComponentParameterStructure;
1078
1079        ret = Exynos_OMX_Check_SizeVersion(pComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
1080        if (ret != OMX_ErrorNone) {
1081            goto EXIT;
1082        }
1083
1084        if ((pExynosComponent->currentState != OMX_StateLoaded) && (pExynosComponent->currentState != OMX_StateWaitForResources)) {
1085            ret = OMX_ErrorIncorrectStateOperation;
1086            goto EXIT;
1087        }
1088
1089        if (!Exynos_OSAL_Strcmp((char*)pComponentRole->cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE)) {
1090            pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX].portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
1091        } else {
1092            ret = OMX_ErrorBadParameter;
1093            goto EXIT;
1094        }
1095    }
1096        break;
1097    case OMX_IndexParamVideoProfileLevelCurrent:
1098    {
1099        OMX_VIDEO_PARAM_PROFILELEVELTYPE *pSrcProfileLevel = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pComponentParameterStructure;
1100        OMX_VIDEO_PARAM_AVCTYPE *pDstAVCComponent = NULL;
1101        EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1102
1103        ret = Exynos_OMX_Check_SizeVersion(pSrcProfileLevel, sizeof(OMX_VIDEO_PARAM_PROFILELEVELTYPE));
1104        if (ret != OMX_ErrorNone)
1105            goto EXIT;
1106
1107        if (pSrcProfileLevel->nPortIndex >= ALL_PORT_NUM) {
1108            ret = OMX_ErrorBadPortIndex;
1109            goto EXIT;
1110        }
1111
1112        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1113
1114        pDstAVCComponent = &pH264Enc->AVCComponent[pSrcProfileLevel->nPortIndex];
1115        pDstAVCComponent->eProfile = pSrcProfileLevel->eProfile;
1116        pDstAVCComponent->eLevel = pSrcProfileLevel->eLevel;
1117    }
1118        break;
1119    case OMX_IndexParamVideoErrorCorrection:
1120    {
1121        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pSrcErrorCorrectionType = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)pComponentParameterStructure;
1122        OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *pDstErrorCorrectionType = NULL;
1123        EXYNOS_H264ENC_HANDLE *pH264Enc = NULL;
1124
1125        ret = Exynos_OMX_Check_SizeVersion(pSrcErrorCorrectionType, sizeof(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE));
1126        if (ret != OMX_ErrorNone) {
1127            goto EXIT;
1128        }
1129
1130        if (pSrcErrorCorrectionType->nPortIndex != OUTPUT_PORT_INDEX) {
1131            ret = OMX_ErrorBadPortIndex;
1132            goto EXIT;
1133        }
1134
1135        pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1136        pDstErrorCorrectionType = &pH264Enc->errorCorrectionType[OUTPUT_PORT_INDEX];
1137
1138        pDstErrorCorrectionType->bEnableHEC = pSrcErrorCorrectionType->bEnableHEC;
1139        pDstErrorCorrectionType->bEnableResync = pSrcErrorCorrectionType->bEnableResync;
1140        pDstErrorCorrectionType->nResynchMarkerSpacing = pSrcErrorCorrectionType->nResynchMarkerSpacing;
1141        pDstErrorCorrectionType->bEnableDataPartitioning = pSrcErrorCorrectionType->bEnableDataPartitioning;
1142        pDstErrorCorrectionType->bEnableRVLC = pSrcErrorCorrectionType->bEnableRVLC;
1143    }
1144        break;
1145    default:
1146        ret = Exynos_OMX_VideoEncodeSetParameter(hComponent, nIndex, pComponentParameterStructure);
1147        break;
1148    }
1149EXIT:
1150    FunctionOut();
1151
1152    return ret;
1153}
1154
1155OMX_ERRORTYPE Exynos_H264Enc_GetConfig(
1156    OMX_HANDLETYPE hComponent,
1157    OMX_INDEXTYPE nIndex,
1158    OMX_PTR pComponentConfigStructure)
1159{
1160    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1161    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1162    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1163    EXYNOS_H264ENC_HANDLE    *pH264Enc         = NULL;
1164
1165    FunctionIn();
1166
1167    if (hComponent == NULL || pComponentConfigStructure == NULL) {
1168        ret = OMX_ErrorBadParameter;
1169        goto EXIT;
1170    }
1171    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1172    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1173    if (ret != OMX_ErrorNone) {
1174        goto EXIT;
1175    }
1176    if (pOMXComponent->pComponentPrivate == NULL) {
1177        ret = OMX_ErrorBadParameter;
1178        goto EXIT;
1179    }
1180    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1181    if (pExynosComponent->currentState == OMX_StateInvalid) {
1182        ret = OMX_ErrorInvalidState;
1183        goto EXIT;
1184    }
1185    pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1186
1187    switch (nIndex) {
1188    case OMX_IndexConfigVideoAVCIntraPeriod:
1189    {
1190        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1191        OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1192
1193        if ((portIndex != OUTPUT_PORT_INDEX)) {
1194            ret = OMX_ErrorBadPortIndex;
1195            goto EXIT;
1196        } else {
1197            pAVCIntraPeriod->nIDRPeriod = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames + 1;
1198            pAVCIntraPeriod->nPFrames = pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames;
1199        }
1200    }
1201        break;
1202    default:
1203        ret = Exynos_OMX_VideoEncodeGetConfig(hComponent, nIndex, pComponentConfigStructure);
1204        break;
1205    }
1206
1207EXIT:
1208    FunctionOut();
1209
1210    return ret;
1211}
1212
1213OMX_ERRORTYPE Exynos_H264Enc_SetConfig(
1214    OMX_HANDLETYPE hComponent,
1215    OMX_INDEXTYPE nIndex,
1216    OMX_PTR pComponentConfigStructure)
1217{
1218    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1219    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
1220    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
1221    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
1222    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
1223
1224    FunctionIn();
1225
1226    if (hComponent == NULL || pComponentConfigStructure == NULL) {
1227        ret = OMX_ErrorBadParameter;
1228        goto EXIT;
1229    }
1230    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1231    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1232    if (ret != OMX_ErrorNone) {
1233        goto EXIT;
1234    }
1235    if (pOMXComponent->pComponentPrivate == NULL) {
1236        ret = OMX_ErrorBadParameter;
1237        goto EXIT;
1238    }
1239    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1240    if (pExynosComponent->currentState == OMX_StateInvalid) {
1241        ret = OMX_ErrorInvalidState;
1242        goto EXIT;
1243    }
1244
1245    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1246    pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1247
1248    switch (nIndex) {
1249    case OMX_IndexConfigVideoIntraPeriod:
1250    {
1251        EXYNOS_OMX_VIDEOENC_COMPONENT *pVEncBase = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1252        OMX_U32 nPFrames = (*((OMX_U32 *)pComponentConfigStructure)) - 1;
1253
1254        pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = nPFrames;
1255
1256        ret = OMX_ErrorNone;
1257    }
1258        break;
1259    case OMX_IndexConfigVideoAVCIntraPeriod:
1260    {
1261        OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pAVCIntraPeriod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pComponentConfigStructure;
1262        OMX_U32           portIndex = pAVCIntraPeriod->nPortIndex;
1263
1264        if ((portIndex != OUTPUT_PORT_INDEX)) {
1265            ret = OMX_ErrorBadPortIndex;
1266            goto EXIT;
1267        } else {
1268            if (pAVCIntraPeriod->nIDRPeriod == (pAVCIntraPeriod->nPFrames + 1))
1269                pH264Enc->AVCComponent[OUTPUT_PORT_INDEX].nPFrames = pAVCIntraPeriod->nPFrames;
1270            else {
1271                ret = OMX_ErrorBadParameter;
1272                goto EXIT;
1273            }
1274        }
1275    }
1276        break;
1277    default:
1278        ret = Exynos_OMX_VideoEncodeSetConfig(hComponent, nIndex, pComponentConfigStructure);
1279        break;
1280    }
1281
1282EXIT:
1283    if (ret == OMX_ErrorNone)
1284        pVideoEnc->configChange = OMX_TRUE;
1285
1286    FunctionOut();
1287
1288    return ret;
1289}
1290
1291OMX_ERRORTYPE Exynos_H264Enc_GetExtensionIndex(
1292    OMX_IN OMX_HANDLETYPE  hComponent,
1293    OMX_IN OMX_STRING      cParameterName,
1294    OMX_OUT OMX_INDEXTYPE *pIndexType)
1295{
1296    OMX_ERRORTYPE             ret              = OMX_ErrorNone;
1297    OMX_COMPONENTTYPE        *pOMXComponent    = NULL;
1298    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = NULL;
1299
1300    FunctionIn();
1301
1302    if (hComponent == NULL) {
1303        ret = OMX_ErrorBadParameter;
1304        goto EXIT;
1305    }
1306    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
1307    ret = Exynos_OMX_Check_SizeVersion(pOMXComponent, sizeof(OMX_COMPONENTTYPE));
1308    if (ret != OMX_ErrorNone) {
1309        goto EXIT;
1310    }
1311    if (pOMXComponent->pComponentPrivate == NULL) {
1312        ret = OMX_ErrorBadParameter;
1313        goto EXIT;
1314    }
1315    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1316    if ((cParameterName == NULL) || (pIndexType == NULL)) {
1317        ret = OMX_ErrorBadParameter;
1318        goto EXIT;
1319    }
1320    if (pExynosComponent->currentState == OMX_StateInvalid) {
1321        ret = OMX_ErrorInvalidState;
1322        goto EXIT;
1323    }
1324    if (Exynos_OSAL_Strcmp(cParameterName, EXYNOS_INDEX_CONFIG_VIDEO_INTRAPERIOD) == 0) {
1325        *pIndexType = OMX_IndexConfigVideoIntraPeriod;
1326        ret = OMX_ErrorNone;
1327    } else {
1328        ret = Exynos_OMX_VideoEncodeGetExtensionIndex(hComponent, cParameterName, pIndexType);
1329    }
1330
1331EXIT:
1332    FunctionOut();
1333
1334    return ret;
1335}
1336
1337OMX_ERRORTYPE Exynos_H264Enc_ComponentRoleEnum(OMX_HANDLETYPE hComponent, OMX_U8 *cRole, OMX_U32 nIndex)
1338{
1339    OMX_ERRORTYPE               ret              = OMX_ErrorNone;
1340    OMX_COMPONENTTYPE          *pOMXComponent    = NULL;
1341    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
1342
1343    FunctionIn();
1344
1345    if ((hComponent == NULL) || (cRole == NULL)) {
1346        ret = OMX_ErrorBadParameter;
1347        goto EXIT;
1348    }
1349    if (nIndex == (MAX_COMPONENT_ROLE_NUM-1)) {
1350        Exynos_OSAL_Strcpy((char *)cRole, EXYNOS_OMX_COMPONENT_H264_ENC_ROLE);
1351        ret = OMX_ErrorNone;
1352    } else {
1353        ret = OMX_ErrorNoMore;
1354    }
1355
1356EXIT:
1357    FunctionOut();
1358
1359    return ret;
1360}
1361
1362/* MFC Init */
1363OMX_ERRORTYPE Exynos_H264Enc_Init(OMX_COMPONENTTYPE *pOMXComponent)
1364{
1365    OMX_ERRORTYPE             ret = OMX_ErrorNone;
1366    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1367    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1368    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1369    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1370    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;;
1371    EXYNOS_MFC_H264ENC_HANDLE     *pMFCH264Handle    = &pH264Enc->hMFCH264Handle;
1372    OMX_PTR                   hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1373    OMX_COLOR_FORMATTYPE      eColorFormat;
1374
1375    ExynosVideoEncOps       *pEncOps    = NULL;
1376    ExynosVideoEncBufferOps *pInbufOps  = NULL;
1377    ExynosVideoEncBufferOps *pOutbufOps = NULL;
1378
1379    CSC_METHOD csc_method = CSC_METHOD_SW;
1380
1381    ExynosVideoEncParam     *pEncParam    = NULL;
1382    ExynosVideoGeometry      bufferConf;
1383    OMX_U32                  inputBufferNumber = 0;
1384    ExynosVideoBuffer bufferInfo;
1385
1386    int i = 0;
1387
1388    FunctionIn();
1389
1390    pH264Enc->hMFCH264Handle.bConfiguredMFCSrc = OMX_FALSE;
1391    pH264Enc->hMFCH264Handle.bConfiguredMFCDst = OMX_FALSE;
1392    pVideoEnc->bFirstOutput = OMX_FALSE;
1393    pExynosComponent->bUseFlagEOF = OMX_TRUE;
1394    pExynosComponent->bSaveFlagEOS = OMX_FALSE;
1395
1396    eColorFormat = pExynosInputPort->portDefinition.format.video.eColorFormat;
1397    if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
1398        if (eColorFormat == OMX_COLOR_FormatAndroidOpaque) {
1399            pExynosInputPort->bufferProcessType = BUFFER_COPY;
1400        } else {
1401            pExynosInputPort->bufferProcessType = BUFFER_SHARE;
1402        }
1403    }
1404
1405    /* H.264 Codec Open */
1406    ret = H264CodecOpen(pH264Enc);
1407    if (ret != OMX_ErrorNone) {
1408        goto EXIT;
1409    }
1410
1411    pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1412    pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1413    pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1414
1415    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1416        Exynos_OSAL_SemaphoreCreate(&pExynosInputPort->codecSemID);
1417        Exynos_OSAL_QueueCreate(&pExynosInputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1418    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1419        /*************/
1420        /*    TBD    */
1421        /*************/
1422        /* Does not require any actions? */
1423    }
1424
1425    Set_H264Enc_Param(pExynosComponent);
1426    pEncParam = &pMFCH264Handle->encParam;
1427    if (pEncOps->Set_EncParam) {
1428        if(pEncOps->Set_EncParam(pH264Enc->hMFCH264Handle.hMFCHandle, pEncParam) != VIDEO_ERROR_NONE) {
1429            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
1430            ret = OMX_ErrorInsufficientResources;
1431            goto EXIT;
1432        }
1433    }
1434
1435    if (pInbufOps->Set_Shareable) {
1436        pInbufOps->Set_Shareable(pH264Enc->hMFCH264Handle.hMFCHandle);
1437    }
1438
1439    if ((pExynosInputPort->bufferProcessType & BUFFER_SHARE) == BUFFER_SHARE) {
1440        inputBufferNumber = MAX_VIDEO_INPUTBUFFER_NUM;
1441    } else if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1442        inputBufferNumber = MFC_INPUT_BUFFER_NUM_MAX;
1443    }
1444
1445    Exynos_OSAL_Memset(&bufferConf, 0, sizeof(bufferConf));
1446
1447    /* input buffer info: only 3 config values needed */
1448    bufferConf.eColorFormat = pEncParam->commonParam.FrameMap;
1449    bufferConf.nFrameWidth = pExynosInputPort->portDefinition.format.video.nFrameWidth;
1450    bufferConf.nFrameHeight = pExynosInputPort->portDefinition.format.video.nFrameHeight;
1451
1452    /* set input buffer geometry */
1453    if (pInbufOps->Set_Geometry) {
1454        if (pInbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1455            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for input buffer");
1456            ret = OMX_ErrorInsufficientResources;
1457            goto EXIT;
1458        }
1459    }
1460
1461    /* should be done before prepare input buffer */
1462    if (pInbufOps->Enable_Cacheable) {
1463        if (pInbufOps->Enable_Cacheable(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
1464            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup cacheable input buffer");
1465            ret = OMX_ErrorInsufficientResources;
1466            goto EXIT;
1467        }
1468    }
1469
1470    /* setup input buffer */
1471    if (pInbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, inputBufferNumber) != VIDEO_ERROR_NONE) {
1472        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup input buffer");
1473        ret = OMX_ErrorInsufficientResources;
1474        goto EXIT;
1475    }
1476
1477    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1478        /* Register input buffer */
1479        OMX_PTR pTempAddress[2] = {NULL, NULL};
1480        OMX_U32 TempAllocSize[2] = {0, 0};
1481
1482        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1483            pVideoEnc->pMFCEncInputBuffer[i] = Exynos_OSAL_Malloc(sizeof(CODEC_ENC_INPUT_BUFFER));
1484            /* Use ION Allocator */
1485            /*Alloc Y-Buffer */
1486            pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_YBUFFER_SIZE, NORMAL_MEMORY);
1487            pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize = DEFAULT_MFC_INPUT_YBUFFER_SIZE;
1488            pVideoEnc->pMFCEncInputBuffer[i]->YDataSize = 0;
1489            /*Alloc C-Buffer */
1490            pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr = (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, DEFAULT_MFC_INPUT_CBUFFER_SIZE, NORMAL_MEMORY);
1491            pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize = DEFAULT_MFC_INPUT_CBUFFER_SIZE;
1492            pVideoEnc->pMFCEncInputBuffer[i]->CDataSize = 0;
1493
1494            pTempAddress[0] = pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr;
1495            pTempAddress[1] = pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr;
1496            TempAllocSize[0] = pVideoEnc->pMFCEncInputBuffer[i]->YBufferSize;
1497            TempAllocSize[1] = pVideoEnc->pMFCEncInputBuffer[i]->CBufferSize;
1498
1499            if ((pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr == NULL) ||
1500                (pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr == NULL)) {
1501                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Fail input buffer");
1502                ret = OMX_ErrorInsufficientResources;
1503                goto EXIT;
1504            }
1505
1506            if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1507                                    (unsigned char **)pTempAddress,
1508                                    (unsigned int *)TempAllocSize) != VIDEO_ERROR_NONE) {
1509                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1510                ret = OMX_ErrorInsufficientResources;
1511                goto EXIT;
1512            }
1513
1514            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]);
1515            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->YVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
1516            Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "pVideoEnc->pMFCEncInputBuffer[%d]->CVirAddr: 0x%x", i, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
1517
1518            Exynos_CodecBufferEnQueue(pExynosComponent, INPUT_PORT_INDEX, pVideoEnc->pMFCEncInputBuffer[i]);
1519        }
1520    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1521        OMX_U32 TempAllocSize[2] = {0, 0};
1522        if (pExynosInputPort->bStoreMetaData == OMX_TRUE) {
1523            TempAllocSize[0] = ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameWidth) * ALIGN_TO_16B(pExynosInputPort->portDefinition.format.video.nFrameHeight);
1524            TempAllocSize[1] = ALIGN(TempAllocSize[0]/2,256);
1525        }
1526
1527        /* Register input buffer */
1528        for (i = 0; i < pExynosInputPort->portDefinition.nBufferCountActual; i++) {
1529            if (pInbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1530                                    (unsigned char **)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
1531                                    (pExynosInputPort->bStoreMetaData ? (unsigned int *)TempAllocSize :
1532                                    (unsigned int *)&pExynosInputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen)) != VIDEO_ERROR_NONE) {
1533                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register input buffer");
1534                ret = OMX_ErrorInsufficientResources;
1535                goto EXIT;
1536            }
1537        }
1538    }
1539
1540    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1541        Exynos_OSAL_SemaphoreCreate(&pExynosOutputPort->codecSemID);
1542        Exynos_OSAL_QueueCreate(&pExynosOutputPort->codecBufferQ, MAX_QUEUE_ELEMENTS);
1543    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1544        /*************/
1545        /*    TBD    */
1546        /*************/
1547        /* Does not require any actions. */
1548    }
1549
1550    /* set geometry for output (dst) */
1551    if (pOutbufOps->Set_Geometry) {
1552        /* only 2 config values needed */
1553        bufferConf.eCompressionFormat = VIDEO_CODING_AVC;
1554        bufferConf.nSizeImage = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
1555
1556        if (pOutbufOps->Set_Geometry(pH264Enc->hMFCH264Handle.hMFCHandle, &bufferConf) != VIDEO_ERROR_NONE) {
1557            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to set geometry for output buffer");
1558            ret = OMX_ErrorInsufficientResources;
1559            goto EXIT;
1560        }
1561    }
1562    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s:%d", __FUNCTION__, __LINE__);
1563
1564    /* should be done before prepare output buffer */
1565    if (pOutbufOps->Enable_Cacheable) {
1566        if (pOutbufOps->Enable_Cacheable(pH264Enc->hMFCH264Handle.hMFCHandle) != VIDEO_ERROR_NONE) {
1567            ret = OMX_ErrorInsufficientResources;
1568            goto EXIT;
1569        }
1570    }
1571
1572    if (pOutbufOps->Set_Shareable) {
1573        pOutbufOps->Set_Shareable(pH264Enc->hMFCH264Handle.hMFCHandle);
1574    }
1575
1576    if (pOutbufOps->Setup(pH264Enc->hMFCH264Handle.hMFCHandle, MFC_OUTPUT_BUFFER_NUM_MAX) != VIDEO_ERROR_NONE) {
1577        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to setup output buffer");
1578        ret = OMX_ErrorInsufficientResources;
1579        goto EXIT;
1580    }
1581
1582    OMX_U32 dataLen[2] = {0, 0};
1583    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1584        int OutBufferSize = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight * 3 / 2;
1585        /* Register input buffer */
1586        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1587            pVideoEnc->pMFCEncOutputBuffer[i] = (CODEC_ENC_OUTPUT_BUFFER *)Exynos_OSAL_Malloc(sizeof(CODEC_ENC_OUTPUT_BUFFER));
1588            pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr =
1589                (void *)Exynos_OSAL_SharedMemory_Alloc(pVideoEnc->hSharedMemory, OutBufferSize, NORMAL_MEMORY);
1590            pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize = OutBufferSize;
1591            pVideoEnc->pMFCEncOutputBuffer[i]->dataSize = 0;
1592
1593            if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr == NULL) {
1594                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Alloc output buffer");
1595                ret = OMX_ErrorInsufficientResources;
1596                goto EXIT;
1597            }
1598
1599            if (pOutbufOps->Register(pH264Enc->hMFCH264Handle.hMFCHandle,
1600                                     (unsigned char **)(&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr),
1601                                     (unsigned int *)&pVideoEnc->pMFCEncOutputBuffer[i]->bufferSize) != VIDEO_ERROR_NONE) {
1602                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1603                ret = OMX_ErrorInsufficientResources;
1604                goto EXIT;
1605            }
1606            pOutbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle,
1607                                     (unsigned char **)&pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr,
1608                                     (unsigned int *)dataLen, 1, NULL);
1609        }
1610    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1611        /* Register input buffer */
1612        /*************/
1613        /*    TBD    */
1614        /*************/
1615        for (i = 0; i < pExynosOutputPort->portDefinition.nBufferCountActual; i++) {
1616            if (pOutbufOps->Register(hMFCHandle,
1617                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
1618                                     (unsigned int *)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->nAllocLen) != VIDEO_ERROR_NONE) {
1619                Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to Register output buffer");
1620                ret = OMX_ErrorInsufficientResources;
1621                goto EXIT;
1622            }
1623            pOutbufOps->Enqueue(pH264Enc->hMFCH264Handle.hMFCHandle,
1624                                     (unsigned char **)&pExynosOutputPort->extendBufferHeader[i].OMXBufferHeader->pBuffer,
1625                                     (unsigned int *)dataLen, 1, NULL);
1626        }
1627    }
1628
1629    pH264Enc->bSourceStart = OMX_FALSE;
1630    Exynos_OSAL_SignalCreate(&pH264Enc->hSourceStartEvent);
1631    pH264Enc->bDestinationStart = OMX_FALSE;
1632    Exynos_OSAL_SignalCreate(&pH264Enc->hDestinationStartEvent);
1633
1634    Exynos_OSAL_Memset(pExynosComponent->timeStamp, -19771003, sizeof(OMX_TICKS) * MAX_TIMESTAMP);
1635    Exynos_OSAL_Memset(pExynosComponent->nFlags, 0, sizeof(OMX_U32) * MAX_FLAGS);
1636    pH264Enc->hMFCH264Handle.indexTimestamp = 0;
1637    pH264Enc->hMFCH264Handle.outputIndexTimestamp = 0;
1638
1639    pExynosComponent->getAllDelayBuffer = OMX_FALSE;
1640
1641#if 0//defined(USE_CSC_GSCALER)
1642    csc_method = CSC_METHOD_HW; //in case of Use ION buffer.
1643#endif
1644    pVideoEnc->csc_handle = csc_init(csc_method);
1645    if (pVideoEnc->csc_handle == NULL) {
1646        ret = OMX_ErrorInsufficientResources;
1647        goto EXIT;
1648    }
1649    pVideoEnc->csc_set_format = OMX_FALSE;
1650
1651EXIT:
1652    FunctionOut();
1653
1654    return ret;
1655}
1656
1657/* MFC Terminate */
1658OMX_ERRORTYPE Exynos_H264Enc_Terminate(OMX_COMPONENTTYPE *pOMXComponent)
1659{
1660    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
1661    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1662    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle);
1663    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1664    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1665    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1666    OMX_PTR                hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1667
1668    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1669    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1670    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1671
1672    int i = 0;
1673
1674    FunctionIn();
1675
1676    if (pVideoEnc->csc_handle != NULL) {
1677        csc_deinit(pVideoEnc->csc_handle);
1678        pVideoEnc->csc_handle = NULL;
1679    }
1680
1681    Exynos_OSAL_SignalTerminate(pH264Enc->hDestinationStartEvent);
1682    pH264Enc->hDestinationStartEvent = NULL;
1683    pH264Enc->bDestinationStart = OMX_FALSE;
1684    Exynos_OSAL_SignalTerminate(pH264Enc->hSourceStartEvent);
1685    pH264Enc->hSourceStartEvent = NULL;
1686    pH264Enc->bSourceStart = OMX_FALSE;
1687
1688    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1689        for (i = 0; i < MFC_INPUT_BUFFER_NUM_MAX; i++) {
1690            if (pVideoEnc->pMFCEncInputBuffer[i] != NULL) {
1691                if (pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr != NULL)
1692                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr);
1693                if (pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr != NULL)
1694                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncInputBuffer[i]->CVirAddr);
1695                Exynos_OSAL_Free(pVideoEnc->pMFCEncInputBuffer[i]);
1696                pVideoEnc->pMFCEncInputBuffer[i] = NULL;
1697            }
1698        }
1699
1700        Exynos_OSAL_QueueTerminate(&pExynosInputPort->codecBufferQ);
1701        Exynos_OSAL_SemaphoreTerminate(pExynosInputPort->codecSemID);
1702    } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1703        /*************/
1704        /*    TBD    */
1705        /*************/
1706        /* Does not require any actions. */
1707    }
1708
1709    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1710        for (i = 0; i < MFC_OUTPUT_BUFFER_NUM_MAX; i++) {
1711            if (pVideoEnc->pMFCEncOutputBuffer[i] != NULL) {
1712                if (pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr != NULL)
1713                    Exynos_OSAL_SharedMemory_Free(pVideoEnc->hSharedMemory, pVideoEnc->pMFCEncOutputBuffer[i]->VirAddr);
1714                Exynos_OSAL_Free(pVideoEnc->pMFCEncOutputBuffer[i]);
1715                pVideoEnc->pMFCEncOutputBuffer[i] = NULL;
1716            }
1717        }
1718
1719        Exynos_OSAL_QueueTerminate(&pExynosOutputPort->codecBufferQ);
1720        Exynos_OSAL_SemaphoreTerminate(pExynosOutputPort->codecSemID);
1721    } else if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
1722        /*************/
1723        /*    TBD    */
1724        /*************/
1725        /* Does not require any actions. */
1726    }
1727    H264CodecClose(pH264Enc);
1728
1729EXIT:
1730    FunctionOut();
1731
1732    return ret;
1733}
1734
1735OMX_ERRORTYPE Exynos_H264Enc_SrcIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
1736{
1737    OMX_ERRORTYPE               ret = OMX_ErrorNone;
1738    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1739    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1740    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1741    void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1742    EXYNOS_OMX_BASEPORT *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1743    EXYNOS_OMX_BASEPORT *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
1744    OMX_U32  oneFrameSize = pSrcInputData->dataLen;
1745    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1746    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1747    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1748    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1749    int i;
1750
1751    FunctionIn();
1752
1753    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_FALSE) {
1754        ret = H264CodecDstSetup(pOMXComponent);
1755    }
1756
1757    if (pH264Enc->hMFCH264Handle.bConfiguredMFCSrc == OMX_FALSE) {
1758        ret = H264CodecSrcSetup(pOMXComponent, pSrcInputData);
1759        goto EXIT;
1760    }
1761
1762    if ((pSrcInputData->dataLen >= 0) ||
1763        ((pSrcInputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1764        OMX_PTR pMFCYUVVirBuffer[2] = {NULL, NULL};
1765        OMX_U32 pMFCYUVDataSize[2]  = {NULL, NULL};
1766
1767        pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->timeStamp;
1768        pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.indexTimestamp] = pSrcInputData->nFlags;
1769        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);
1770        pEncOps->Set_FrameTag(hMFCHandle, pH264Enc->hMFCH264Handle.indexTimestamp);
1771        pH264Enc->hMFCH264Handle.indexTimestamp++;
1772        pH264Enc->hMFCH264Handle.indexTimestamp %= MAX_TIMESTAMP;
1773
1774        /* queue work for input buffer */
1775        if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1776            CODEC_ENC_INPUT_BUFFER *codecInputBuffer = (CODEC_ENC_INPUT_BUFFER *)pSrcInputData->pPrivate;
1777            pMFCYUVDataSize[0] = codecInputBuffer->YDataSize;
1778            pMFCYUVDataSize[1] = codecInputBuffer->CDataSize;
1779        } else if (pExynosInputPort->bufferProcessType == BUFFER_SHARE) {
1780            pMFCYUVDataSize[0] = pExynosInputPort->portDefinition.format.video.nFrameWidth * pExynosInputPort->portDefinition.format.video.nFrameHeight; //codecInputBuffer->YDataSize;
1781            pMFCYUVDataSize[1] = pMFCYUVDataSize[0]/2;
1782        }
1783
1784        Exynos_OSAL_Log(EXYNOS_LOG_TRACE, "Exynos_H264Enc_SrcIn(): oneFrameSize: %d, bufferHeader: 0x%x", oneFrameSize, pSrcInputData->bufferHeader);
1785
1786        pMFCYUVVirBuffer[0] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[0];
1787        pMFCYUVVirBuffer[1] = pSrcInputData->buffer.multiPlaneBuffer.dataBuffer[1];
1788
1789        codecReturn = pInbufOps->Enqueue(hMFCHandle, (unsigned char **)pMFCYUVVirBuffer,
1790                              (unsigned int *)pMFCYUVDataSize, 2, pSrcInputData->bufferHeader);
1791        if (codecReturn != VIDEO_ERROR_NONE) {
1792            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pInbufOps->Enqueue", __FUNCTION__, __LINE__);
1793            ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1794            goto EXIT;
1795        }
1796
1797//        if (pH264Enc->bSourceStart ==OMX_TRUE)
1798//            H264CodecStart(pOMXComponent, INPUT_PORT_INDEX);
1799    }
1800
1801    ret = OMX_ErrorNone;
1802
1803EXIT:
1804    FunctionOut();
1805
1806    return ret;
1807}
1808
1809OMX_ERRORTYPE Exynos_H264Enc_SrcOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
1810{
1811    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1812    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1813    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1814    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1815    void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1816    EXYNOS_OMX_BASEPORT     *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
1817    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1818    ExynosVideoEncBufferOps *pInbufOps  = pH264Enc->hMFCH264Handle.pInbufOps;
1819    ExynosVideoBuffer       *pVideoBuffer;
1820
1821    FunctionIn();
1822
1823    pVideoBuffer = pInbufOps->Dequeue(hMFCHandle);
1824
1825    pSrcOutputData->dataLen       = 0;
1826    pSrcOutputData->usedDataLen   = 0;
1827    pSrcOutputData->remainDataLen = 0;
1828    pSrcOutputData->nFlags    = 0;
1829    pSrcOutputData->timeStamp = 0;
1830
1831    if (pVideoBuffer == NULL) {
1832        pSrcOutputData->buffer.singlePlaneBuffer.dataBuffer = NULL;
1833        pSrcOutputData->allocSize  = 0;
1834        pSrcOutputData->pPrivate = NULL;
1835        pSrcOutputData->bufferHeader = NULL;
1836    } else {
1837        pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] = pVideoBuffer->planes[0].addr;
1838        pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[1] = pVideoBuffer->planes[1].addr;
1839        pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[2] = pVideoBuffer->planes[2].addr;
1840        pSrcOutputData->allocSize  = pVideoBuffer->planes[0].allocSize +
1841                                        pVideoBuffer->planes[1].allocSize +
1842                                        pVideoBuffer->planes[2].allocSize;
1843
1844        if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
1845            int i = 0;
1846            while (pSrcOutputData->buffer.multiPlaneBuffer.dataBuffer[0] != pVideoEnc->pMFCEncInputBuffer[i]->YVirAddr) {
1847                if (i >= MFC_INPUT_BUFFER_NUM_MAX) {
1848                    Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - Lost buffer", __FUNCTION__, __LINE__);
1849                    ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1850                    goto EXIT;
1851                }
1852                i++;
1853            }
1854            pVideoEnc->pMFCEncInputBuffer[i]->YDataSize = 0;
1855            pVideoEnc->pMFCEncInputBuffer[i]->CDataSize = 0;
1856            pSrcOutputData->pPrivate = pVideoEnc->pMFCEncInputBuffer[i];
1857        }
1858
1859        /* For Share Buffer */
1860        pSrcOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE*)pVideoBuffer->pPrivate;
1861    }
1862
1863    ret = OMX_ErrorNone;
1864
1865EXIT:
1866    FunctionOut();
1867
1868    return ret;
1869}
1870
1871OMX_ERRORTYPE Exynos_H264Enc_DstIn(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
1872{
1873    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1874    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1875    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1876    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1877    void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1878    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1879    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1880    OMX_U32 dataLen = 0;
1881    ExynosVideoErrorType codecReturn = VIDEO_ERROR_NONE;
1882
1883    FunctionIn();
1884
1885    if (pDstInputData->buffer.singlePlaneBuffer.dataBuffer == NULL) {
1886        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "Failed to find input buffer");
1887        ret = OMX_ErrorBadParameter;
1888        goto EXIT;
1889    }
1890
1891    codecReturn = pOutbufOps->Enqueue(hMFCHandle,
1892                     (unsigned char **)&pDstInputData->buffer.singlePlaneBuffer.dataBuffer,
1893                     (unsigned int *)&dataLen, 1, pDstInputData->bufferHeader);
1894
1895    if (codecReturn != VIDEO_ERROR_NONE) {
1896        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - pOutbufOps->Enqueue", __FUNCTION__, __LINE__);
1897        ret = (OMX_ERRORTYPE)OMX_ErrorCodecEncode;
1898        goto EXIT;
1899    }
1900
1901//    if (pH264Enc->bDestinationStart ==OMX_TRUE)
1902//        H264CodecStart(pOMXComponent, OUTPUT_PORT_INDEX);
1903
1904    ret = OMX_ErrorNone;
1905
1906EXIT:
1907    FunctionOut();
1908
1909    return ret;
1910}
1911
1912OMX_ERRORTYPE Exynos_H264Enc_DstOut(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
1913{
1914    OMX_ERRORTYPE                  ret = OMX_ErrorNone;
1915    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
1916    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
1917    EXYNOS_H264ENC_HANDLE         *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
1918    void                          *hMFCHandle = pH264Enc->hMFCH264Handle.hMFCHandle;
1919    ExynosVideoEncOps       *pEncOps    = pH264Enc->hMFCH264Handle.pEncOps;
1920    ExynosVideoEncBufferOps *pOutbufOps = pH264Enc->hMFCH264Handle.pOutbufOps;
1921    ExynosVideoBuffer       *pVideoBuffer;
1922    ExynosVideoFrameStatusType displayStatus = VIDEO_FRAME_STATUS_UNKNOWN;
1923    ExynosVideoGeometry bufferGeometry;
1924    OMX_S32 indexTimestamp = 0;
1925
1926    FunctionIn();
1927
1928    if (pH264Enc->bDestinationStart == OMX_FALSE) {
1929        ret = OMX_ErrorNone;
1930        goto EXIT;
1931    }
1932
1933    if ((pVideoBuffer = pOutbufOps->Dequeue(hMFCHandle)) == NULL) {
1934        ret = OMX_ErrorNone;
1935        goto EXIT;
1936    }
1937
1938    pH264Enc->hMFCH264Handle.outputIndexTimestamp++;
1939    pH264Enc->hMFCH264Handle.outputIndexTimestamp %= MAX_TIMESTAMP;
1940
1941    pDstOutputData->buffer.singlePlaneBuffer.dataBuffer = pVideoBuffer->planes[0].addr;
1942    pDstOutputData->allocSize   = pVideoBuffer->planes[0].allocSize;
1943    pDstOutputData->dataLen     = pVideoBuffer->planes[0].dataSize;
1944    pDstOutputData->remainDataLen = pVideoBuffer->planes[0].dataSize;
1945    pDstOutputData->usedDataLen = 0;
1946    pDstOutputData->pPrivate = pVideoBuffer;
1947    /* For Share Buffer */
1948    pDstOutputData->bufferHeader = (OMX_BUFFERHEADERTYPE *)pVideoBuffer->pPrivate;
1949
1950    if (pVideoEnc->bFirstOutput == OMX_FALSE) {
1951        OMX_U8 *p = NULL;
1952        int iSpsSize = 0;
1953        int iPpsSize = 0;
1954
1955        /* Calculate sps/pps size if needed */
1956        p = FindDelimiter((OMX_U8 *)(pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + 4),
1957                            pDstOutputData->dataLen - 4);
1958
1959        iSpsSize = (unsigned int)p - (unsigned int)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
1960        pH264Enc->hMFCH264Handle.headerData.pHeaderSPS =
1961            (OMX_PTR)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer;
1962        pH264Enc->hMFCH264Handle.headerData.SPSLen = iSpsSize;
1963
1964        iPpsSize = pDstOutputData->dataLen - iSpsSize;
1965        pH264Enc->hMFCH264Handle.headerData.pHeaderPPS =
1966            (OMX_U8 *)pDstOutputData->buffer.singlePlaneBuffer.dataBuffer + iSpsSize;
1967        pH264Enc->hMFCH264Handle.headerData.PPSLen = iPpsSize;
1968
1969        pDstOutputData->timeStamp = 0;
1970        pDstOutputData->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
1971        pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1972    } else {
1973        indexTimestamp = pEncOps->Get_FrameTag(pH264Enc->hMFCH264Handle.hMFCHandle);
1974        if ((indexTimestamp < 0) || (indexTimestamp >= MAX_TIMESTAMP)) {
1975            pDstOutputData->timeStamp = pExynosComponent->timeStamp[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
1976            pDstOutputData->nFlags = pExynosComponent->nFlags[pH264Enc->hMFCH264Handle.outputIndexTimestamp];
1977        } else {
1978            pDstOutputData->timeStamp = pExynosComponent->timeStamp[indexTimestamp];
1979            pDstOutputData->nFlags = pExynosComponent->nFlags[indexTimestamp];
1980        }
1981
1982        pDstOutputData->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
1983        if (pVideoBuffer->frameType == VIDEO_FRAME_I)
1984            pDstOutputData->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
1985    }
1986
1987    if ((displayStatus == VIDEO_FRAME_STATUS_CHANGE_RESOL) ||
1988        ((pDstOutputData->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
1989        pDstOutputData->remainDataLen = 0;
1990    }
1991
1992    ret = OMX_ErrorNone;
1993
1994EXIT:
1995    FunctionOut();
1996
1997    return ret;
1998}
1999
2000OMX_ERRORTYPE Exynos_H264Enc_srcInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcInputData)
2001{
2002    OMX_ERRORTYPE             ret = OMX_ErrorNone;
2003    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2004    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2005    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2006
2007    FunctionIn();
2008
2009    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2010        ret = OMX_ErrorNone;
2011        goto EXIT;
2012    }
2013    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2014        ret = OMX_ErrorNone;
2015        goto EXIT;
2016    }
2017
2018    ret = Exynos_H264Enc_SrcIn(pOMXComponent, pSrcInputData);
2019    if (ret != OMX_ErrorNone) {
2020        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcIn -> event is thrown to client", __FUNCTION__, __LINE__);
2021        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2022                                                pExynosComponent->callbackData,
2023                                                OMX_EventError, ret, 0, NULL);
2024    }
2025
2026EXIT:
2027    FunctionOut();
2028
2029    return ret;
2030}
2031
2032OMX_ERRORTYPE Exynos_H264Enc_srcOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pSrcOutputData)
2033{
2034    OMX_ERRORTYPE             ret = OMX_ErrorNone;
2035    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2036    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2037    EXYNOS_OMX_BASEPORT      *pExynosInputPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2038
2039    FunctionIn();
2040
2041    if ((!CHECK_PORT_ENABLED(pExynosInputPort)) || (!CHECK_PORT_POPULATED(pExynosInputPort))) {
2042        ret = OMX_ErrorNone;
2043        goto EXIT;
2044    }
2045
2046    if ((pExynosInputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2047        if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, INPUT_PORT_INDEX)) {
2048            ret = OMX_ErrorNone;
2049            goto EXIT;
2050        }
2051    }
2052    if ((pH264Enc->bSourceStart == OMX_FALSE) &&
2053       (!CHECK_PORT_BEING_FLUSHED(pExynosInputPort))) {
2054        Exynos_OSAL_SignalWait(pH264Enc->hSourceStartEvent, DEF_MAX_WAIT_TIME);
2055        Exynos_OSAL_SignalReset(pH264Enc->hSourceStartEvent);
2056    }
2057
2058    ret = Exynos_H264Enc_SrcOut(pOMXComponent, pSrcOutputData);
2059    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2060        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - SrcOut -> event is thrown to client", __FUNCTION__, __LINE__);
2061        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2062                                                pExynosComponent->callbackData,
2063                                                OMX_EventError, ret, 0, NULL);
2064    }
2065
2066EXIT:
2067    FunctionOut();
2068
2069    return ret;
2070}
2071
2072OMX_ERRORTYPE Exynos_H264Enc_dstInputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstInputData)
2073{
2074    OMX_ERRORTYPE             ret = OMX_ErrorNone;
2075    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2076    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2077    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2078
2079    FunctionIn();
2080
2081    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2082        ret = OMX_ErrorNone;
2083        goto EXIT;
2084    }
2085    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2086        ret = OMX_ErrorNone;
2087        goto EXIT;
2088    }
2089    if (pExynosOutputPort->bufferProcessType == BUFFER_SHARE) {
2090        if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2091           (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2092            Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2093            Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2094        }
2095    }
2096    if (pH264Enc->hMFCH264Handle.bConfiguredMFCDst == OMX_TRUE) {
2097        ret = Exynos_H264Enc_DstIn(pOMXComponent, pDstInputData);
2098        if (ret != OMX_ErrorNone) {
2099            Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstIn -> event is thrown to client", __FUNCTION__, __LINE__);
2100            pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2101                                                pExynosComponent->callbackData,
2102                                                OMX_EventError, ret, 0, NULL);
2103        }
2104    }
2105
2106EXIT:
2107    FunctionOut();
2108
2109    return ret;
2110}
2111
2112OMX_ERRORTYPE Exynos_H264Enc_dstOutputBufferProcess(OMX_COMPONENTTYPE *pOMXComponent, EXYNOS_OMX_DATA *pDstOutputData)
2113{
2114    OMX_ERRORTYPE             ret = OMX_ErrorNone;
2115    EXYNOS_OMX_BASECOMPONENT *pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2116    EXYNOS_H264ENC_HANDLE    *pH264Enc = (EXYNOS_H264ENC_HANDLE *)((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle;
2117    EXYNOS_OMX_BASEPORT      *pExynosOutputPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2118
2119    FunctionIn();
2120
2121    if ((!CHECK_PORT_ENABLED(pExynosOutputPort)) || (!CHECK_PORT_POPULATED(pExynosOutputPort))) {
2122        ret = OMX_ErrorNone;
2123        goto EXIT;
2124    }
2125    if (OMX_FALSE == Exynos_Check_BufferProcess_State(pExynosComponent, OUTPUT_PORT_INDEX)) {
2126        ret = OMX_ErrorNone;
2127        goto EXIT;
2128    }
2129
2130    if ((pExynosOutputPort->bufferProcessType & BUFFER_COPY) == BUFFER_COPY) {
2131        if ((pH264Enc->bDestinationStart == OMX_FALSE) &&
2132           (!CHECK_PORT_BEING_FLUSHED(pExynosOutputPort))) {
2133            Exynos_OSAL_SignalWait(pH264Enc->hDestinationStartEvent, DEF_MAX_WAIT_TIME);
2134            Exynos_OSAL_SignalReset(pH264Enc->hDestinationStartEvent);
2135        }
2136    }
2137    ret = Exynos_H264Enc_DstOut(pOMXComponent, pDstOutputData);
2138    if ((ret != OMX_ErrorNone) && (pExynosComponent->currentState == OMX_StateExecuting)) {
2139        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "%s: %d: Failed - DstOut -> event is thrown to client", __FUNCTION__, __LINE__);
2140        pExynosComponent->pCallbacks->EventHandler((OMX_HANDLETYPE)pOMXComponent,
2141                                                pExynosComponent->callbackData,
2142                                                OMX_EventError, ret, 0, NULL);
2143    }
2144
2145EXIT:
2146    FunctionOut();
2147
2148    return ret;
2149}
2150
2151OSCL_EXPORT_REF OMX_ERRORTYPE Exynos_OMX_ComponentInit(OMX_HANDLETYPE hComponent, OMX_STRING componentName)
2152{
2153    OMX_ERRORTYPE                  ret              = OMX_ErrorNone;
2154    OMX_COMPONENTTYPE             *pOMXComponent    = NULL;
2155    EXYNOS_OMX_BASECOMPONENT      *pExynosComponent = NULL;
2156    EXYNOS_OMX_BASEPORT           *pExynosPort      = NULL;
2157    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc        = NULL;
2158    EXYNOS_H264ENC_HANDLE         *pH264Enc         = NULL;
2159    int i = 0;
2160
2161    FunctionIn();
2162
2163    if ((hComponent == NULL) || (componentName == NULL)) {
2164        ret = OMX_ErrorBadParameter;
2165        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, Line:%d", __LINE__);
2166        goto EXIT;
2167    }
2168    if (Exynos_OSAL_Strcmp(EXYNOS_OMX_COMPONENT_H264_ENC, componentName) != 0) {
2169        ret = OMX_ErrorBadParameter;
2170        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorBadParameter, componentName:%s, Line:%d", componentName, __LINE__);
2171        goto EXIT;
2172    }
2173
2174    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2175    ret = Exynos_OMX_VideoEncodeComponentInit(pOMXComponent);
2176    if (ret != OMX_ErrorNone) {
2177        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_Error, Line:%d", __LINE__);
2178        goto EXIT;
2179    }
2180    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2181    pExynosComponent->codecType = HW_VIDEO_ENC_CODEC;
2182
2183    pExynosComponent->componentName = (OMX_STRING)Exynos_OSAL_Malloc(MAX_OMX_COMPONENT_NAME_SIZE);
2184    if (pExynosComponent->componentName == NULL) {
2185        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2186        ret = OMX_ErrorInsufficientResources;
2187        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2188        goto EXIT;
2189    }
2190    Exynos_OSAL_Memset(pExynosComponent->componentName, 0, MAX_OMX_COMPONENT_NAME_SIZE);
2191
2192    pH264Enc = Exynos_OSAL_Malloc(sizeof(EXYNOS_H264ENC_HANDLE));
2193    if (pH264Enc == NULL) {
2194        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2195        ret = OMX_ErrorInsufficientResources;
2196        Exynos_OSAL_Log(EXYNOS_LOG_ERROR, "OMX_ErrorInsufficientResources, Line:%d", __LINE__);
2197        goto EXIT;
2198    }
2199    Exynos_OSAL_Memset(pH264Enc, 0, sizeof(EXYNOS_H264ENC_HANDLE));
2200    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2201    pVideoEnc->hCodecHandle = (OMX_HANDLETYPE)pH264Enc;
2202    pVideoEnc->quantization.nQpI = 20;
2203    pVideoEnc->quantization.nQpP = 20;
2204    pVideoEnc->quantization.nQpB = 20;
2205
2206    Exynos_OSAL_Strcpy(pExynosComponent->componentName, EXYNOS_OMX_COMPONENT_H264_ENC);
2207    /* Set componentVersion */
2208    pExynosComponent->componentVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2209    pExynosComponent->componentVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2210    pExynosComponent->componentVersion.s.nRevision     = REVISION_NUMBER;
2211    pExynosComponent->componentVersion.s.nStep         = STEP_NUMBER;
2212    /* Set specVersion */
2213    pExynosComponent->specVersion.s.nVersionMajor = VERSIONMAJOR_NUMBER;
2214    pExynosComponent->specVersion.s.nVersionMinor = VERSIONMINOR_NUMBER;
2215    pExynosComponent->specVersion.s.nRevision     = REVISION_NUMBER;
2216    pExynosComponent->specVersion.s.nStep         = STEP_NUMBER;
2217
2218    /* Input port */
2219    pExynosPort = &pExynosComponent->pExynosPort[INPUT_PORT_INDEX];
2220    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2221    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2222    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2223    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_INPUT_BUFFER_SIZE;
2224    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
2225    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2226    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "raw/video");
2227    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
2228    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2229    pExynosPort->bufferProcessType = BUFFER_COPY;
2230    pExynosPort->portWayType = WAY2_PORT;
2231
2232    /* Output port */
2233    pExynosPort = &pExynosComponent->pExynosPort[OUTPUT_PORT_INDEX];
2234    pExynosPort->portDefinition.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
2235    pExynosPort->portDefinition.format.video.nFrameHeight= DEFAULT_FRAME_HEIGHT;
2236    pExynosPort->portDefinition.format.video.nStride = 0; /*DEFAULT_FRAME_WIDTH;*/
2237    pExynosPort->portDefinition.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUFFER_SIZE;
2238    pExynosPort->portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
2239    Exynos_OSAL_Memset(pExynosPort->portDefinition.format.video.cMIMEType, 0, MAX_OMX_MIMETYPE_SIZE);
2240    Exynos_OSAL_Strcpy(pExynosPort->portDefinition.format.video.cMIMEType, "video/avc");
2241    pExynosPort->portDefinition.format.video.eColorFormat = OMX_COLOR_FormatUnused;
2242    pExynosPort->portDefinition.bEnabled = OMX_TRUE;
2243    pExynosPort->bufferProcessType = BUFFER_COPY;
2244    pExynosPort->portWayType = WAY2_PORT;
2245
2246    for(i = 0; i < ALL_PORT_NUM; i++) {
2247        INIT_SET_SIZE_VERSION(&pH264Enc->AVCComponent[i], OMX_VIDEO_PARAM_AVCTYPE);
2248        pH264Enc->AVCComponent[i].nPortIndex = i;
2249        pH264Enc->AVCComponent[i].eProfile   = OMX_VIDEO_AVCProfileBaseline;
2250        pH264Enc->AVCComponent[i].eLevel     = OMX_VIDEO_AVCLevel31;
2251
2252        pH264Enc->AVCComponent[i].nPFrames = 20;
2253    }
2254
2255    pOMXComponent->GetParameter      = &Exynos_H264Enc_GetParameter;
2256    pOMXComponent->SetParameter      = &Exynos_H264Enc_SetParameter;
2257    pOMXComponent->GetConfig         = &Exynos_H264Enc_GetConfig;
2258    pOMXComponent->SetConfig         = &Exynos_H264Enc_SetConfig;
2259    pOMXComponent->GetExtensionIndex = &Exynos_H264Enc_GetExtensionIndex;
2260    pOMXComponent->ComponentRoleEnum = &Exynos_H264Enc_ComponentRoleEnum;
2261    pOMXComponent->ComponentDeInit   = &Exynos_OMX_ComponentDeinit;
2262
2263    pExynosComponent->exynos_codec_componentInit      = &Exynos_H264Enc_Init;
2264    pExynosComponent->exynos_codec_componentTerminate = &Exynos_H264Enc_Terminate;
2265
2266    pVideoEnc->exynos_codec_srcInputProcess  = &Exynos_H264Enc_srcInputBufferProcess;
2267    pVideoEnc->exynos_codec_srcOutputProcess = &Exynos_H264Enc_srcOutputBufferProcess;
2268    pVideoEnc->exynos_codec_dstInputProcess  = &Exynos_H264Enc_dstInputBufferProcess;
2269    pVideoEnc->exynos_codec_dstOutputProcess = &Exynos_H264Enc_dstOutputBufferProcess;
2270
2271    pVideoEnc->exynos_codec_start         = &H264CodecStart;
2272    pVideoEnc->exynos_codec_stop          = &H264CodecStop;
2273    pVideoEnc->exynos_codec_bufferProcessRun = &H264CodecOutputBufferProcessRun;
2274    pVideoEnc->exynos_codec_enqueueAllBuffer = &H264CodecEnQueueAllBuffer;
2275
2276    pVideoEnc->exynos_checkInputFrame        = NULL;
2277    pVideoEnc->exynos_codec_getCodecInputPrivateData  = &GetCodecInputPrivateData;
2278    pVideoEnc->exynos_codec_getCodecOutputPrivateData = &GetCodecOutputPrivateData;
2279
2280    pVideoEnc->hSharedMemory = Exynos_OSAL_SharedMemory_Open();
2281    if (pVideoEnc->hSharedMemory == NULL) {
2282        Exynos_OSAL_Free(pH264Enc);
2283        pH264Enc = ((EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle)->hCodecHandle = NULL;
2284        Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2285        ret = OMX_ErrorInsufficientResources;
2286        goto EXIT;
2287    }
2288
2289    pExynosComponent->currentState = OMX_StateLoaded;
2290
2291    ret = OMX_ErrorNone;
2292
2293EXIT:
2294    FunctionOut();
2295
2296    return ret;
2297}
2298
2299OMX_ERRORTYPE Exynos_OMX_ComponentDeinit(OMX_HANDLETYPE hComponent)
2300{
2301    OMX_ERRORTYPE            ret = OMX_ErrorNone;
2302    OMX_COMPONENTTYPE          *pOMXComponent = NULL;
2303    EXYNOS_OMX_BASECOMPONENT   *pExynosComponent = NULL;
2304    EXYNOS_OMX_VIDEOENC_COMPONENT *pVideoEnc = NULL;
2305    EXYNOS_H264ENC_HANDLE      *pH264Enc         = NULL;
2306
2307    FunctionIn();
2308
2309    if (hComponent == NULL) {
2310        ret = OMX_ErrorBadParameter;
2311        goto EXIT;
2312    }
2313    pOMXComponent = (OMX_COMPONENTTYPE *)hComponent;
2314    pExynosComponent = (EXYNOS_OMX_BASECOMPONENT *)pOMXComponent->pComponentPrivate;
2315    pVideoEnc = (EXYNOS_OMX_VIDEOENC_COMPONENT *)pExynosComponent->hComponentHandle;
2316
2317    Exynos_OSAL_SharedMemory_Close(pVideoEnc->hSharedMemory);
2318
2319    Exynos_OSAL_Free(pExynosComponent->componentName);
2320    pExynosComponent->componentName = NULL;
2321
2322    pH264Enc = (EXYNOS_H264ENC_HANDLE *)pVideoEnc->hCodecHandle;
2323    if (pH264Enc != NULL) {
2324        Exynos_OSAL_Free(pH264Enc);
2325        pH264Enc = pVideoEnc->hCodecHandle = NULL;
2326    }
2327
2328    ret = Exynos_OMX_VideoEncodeComponentDeinit(pOMXComponent);
2329    if (ret != OMX_ErrorNone) {
2330        goto EXIT;
2331    }
2332
2333    ret = OMX_ErrorNone;
2334
2335EXIT:
2336    FunctionOut();
2337
2338    return ret;
2339}
2340