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