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