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 "component_node.h" 17#include <ashmem.h> 18#include <securec.h> 19#include <unistd.h> 20#include <sys/stat.h> 21#include <hitrace_meter.h> 22#include "codec_log_wrapper.h" 23#include "component_mgr.h" 24#include "icodec_buffer.h" 25#include "sys/mman.h" 26#include "v3_0/codec_ext_types.h" 27#include "codec_component_service.h" 28 29#define AUDIO_CODEC_NAME "OMX.audio" 30 31using OHOS::HDI::Codec::V3_0::EventInfo; 32using OHOS::HDI::Codec::V3_0::CodecEventType; 33using OHOS::HDI::Codec::V3_0::CodecStateType; 34using OHOS::HDI::Codec::V3_0::CodecCommandType; 35using OHOS::HDI::Codec::V3_0::CodecStateType; 36using OHOS::HDI::Codec::V3_0::CODEC_STATE_INVALID; 37using OHOS::HDI::Codec::V3_0::CODEC_STATE_LOADED; 38using OHOS::HDI::Codec::V3_0::CODEC_STATE_IDLE; 39using OHOS::HDI::Codec::V3_0::CODEC_STATE_EXECUTING; 40using OHOS::HDI::Codec::V3_0::CODEC_COMMAND_STATE_SET; 41#define FD_SIZE sizeof(int) 42namespace { 43 constexpr int NAME_LENGTH = 32; 44 constexpr int ROLE_MAX_LEN = 256; 45} 46 47namespace OHOS { 48namespace Codec { 49namespace Omx { 50OMX_ERRORTYPE ComponentNode::OnEvent(OMX_HANDLETYPE component, void *appData, OMX_EVENTTYPE event, uint32_t data1, 51 uint32_t data2, void *eventData) 52{ 53 ComponentNode *node = static_cast<ComponentNode *>(appData); 54 (void)component; 55 if (node != nullptr) { 56 node->OnEvent(static_cast<CodecEventType>(event), data1, data2, eventData); 57 } 58 return OMX_ErrorNone; 59} 60 61OMX_ERRORTYPE ComponentNode::OnEmptyBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer) 62{ 63 ComponentNode *node = static_cast<ComponentNode *>(appData); 64 (void)component; 65 if (node != nullptr) { 66 node->OnEmptyBufferDone(buffer); 67 } 68 return OMX_ErrorNone; 69} 70 71OMX_ERRORTYPE ComponentNode::OnFillBufferDone(OMX_HANDLETYPE component, void *appData, OMX_BUFFERHEADERTYPE *buffer) 72{ 73 ComponentNode *node = static_cast<ComponentNode *>(appData); 74 (void)component; 75 if (node != nullptr) { 76 node->OnFillBufferDone(buffer); 77 } 78 return OMX_ErrorNone; 79} 80 81OMX_CALLBACKTYPE ComponentNode::callbacks_ = {&ComponentNode::OnEvent, &ComponentNode::OnEmptyBufferDone, 82 &ComponentNode::OnFillBufferDone}; 83 84ComponentNode::ComponentNode(const sptr<ICodecCallback> &callbacks, int64_t appData, std::shared_ptr<ComponentMgr> &mgr) 85 : comp_(nullptr), 86 omxCallback_(callbacks), 87 appData_(appData), 88 bufferIdCount_(0), 89 mgr_(mgr) 90{ 91} 92 93ComponentNode::~ComponentNode() 94{ 95 std::unique_lock<std::shared_mutex> lk(mapMutex_); 96 omxCallback_ = nullptr; 97 bufferHeaderPortMap_.clear(); 98 codecBufferMap_.clear(); 99 bufferHeaderMap_.clear(); 100 portIndexMap_.clear(); 101 bufferIdCount_ = 0; 102 comp_ = nullptr; 103 mgr_ = nullptr; 104} 105 106int32_t ComponentNode::OpenHandle(const std::string &name) 107{ 108 if (comp_ != nullptr) { 109 return HDF_SUCCESS; 110 } 111 112 OMX_COMPONENTTYPE *comp = nullptr; 113 auto err = mgr_->CreateComponentInstance(name.c_str(), &callbacks_, this, &comp); 114 if (err != OMX_ErrorNone) { 115 CODEC_LOGE("CreateComponentInstance err = %{public}x ", err); 116 return err; 117 } 118 this->comp_ = (OMX_HANDLETYPE)comp; 119 compName_ = name; 120 return HDF_SUCCESS; 121} 122 123int32_t ComponentNode::CloseHandle() 124{ 125 if (comp_ == nullptr) { 126 CODEC_LOGE("comp_ is null"); 127 return HDF_FAILURE; 128 } 129 130 auto err = mgr_->DeleteComponentInstance(reinterpret_cast<OMX_COMPONENTTYPE *>(comp_)); 131 if (err != OMX_ErrorNone) { 132 CODEC_LOGE("DeleteComponentInstance err = %{public}x ", err); 133 return err; 134 } 135 return HDF_SUCCESS; 136} 137 138int32_t ComponentNode::GetComponentVersion(CompVerInfo &verInfo) 139{ 140 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 141 char name[NAME_LENGTH] = {0}; 142 OMX_UUIDTYPE uuid = {0}; 143 OMX_VERSIONTYPE compVersion = {.nVersion = 0}; 144 OMX_VERSIONTYPE sepcVersion = {.nVersion = 0}; 145 int32_t err = OMX_GetComponentVersion(comp_, name, &compVersion, &sepcVersion, &uuid); 146 if (err != OMX_ErrorNone) { 147 CODEC_LOGE("OMX_GetComponentVersion err = %{public}x ", err); 148 return err; 149 } 150 151 verInfo.compName = name; 152 verInfo.compUUID.insert(verInfo.compUUID.end(), uuid, uuid + sizeof(OMX_UUIDTYPE)); 153 err = memcpy_s(&verInfo.compVersion, sizeof(verInfo.compVersion), &compVersion, sizeof(sepcVersion)); 154 if (err != HDF_SUCCESS) { 155 CODEC_LOGE("memset_s return err [%{public}d].", err); 156 return err; 157 } 158 159 err = memcpy_s(&verInfo.specVersion, sizeof(verInfo.specVersion), &sepcVersion, sizeof(sepcVersion)); 160 if (err != HDF_SUCCESS) { 161 CODEC_LOGE("memset_s return err [%{public}d].", err); 162 return err; 163 } 164 return err; 165} 166 167int32_t ComponentNode::SendCommand(CodecCommandType cmd, uint32_t param, int8_t *cmdData) 168{ 169 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 170 OMX_COMMANDTYPE omxCmd = static_cast<OMX_COMMANDTYPE>(cmd); 171 auto err = OMX_SendCommand(comp_, omxCmd, param, cmdData); 172 if (err != OMX_ErrorNone) { 173 CODEC_LOGE("OMX_SendCommand err = %{public}x ", err); 174 } 175 return err; 176} 177 178int32_t ComponentNode::GetParameter(OMX_INDEXTYPE paramIndex, int8_t *param) 179{ 180 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 181 auto err = OMX_GetParameter(comp_, paramIndex, param); 182 if (err != OMX_ErrorNone) { 183 CODEC_LOGE("OMX_GetParameter err = %{public}x ", err); 184 } 185 return err; 186} 187 188int32_t ComponentNode::SetParameter(OMX_INDEXTYPE paramIndex, const int8_t *param) 189{ 190 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 191 auto err = OMX_SetParameter(comp_, paramIndex, const_cast<int8_t *>(param)); 192 if (err != OMX_ErrorNone) { 193 CODEC_LOGE("OMX_SetParameter err = %{public}x ", err); 194 } 195 return err; 196} 197 198int32_t ComponentNode::SetParameterWithBuffer(int32_t index, const std::vector<int8_t>& paramStruct, 199 const OmxCodecBuffer& inBuffer) 200{ 201 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 202 if (index != HDI::Codec::V3_0::Codec_IndexParamOverlayBuffer) { 203 return OMX_ErrorNotImplemented; 204 } 205 if (paramStruct.size() != sizeof(HDI::Codec::V3_0::CodecParamOverlay)) { 206 return OMX_ErrorBadParameter; 207 } 208 if (inBuffer.bufferhandle == nullptr) { 209 CODEC_LOGE("null bufferhandle"); 210 return OMX_ErrorBadParameter; 211 } 212 BufferHandle* handle = inBuffer.bufferhandle->GetBufferHandle(); 213 if (handle == nullptr) { 214 CODEC_LOGE("null bufferhandle"); 215 return OMX_ErrorBadParameter; 216 } 217 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> mapper = HDI::Codec::V3_0::GetMapperService(); 218 if (mapper != nullptr) { 219 mapper->Mmap(inBuffer.bufferhandle); 220 } 221 auto paramSrc = reinterpret_cast<const HDI::Codec::V3_0::CodecParamOverlay *>(paramStruct.data()); 222 CodecParamOverlayBuffer paramDst { 223 .size = sizeof(CodecParamOverlayBuffer), 224 .enable = paramSrc->enable, 225 .dstX = paramSrc->dstX, 226 .dstY = paramSrc->dstY, 227 .dstW = paramSrc->dstW, 228 .dstH = paramSrc->dstH, 229 .bufferHandle = handle, 230 }; 231 auto err = OMX_SetParameter(comp_, static_cast<OMX_INDEXTYPE>(OMX_IndexParamOverlayBuffer), 232 reinterpret_cast<int8_t *>(¶mDst)); 233 if (err != OMX_ErrorNone) { 234 CODEC_LOGE("OMX_SetParameter err = %{public}x ", err); 235 } 236 if (mapper != nullptr) { 237 mapper->Unmap(inBuffer.bufferhandle); 238 } 239 return err; 240} 241 242int32_t ComponentNode::GetConfig(OMX_INDEXTYPE index, int8_t *config) 243{ 244 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 245 auto err = OMX_GetConfig(comp_, index, config); 246 if (err != OMX_ErrorNone) { 247 CODEC_LOGE("OMX_GetConfig err = %{public}x ", err); 248 } 249 return err; 250} 251 252int32_t ComponentNode::SetConfig(OMX_INDEXTYPE index, const int8_t *config) 253{ 254 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 255 auto err = OMX_SetConfig(comp_, index, const_cast<int8_t *>(config)); 256 if (err != OMX_ErrorNone) { 257 CODEC_LOGE("OMX_SetConfig err = %{public}x ", err); 258 } 259 return err; 260} 261 262int32_t ComponentNode::GetExtensionIndex(const char *parameterName, uint32_t &index) 263{ 264 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 265 OMX_INDEXTYPE indexType = OMX_IndexComponentStartUnused; 266 auto err = OMX_GetExtensionIndex(comp_, const_cast<char *>(parameterName), &indexType); 267 if (err != OMX_ErrorNone) { 268 CODEC_LOGE("OMX_GetExtensionIndex ret value[%{public}x]", err); 269 return err; 270 } 271 index = indexType; 272 return err; 273} 274 275int32_t ComponentNode::GetState(CodecStateType &state) 276{ 277 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 278 OMX_STATETYPE status = OMX_StateInvalid; 279 auto err = OMX_GetState(comp_, &status); 280 if (err != OMX_ErrorNone) { 281 CODEC_LOGE("OMX_GetState ret value[%{public}x]", err); 282 return err; 283 } 284 state = static_cast<CodecStateType>(status); 285 return err; 286} 287 288int32_t ComponentNode::ComponentTunnelRequest(uint32_t port, int32_t omxHandleTypeTunneledComp, uint32_t tunneledPort, 289 OHOS::HDI::Codec::V3_0::CodecTunnelSetupType &tunnelSetup) 290{ 291 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 292 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_); 293 unsigned long tunneledComp = static_cast<unsigned long>(omxHandleTypeTunneledComp); 294 if (comType->ComponentTunnelRequest == nullptr) { 295 CODEC_LOGE("The requested function is not implemented."); 296 return OMX_ErrorNotImplemented; 297 } 298 auto err = comType->ComponentTunnelRequest(comp_, port, reinterpret_cast<OMX_HANDLETYPE>(tunneledComp), 299 tunneledPort, reinterpret_cast<OMX_TUNNELSETUPTYPE *>(&tunnelSetup)); 300 if (err != OMX_ErrorNone) { 301 CODEC_LOGE("ComponentTunnelRequest err = %{public}x ", err); 302 } 303 return err; 304} 305 306int32_t ComponentNode::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData) 307{ 308 this->omxCallback_ = callbacks; 309 appData_ = appData; 310 return OMX_ErrorNone; 311} 312 313int32_t ComponentNode::UseEglImage(struct OmxCodecBuffer &buffer, uint32_t portIndex, const int8_t *eglImage) 314{ 315 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 316 OMX_BUFFERHEADERTYPE *pBufferHdrType = nullptr; 317 auto err = OMX_UseEGLImage(comp_, &pBufferHdrType, portIndex, 0, const_cast<int8_t *>(eglImage)); 318 if (err != OMX_ErrorNone) { 319 CODEC_LOGE("OMX_UseEGLImage error[0x%{public}x]", err); 320 return err; 321 } 322 (void)buffer; 323 return OMX_ErrorNotImplemented; 324} 325 326int32_t ComponentNode::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index) 327{ 328 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 329 CHECK_AND_RETURN_RET_LOG(index < ROLE_MAX_LEN, HDF_ERR_INVALID_PARAM, "index is too large"); 330 uint8_t omxRole[ROLE_MAX_LEN] = {0}; 331 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_); 332 if (comType->ComponentRoleEnum == nullptr) { 333 CODEC_LOGE("The requested function is not implemented."); 334 return OMX_ErrorNotImplemented; 335 } 336 int32_t err = comType->ComponentRoleEnum(comp_, omxRole, index); 337 if (err != OMX_ErrorNone) { 338 CODEC_LOGE("ComponentRoleEnum ret err [0x%{public}x] ", err); 339 return err; 340 } 341 role.insert(role.end(), omxRole, omxRole + strlen(reinterpret_cast<const char *>(omxRole))); 342 return OMX_ErrorNone; 343} 344 345int32_t ComponentNode::ComponentDeInit() 346{ 347 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 348 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_); 349 auto err = comType->ComponentDeInit(comp_); 350 if (err != OMX_ErrorNone) { 351 CODEC_LOGE("ComponentDeInit err = %{public}x ", err); 352 } 353 return err; 354} 355 356int32_t ComponentNode::OnEvent(CodecEventType event, uint32_t data1, uint32_t data2, void *eventData) 357{ 358 CODEC_LOGD("eventType: [%{public}d], data1: [%{public}x], data2: [%{public}x]", event, data1, data2); 359 if (omxCallback_ == nullptr) { 360 CODEC_LOGE("omxCallback_ is null"); 361 return OMX_ErrorNone; 362 } 363 (void)eventData; 364 EventInfo info = {.appData = appData_, .data1 = data1, .data2 = data2}; 365 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnEvent"); 366 (void)omxCallback_->EventHandler(event, info); 367 368 return OMX_ErrorNone; 369} 370 371int32_t ComponentNode::OnEmptyBufferDone(OMX_BUFFERHEADERTYPE *buffer) 372{ 373 if ((omxCallback_ == nullptr) || (buffer == nullptr)) { 374 CODEC_LOGE("omxCallback_ or buffer is null"); 375 return OMX_ErrorNone; 376 } 377 sptr<ICodecBuffer> codecBuffer = GetBufferInfoByHeader(buffer); 378 if (codecBuffer == nullptr || codecBuffer->EmptyOmxBufferDone(*buffer) != HDF_SUCCESS) { 379 CODEC_LOGE("codecBuffer is null or EmptyOmxBufferDone error"); 380 return OMX_ErrorNone; 381 } 382 OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); 383 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnEmptyBufferDone"); 384 (void)omxCallback_->EmptyBufferDone(appData_, codecOmxBuffer); 385 return OMX_ErrorNone; 386} 387 388int32_t ComponentNode::OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer) 389{ 390 if ((omxCallback_ == nullptr) || (buffer == nullptr)) { 391 CODEC_LOGE("omxCallback_ or buffer is null"); 392 return OMX_ErrorNone; 393 } 394 395 sptr<ICodecBuffer> codecBuffer = GetBufferInfoByHeader(buffer); 396 if (codecBuffer == nullptr || codecBuffer->FillOmxBufferDone(*buffer) != HDF_SUCCESS) { 397 CODEC_LOGE("codecBuffer is null or EmptyOmxBufferDone error"); 398 return OMX_ErrorNone; 399 } 400 401 struct OmxCodecBuffer &codecOmxBuffer = codecBuffer->GetCodecBuffer(); 402 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnFillBufferDone"); 403 auto appPrivate = static_cast<OMXBufferAppPrivateData *>(buffer->pAppPrivate); 404 if (appPrivate != nullptr && appPrivate->param != nullptr && 405 appPrivate->sizeOfParam < 1024) { // 1024: to protect from taint data 406 codecOmxBuffer.alongParam.resize(appPrivate->sizeOfParam); 407 std::copy(static_cast<uint8_t*>(appPrivate->param), 408 static_cast<uint8_t*>(appPrivate->param) + appPrivate->sizeOfParam, 409 codecOmxBuffer.alongParam.begin()); 410 } 411 (void)omxCallback_->FillBufferDone(appData_, codecOmxBuffer); 412 return OMX_ErrorNone; 413} 414 415int32_t ComponentNode::UseBuffer(uint32_t portIndex, OmxCodecBuffer &buffer) 416{ 417 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 418 419 int32_t err = OMX_ErrorBadParameter; 420 sptr<ICodecBuffer> codecBuffer = sptr<ICodecBuffer>(); 421 if (compName_.find(AUDIO_CODEC_NAME) != std::string::npos) { 422 codecBuffer = sptr<ICodecBuffer>(new ICodecBuffer(buffer)); 423 } else { 424 codecBuffer = ICodecBuffer::CreateCodeBuffer(buffer); 425 } 426 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorInvalidComponent, "codecBuffer is null"); 427 428 OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; 429 err = UseBufferByType(portIndex, buffer, codecBuffer, bufferHdrType); 430 if (err != OMX_ErrorNone) { 431 CODEC_LOGE("type [%{public}d] OMX_AllocateBuffer or OMX_UseBuffer ret = [%{public}x]", buffer.bufferType, err); 432 codecBuffer = nullptr; 433 return err; 434 } 435 436 uint32_t bufferId = GenerateBufferId(); 437 buffer.bufferId = bufferId; 438 codecBuffer->SetBufferId(bufferId); 439 { 440 std::unique_lock<std::shared_mutex> lk(mapMutex_); 441 codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); 442 bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); 443 bufferHeaderPortMap_.emplace(std::make_pair(bufferHdrType, portIndex)); 444 portIndexMap_.emplace(std::make_pair(bufferHdrType, portIndex)); 445 } 446 return err; 447} 448 449int32_t ComponentNode::AllocateBuffer(uint32_t portIndex, OmxCodecBuffer &buffer) 450{ 451 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 452 OMX_BUFFERHEADERTYPE *bufferHdrType = 0; 453 OMXBufferAppPrivateData priv{}; 454 int32_t err = OMX_AllocateBuffer(static_cast<OMX_HANDLETYPE>(comp_), 455 &bufferHdrType, portIndex, &priv, buffer.allocLen); 456 if (err != OMX_ErrorNone) { 457 CODEC_LOGE("OMX_AllocateBuffer error, err = %{public}x", err); 458 return err; 459 } 460 461 buffer.allocLen = bufferHdrType->nAllocLen; 462 sptr<ICodecBuffer> codecBuffer = ICodecBuffer::AllocateCodecBuffer(buffer, *bufferHdrType); 463 if (codecBuffer == nullptr) { 464 CODEC_LOGE("codecBuffer is null"); 465 (void)OMX_FreeBuffer(static_cast<OMX_HANDLETYPE>(comp_), portIndex, bufferHdrType); 466 return OMX_ErrorInvalidComponent; 467 } 468 bufferHdrType->pAppPrivate = nullptr; 469 uint32_t bufferId = GenerateBufferId(); 470 buffer.bufferId = bufferId; 471 codecBuffer->SetBufferId(bufferId); 472 { 473 std::unique_lock<std::shared_mutex> lk(mapMutex_); 474 codecBufferMap_.emplace(std::make_pair(bufferId, codecBuffer)); 475 bufferHeaderMap_.emplace(std::make_pair(bufferHdrType, bufferId)); 476 bufferHeaderPortMap_.emplace(std::make_pair(bufferHdrType, portIndex)); 477 portIndexMap_.emplace(std::make_pair(bufferHdrType, portIndex)); 478 } 479 return OMX_ErrorNone; 480} 481 482int32_t ComponentNode::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer) 483{ 484 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 485 int32_t err = OMX_ErrorBadParameter; 486 sptr<ICodecBuffer> codecBufer = sptr<ICodecBuffer>(); 487 OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; 488 if (!GetBufferById(buffer.bufferId, codecBufer, bufferHdrType)) { 489 CODEC_LOGE(" GetBufferById return false"); 490 return err; 491 } 492 493 err = OMX_FreeBuffer(static_cast<OMX_HANDLETYPE>(comp_), portIndex, bufferHdrType); 494 if (err != OMX_ErrorNone) { 495 CODEC_LOGE("OMX_FreeBuffer err [%{public}x]", err); 496 return err; 497 } 498 499 { 500 std::unique_lock<std::shared_mutex> lk(mapMutex_); 501 auto iterOmxBuffer = bufferHeaderMap_.begin(); 502 while (iterOmxBuffer != bufferHeaderMap_.end()) { 503 if (iterOmxBuffer->first == bufferHdrType) { 504 bufferHeaderMap_.erase(iterOmxBuffer); 505 break; 506 } 507 iterOmxBuffer++; 508 } 509 510 iterOmxBuffer = bufferHeaderPortMap_.begin(); 511 while (iterOmxBuffer != bufferHeaderPortMap_.end()) { 512 if (iterOmxBuffer->first == bufferHdrType) { 513 bufferHeaderPortMap_.erase(iterOmxBuffer); 514 break; 515 } 516 iterOmxBuffer++; 517 } 518 519 auto iter = codecBufferMap_.find(buffer.bufferId); 520 if (iter != codecBufferMap_.end()) { 521 codecBufferMap_.erase(iter); 522 } 523 } 524 525 (void)codecBufer->FreeBuffer(const_cast<OmxCodecBuffer &>(buffer)); 526 527 for (auto it = audioBuffer_.begin(); it != audioBuffer_.end(); it++) { 528 if (it->first == nullptr) { 529 continue; 530 } 531 if (::munmap(it->first, static_cast<size_t>(it->second)) != 0) { 532 CODEC_LOGW("Error munmap"); 533 } 534 } 535 audioBuffer_.clear(); 536 return err; 537} 538 539int32_t ComponentNode::EmptyThisBuffer(OmxCodecBuffer &buffer) 540{ 541 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 542 int32_t err = OMX_ErrorBadParameter; 543 OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; 544 sptr<ICodecBuffer> codecBuffer = sptr<ICodecBuffer>(); 545 if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { 546 CODEC_LOGE(" GetBufferById return false"); 547 return err; 548 } 549 err = codecBuffer->EmptyOmxBuffer(buffer, *bufferHdrType); 550 if (err != HDF_SUCCESS) { 551 CODEC_LOGE("EmptyOmxBuffer err [%{public}d]", err); 552 return err; 553 } 554 bufferHdrType->pAppPrivate = nullptr; 555 OMXBufferAppPrivateData privateData{}; 556 if (buffer.bufferType == CODEC_BUFFER_TYPE_DYNAMIC_HANDLE && (!buffer.alongParam.empty())) { 557 privateData.sizeOfParam = static_cast<uint32_t>(buffer.alongParam.size()); 558 privateData.param = static_cast<void *>(buffer.alongParam.data()); 559 bufferHdrType->pAppPrivate = static_cast<void *>(&privateData); 560 } 561 562 err = OMX_EmptyThisBuffer(static_cast<OMX_HANDLETYPE>(comp_), bufferHdrType); 563 bufferHdrType->pAppPrivate = nullptr; 564 return err; 565} 566 567int32_t ComponentNode::FillThisBuffer(OmxCodecBuffer &buffer) 568{ 569 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null"); 570 int32_t err = OMX_ErrorBadParameter; 571 OMX_BUFFERHEADERTYPE *bufferHdrType = nullptr; 572 sptr<ICodecBuffer> codecBuffer = sptr<ICodecBuffer>(); 573 if (!GetBufferById(buffer.bufferId, codecBuffer, bufferHdrType)) { 574 CODEC_LOGE("GetBufferById return false"); 575 return err; 576 } 577 578 err = codecBuffer->FillOmxBuffer(buffer, *bufferHdrType); 579 if (err != HDF_SUCCESS) { 580 CODEC_LOGE("FillOmxBuffer err [%{public}d]", err); 581 return err; 582 } 583 584 err = OMX_FillThisBuffer(static_cast<OMX_HANDLETYPE>(comp_), bufferHdrType); 585 return err; 586} 587 588int32_t ComponentNode::UseBufferByType(uint32_t portIndex, OmxCodecBuffer &buffer, 589 sptr<ICodecBuffer> codecBuffer, OMX_BUFFERHEADERTYPE *&bufferHdrType) 590{ 591 int32_t err = OMX_ErrorUndefined; 592 switch (buffer.bufferType) { 593 case CODEC_BUFFER_TYPE_AVSHARE_MEM_FD: { 594 if (compName_.find(AUDIO_CODEC_NAME) != std::string::npos) { 595 void *addr = ::mmap(nullptr, static_cast<size_t>(buffer.allocLen), 596 static_cast<int>(PROT_READ | PROT_WRITE), MAP_SHARED, buffer.fd, 0); 597 CHECK_AND_RETURN_RET_LOG(addr != nullptr, OMX_ErrorBadParameter, "addr is null"); 598 err = OMX_UseBuffer(static_cast<OMX_HANDLETYPE>(comp_), &bufferHdrType, portIndex, 0, buffer.allocLen, 599 reinterpret_cast<uint8_t *>(addr)); 600 audioBuffer_.push_back({addr, buffer.allocLen}); 601 break; 602 } 603 err = OMX_AllocateBuffer(static_cast<OMX_HANDLETYPE>(comp_), &bufferHdrType, portIndex, 0, 604 buffer.allocLen); 605 break; 606 } 607 case CODEC_BUFFER_TYPE_HANDLE: 608 case CODEC_BUFFER_TYPE_DYNAMIC_HANDLE: 609 err = OMX_UseBuffer(static_cast<OMX_HANDLETYPE>(comp_), &bufferHdrType, portIndex, 0, buffer.allocLen, 610 codecBuffer->GetBuffer()); 611 break; 612 case CODEC_BUFFER_TYPE_DMA_MEM_FD: { 613 err = OMX_UseBuffer(static_cast<OMX_HANDLETYPE>(comp_), &bufferHdrType, portIndex, 0, 0, 614 reinterpret_cast<uint8_t *>(&buffer.fd)); 615 break; 616 } 617 default: 618 break; 619 } 620 return err; 621} 622 623uint32_t ComponentNode::GenerateBufferId() 624{ 625 std::unique_lock<std::shared_mutex> lk(mapMutex_); 626 uint32_t bufferId = 0; 627 do { 628 if (++bufferIdCount_ == 0) { 629 ++bufferIdCount_; 630 } 631 bufferId = bufferIdCount_; 632 } while (codecBufferMap_.find(bufferId) != codecBufferMap_.end()); 633 return bufferId; 634} 635 636sptr<ICodecBuffer> ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer) 637{ 638 if (buffer == nullptr) { 639 CODEC_LOGE("Buffer is null"); 640 return sptr<ICodecBuffer>(); 641 } 642 std::shared_lock<std::shared_mutex> lk(mapMutex_); 643 auto iterHead = bufferHeaderMap_.find(buffer); 644 if (iterHead == bufferHeaderMap_.end()) { 645 CODEC_LOGE("Can not find bufferID"); 646 return sptr<ICodecBuffer>(); 647 } 648 649 uint32_t bufferId = iterHead->second; 650 auto iter = codecBufferMap_.find(bufferId); 651 if (iter == codecBufferMap_.end()) { 652 CODEC_LOGE("Can not find bufferInfo by bufferId = %{public}d", bufferId); 653 return sptr<ICodecBuffer>(); 654 } 655 return iter->second; 656} 657 658bool ComponentNode::GetBufferById(uint32_t bufferId, sptr<ICodecBuffer> &codecBuffer, 659 OMX_BUFFERHEADERTYPE *&bufferHdrType) 660{ 661 std::shared_lock<std::shared_mutex> lk(mapMutex_); 662 auto iter = codecBufferMap_.find(bufferId); 663 if ((iter == codecBufferMap_.end()) || (iter->second == nullptr)) { 664 CODEC_LOGE("Can not find bufferIndo by bufferID [%{public}d]", bufferId); 665 return false; 666 } 667 668 auto iterHead = bufferHeaderMap_.begin(); 669 for (; iterHead != bufferHeaderMap_.end(); iterHead++) { 670 if (iterHead->second == bufferId) { 671 break; 672 } 673 } 674 if ((iterHead == bufferHeaderMap_.end()) || (iterHead->first == nullptr)) { 675 CODEC_LOGE("Can not find bufferHeaderType by bufferID [%{public}d] or iterHead->first is null", bufferId); 676 return false; 677 } 678 bufferHdrType = iterHead->first; 679 codecBuffer = iter->second; 680 return true; 681} 682 683void ComponentNode::WaitStateChange(CodecStateType objState, CodecStateType &status) 684{ 685 int32_t ret; 686 uint32_t count = 0; 687 while (status != objState && count < maxStateWaitCount) { 688 usleep(maxStateWaitTime); 689 ret = GetState(status); 690 if (ret != HDF_SUCCESS) { 691 HDF_LOGE("%{public}s: GetState error [%{public}x]", __func__, ret); 692 return; 693 } 694 count++; 695 } 696} 697 698void ComponentNode::GetBuffCount(uint32_t &inputBuffCount, uint32_t &outputBuffCount) 699{ 700 std::unique_lock<std::shared_mutex> lk(mapMutex_); 701 auto iter = portIndexMap_.begin(); 702 while (iter != portIndexMap_.end()) { 703 if (iter->second == 0) { 704 inputBuffCount++; 705 } else { 706 outputBuffCount++; 707 } 708 iter++; 709 } 710} 711 712void ComponentNode::ReleaseOMXResource() 713{ 714 std::shared_lock<std::shared_mutex> lk(mapMutex_); 715 if (codecBufferMap_.size() == 0) { 716 return; 717 } 718 CodecStateType status = CODEC_STATE_INVALID; 719 int32_t ret = GetState(status); 720 if (ret != HDF_SUCCESS) { 721 HDF_LOGE("ReleaseOMXResource GetState error [%{public}x]", ret); 722 return; 723 } 724 if (status == CODEC_STATE_EXECUTING) { 725 SendCommand(CODEC_COMMAND_STATE_SET, CODEC_STATE_IDLE, NULL); 726 WaitStateChange(CODEC_STATE_IDLE, status); 727 } 728 if (status == CODEC_STATE_IDLE) { 729 SendCommand(CODEC_COMMAND_STATE_SET, CODEC_STATE_LOADED, NULL); 730 ret = ReleaseAllBuffer(); 731 if (ret != HDF_SUCCESS) { 732 HDF_LOGE("ReleaseAllBuffer err [%{public}x]", ret); 733 return; 734 } 735 WaitStateChange(CODEC_STATE_LOADED, status); 736 } 737 HDF_LOGI("%{public}s: Release OMX Resource success!", __func__); 738} 739 740int32_t ComponentNode::ReleaseAllBuffer() 741{ 742 auto iter = bufferHeaderMap_.begin(); 743 for (; iter != bufferHeaderMap_.end(); iter++) { 744 OMX_BUFFERHEADERTYPE *bufferHdrType = iter->first; 745 uint32_t protIndex = bufferHeaderPortMap_.find(bufferHdrType)->second; 746 auto ret = OMX_FreeBuffer((OMX_HANDLETYPE)comp_, protIndex, bufferHdrType); 747 if (ret != OMX_ErrorNone) { 748 HDF_LOGE("OMX_FreeBuffer err [%{public}x]", ret); 749 return ret; 750 } 751 } 752 HDF_LOGI("Release OMXBuffer and CodecBuffer success!"); 753 return HDF_SUCCESS; 754} 755} // namespace Omx 756} // namespace Codec 757} // namespace OHOS 758