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