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