1/* 2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "codec_component_service.h" 17#include <hdf_base.h> 18#include <hdf_remote_service.h> 19#include <securec.h> 20#include <malloc.h> 21#include <unistd.h> 22#include <hitrace_meter.h> 23#include "v1_0/display_composer_type.h" 24#include "v1_1/imetadata.h" 25#include "codec_log_wrapper.h" 26 27#define AUDIO_CODEC_NAME "OMX.audio" 28 29namespace OHOS { 30namespace HDI { 31namespace Codec { 32namespace V3_0 { 33 34std::mutex g_mapperMtx; 35sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> g_mapperService; 36 37sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> GetMapperService() 38{ 39 std::lock_guard<std::mutex> lk(g_mapperMtx); 40 if (g_mapperService) { 41 return g_mapperService; 42 } 43 g_mapperService = OHOS::HDI::Display::Buffer::V1_0::IMapper::Get(true); 44 if (g_mapperService) { 45 CODEC_LOGI("get IMapper succ"); 46 return g_mapperService; 47 } 48 CODEC_LOGE("get IMapper failed"); 49 return nullptr; 50} 51 52std::mutex g_metaMtx; 53sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> g_metaService; 54 55sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> GetMetaService() 56{ 57 std::lock_guard<std::mutex> lk(g_metaMtx); 58 if (g_metaService) { 59 return g_metaService; 60 } 61 g_metaService = OHOS::HDI::Display::Buffer::V1_1::IMetadata::Get(true); 62 if (g_metaService) { 63 CODEC_LOGI("get IMetadata succ"); 64 return g_metaService; 65 } 66 CODEC_LOGE("get IMetadata failed"); 67 return nullptr; 68} 69 70void BufferDestructor(BufferHandle* handle) 71{ 72 if (handle == nullptr) { 73 return; 74 } 75 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> mapper = GetMapperService(); 76 if (mapper == nullptr) { 77 return; 78 } 79 sptr<NativeBuffer> buffer = new NativeBuffer(); 80 buffer->SetBufferHandle(handle, true); 81 mapper->FreeMem(buffer); 82} 83 84bool ReWrapNativeBuffer(sptr<NativeBuffer>& buffer) 85{ 86 if (buffer == nullptr) { 87 return true; 88 } 89 BufferHandle* handle = buffer->Move(); 90 if (handle == nullptr) { 91 return true; 92 } 93 buffer->SetBufferHandle(handle, true, BufferDestructor); 94 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> meta = GetMetaService(); 95 if (meta == nullptr) { 96 return false; 97 } 98 int32_t ret = meta->RegisterBuffer(buffer); 99 if (ret != Display::Composer::V1_0::DISPLAY_SUCCESS && 100 ret != Display::Composer::V1_0::DISPLAY_NOT_SUPPORT) { 101 CODEC_LOGE("RegisterBuffer failed, ret = %{public}d", ret); 102 return false; 103 } 104 return true; 105} 106 107bool CodecComponentService::ReWrapNativeBufferInOmxBuffer(const OmxCodecBuffer &inBuffer) 108{ 109 if (!isIPCMode_) { 110 return true; 111 } 112 return ReWrapNativeBuffer(const_cast<OmxCodecBuffer &>(inBuffer).bufferhandle); 113} 114 115CodecComponentService::CodecComponentService(const std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &node, 116 const std::shared_ptr<OHOS::Codec::Omx::ComponentMgr> mgr, const std::string name) 117{ 118 name_ = name; 119 node_ = node; 120 mgr_ = mgr; 121 isIPCMode_ = (HdfRemoteGetCallingPid() == getpid() ? false : true); 122#ifdef SUPPORT_ROLE 123 SetComponentRole(); 124#endif 125} 126CodecComponentService::~CodecComponentService() 127{ 128 if (node_ != nullptr) { 129 node_->ReleaseOMXResource(); 130 int32_t ret = node_->CloseHandle(); 131 if (ret != HDF_SUCCESS) { 132 CODEC_LOGE("CloseHandle failed, err[%{public}d]", ret); 133 } 134 node_ = nullptr; 135 ReleaseCache(); 136 } 137 name_ = ""; 138 mgr_ = nullptr; 139} 140 141void CodecComponentService::ReleaseCache() 142{ 143#ifdef CONFIG_USE_JEMALLOC_DFX_INTF 144 mallopt(M_FLUSH_THREAD_CACHE, 0); 145#endif 146} 147 148int32_t CodecComponentService::GetComponentVersion(CompVerInfo &verInfo) 149{ 150 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetComponentVersion"); 151 return node_->GetComponentVersion(verInfo); 152} 153 154int32_t CodecComponentService::SendCommand(CodecCommandType cmd, uint32_t param, const std::vector<int8_t> &cmdData) 155{ 156 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSendCommand"); 157 CODEC_LOGI("commandType: [%{public}d], command [%{public}d]", cmd, param); 158 return node_->SendCommand(cmd, param, const_cast<int8_t *>(cmdData.data())); 159} 160 161int32_t CodecComponentService::GetParameter(uint32_t index, const std::vector<int8_t> &inParamStruct, 162 std::vector<int8_t> &outParamStruct) 163{ 164 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetParameter"); 165 CODEC_LOGD("index [%{public}x]", index); 166 outParamStruct = inParamStruct; 167 return node_->GetParameter(static_cast<enum OMX_INDEXTYPE>(index), outParamStruct.data()); 168} 169 170int32_t CodecComponentService::SetParameter(uint32_t index, const std::vector<int8_t> ¶mStruct) 171{ 172 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetParameter"); 173 CODEC_LOGD("index [%{public}x]", index); 174 return node_->SetParameter(static_cast<enum OMX_INDEXTYPE>(index), paramStruct.data()); 175} 176 177int32_t CodecComponentService::GetConfig(uint32_t index, const std::vector<int8_t> &inCfgStruct, 178 std::vector<int8_t> &outCfgStruct) 179{ 180 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetConfig"); 181 CODEC_LOGD("index [%{public}x]", index); 182 outCfgStruct = inCfgStruct; 183 return node_->GetConfig(static_cast<enum OMX_INDEXTYPE>(index), outCfgStruct.data()); 184} 185 186int32_t CodecComponentService::SetConfig(uint32_t index, const std::vector<int8_t> &cfgStruct) 187{ 188 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetConfig"); 189 CODEC_LOGD("index [%{public}x]", index); 190 return node_->SetConfig(static_cast<enum OMX_INDEXTYPE>(index), cfgStruct.data()); 191} 192 193int32_t CodecComponentService::GetExtensionIndex(const std::string ¶mName, uint32_t &indexType) 194{ 195 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetExtensionIndex"); 196 CODEC_LOGI("paramName [%{public}s]", paramName.c_str()); 197 return node_->GetExtensionIndex(paramName.c_str(), indexType); 198} 199 200int32_t CodecComponentService::GetState(CodecStateType &state) 201{ 202 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecGetState"); 203 return node_->GetState(state); 204} 205 206int32_t CodecComponentService::ComponentTunnelRequest(uint32_t port, int32_t tunneledComp, uint32_t tunneledPort, 207 const CodecTunnelSetupType &inTunnelSetup, 208 CodecTunnelSetupType &outTunnelSetup) 209{ 210 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentTunnelRequest"); 211 CODEC_LOGI("port [%{public}d]", port); 212 outTunnelSetup = inTunnelSetup; 213 return node_->ComponentTunnelRequest(port, tunneledComp, tunneledPort, outTunnelSetup); 214} 215 216int32_t CodecComponentService::UseBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, OmxCodecBuffer &outBuffer) 217{ 218 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseBuffer"); 219 CODEC_LOGD("portIndex: [%{public}d]", portIndex); 220 if (!ReWrapNativeBufferInOmxBuffer(inBuffer)) { 221 return HDF_FAILURE; 222 } 223 outBuffer = const_cast<OmxCodecBuffer &>(inBuffer); 224 225 if (outBuffer.fd >= 0 && isIPCMode_ && outBuffer.bufferType != CODEC_BUFFER_TYPE_AVSHARE_MEM_FD && 226 outBuffer.bufferType != CODEC_BUFFER_TYPE_DMA_MEM_FD && 227 name_.find(AUDIO_CODEC_NAME) == std::string::npos) { 228 close(outBuffer.fd); 229 outBuffer.fd = -1; 230 } 231 if (outBuffer.fenceFd >= 0) { 232 close(outBuffer.fenceFd); 233 outBuffer.fenceFd = -1; 234 } 235 236 return node_->UseBuffer(portIndex, outBuffer); 237} 238 239int32_t CodecComponentService::AllocateBuffer(uint32_t portIndex, const OmxCodecBuffer &inBuffer, 240 OmxCodecBuffer &outBuffer) 241{ 242 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecAllocateBuffer"); 243 CODEC_LOGD("portIndex: [%{public}d]", portIndex); 244 outBuffer = inBuffer; 245 return node_->AllocateBuffer(portIndex, outBuffer); 246} 247 248int32_t CodecComponentService::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer) 249{ 250 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFreeBuffer"); 251 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer); 252 CODEC_LOGD("portIndex: [%{public}d], bufferId: [%{public}d]", portIndex, buffer.bufferId); 253 int32_t ret = node_->FreeBuffer(portIndex, buffer); 254 ReleaseCache(); 255 if (isIPCMode_ && bufferTemp.fd >= 0) { 256 close(bufferTemp.fd); 257 bufferTemp.fd = -1; 258 } 259 260 return ret; 261} 262 263int32_t CodecComponentService::EmptyThisBuffer(const OmxCodecBuffer &buffer) 264{ 265 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecEmptyThisBuffer"); 266 if (!ReWrapNativeBufferInOmxBuffer(buffer)) { 267 return HDF_FAILURE; 268 } 269 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer); 270 int32_t ret = node_->EmptyThisBuffer(bufferTemp); 271 if (isIPCMode_ && bufferTemp.fd >= 0) { 272 close(bufferTemp.fd); 273 bufferTemp.fd = -1; 274 } 275 276 return ret; 277} 278 279int32_t CodecComponentService::FillThisBuffer(const OmxCodecBuffer &buffer) 280{ 281 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecFillThisBuffer"); 282 if (!ReWrapNativeBufferInOmxBuffer(buffer)) { 283 return HDF_FAILURE; 284 } 285 OmxCodecBuffer &bufferTemp = const_cast<OmxCodecBuffer &>(buffer); 286 int32_t ret = node_->FillThisBuffer(bufferTemp); 287 if (isIPCMode_ && bufferTemp.fd >= 0) { 288 close(bufferTemp.fd); 289 bufferTemp.fd = -1; 290 } 291 292 return ret; 293} 294 295int32_t CodecComponentService::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData) 296{ 297 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetCallbacks"); 298 CODEC_LOGI("service impl!"); 299 CHECK_AND_RETURN_RET_LOG(callbacks != nullptr, HDF_ERR_INVALID_PARAM, "callbacks is null"); 300 return node_->SetCallbacks(callbacks, appData); 301} 302 303int32_t CodecComponentService::ComponentDeInit() 304{ 305 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentDeInit"); 306 CODEC_LOGI("service impl!"); 307 return node_->ComponentDeInit(); 308} 309 310int32_t CodecComponentService::UseEglImage(uint32_t portIndex, const OmxCodecBuffer &inBuffer, 311 OmxCodecBuffer &outBuffer, const std::vector<int8_t> &eglImage) 312{ 313 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecUseEglImage"); 314 CODEC_LOGI("portIndex [%{public}d]", portIndex); 315 outBuffer = inBuffer; 316 return node_->UseEglImage(outBuffer, portIndex, eglImage.data()); 317} 318 319int32_t CodecComponentService::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index) 320{ 321 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecComponentRoleEnum"); 322 CODEC_LOGI("index [%{public}d]", index); 323 return node_->ComponentRoleEnum(role, index); 324} 325 326void CodecComponentService::SetComponentRole() 327{ 328 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecSetComponentRole"); 329 if (name_ == "") { 330 CODEC_LOGE("compName is null"); 331 return; 332 } 333 OHOS::Codec::Omx::CodecOMXCore *core; 334 auto err = mgr_->GetCoreOfComponent(core, name_); 335 if (err != HDF_SUCCESS) { 336 CODEC_LOGE("core is null"); 337 return; 338 } 339 340 std::vector<std::string> roles; 341 int32_t ret = core->GetRolesOfComponent(name_, roles); 342 if (ret != HDF_SUCCESS) { 343 CODEC_LOGE("GetRoleOfComponent return err [%{public}d]", ret); 344 return; 345 } 346 if (roles.empty()) { 347 CODEC_LOGE("role of component is empty"); 348 return; 349 } 350 uint32_t roleIndex = 0; 351 CODEC_LOGI("RoleName = [%{public}s]", roles[roleIndex].c_str()); 352 353 OMX_PARAM_COMPONENTROLETYPE role; 354 errno_t res = strncpy_s(reinterpret_cast<char *>(role.cRole), OMX_MAX_STRINGNAME_SIZE, 355 roles[roleIndex].c_str(), roles[roleIndex].length()); 356 if (res != EOK) { 357 CODEC_LOGE("strncpy_s return err [%{public}d]", err); 358 return; 359 } 360 role.nSize = sizeof(role); 361 ret = node_->SetParameter(OMX_IndexParamStandardComponentRole, reinterpret_cast<int8_t *>(&role)); 362 if (ret != HDF_SUCCESS) { 363 CODEC_LOGE("OMX_IndexParamStandardComponentRole err [%{public}d]", ret); 364 } 365} 366 367int32_t CodecComponentService::SetParameterWithBuffer(uint32_t index, const std::vector<int8_t>& paramStruct, 368 const OmxCodecBuffer& inBuffer) 369{ 370 return node_->SetParameterWithBuffer(index, paramStruct, inBuffer); 371} 372 373const std::string &CodecComponentService::GetComponentCompName() const 374{ 375 return name_; 376} 377 378void CodecComponentService::GetComponentNode(std::shared_ptr<OHOS::Codec::Omx::ComponentNode> &dumpNode_) 379{ 380 dumpNode_ = node_; 381} 382 383} // namespace V3_0 384} // namespace Codec 385} // namespace HDI 386} // namespace OHOS 387