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