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