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 <hdf_remote_service.h>
22 #include <hitrace_meter.h>
23 #include "codec_log_wrapper.h"
24 #include "component_mgr.h"
25 #include "icodec_buffer.h"
26 #include "sys/mman.h"
27 #include "v4_0/codec_ext_types.h"
28 #include "codec_component_service.h"
29
30 #define AUDIO_CODEC_NAME "OMX.audio"
31
32 using OHOS::HDI::Codec::V4_0::EventInfo;
33 using OHOS::HDI::Codec::V4_0::CodecEventType;
34 using OHOS::HDI::Codec::V4_0::CodecStateType;
35 using OHOS::HDI::Codec::V4_0::CodecCommandType;
36 using OHOS::HDI::Codec::V4_0::CODEC_STATE_INVALID;
37 using OHOS::HDI::Codec::V4_0::CODEC_STATE_LOADED;
38 using OHOS::HDI::Codec::V4_0::CODEC_STATE_IDLE;
39 using OHOS::HDI::Codec::V4_0::CODEC_STATE_EXECUTING;
40 using OHOS::HDI::Codec::V4_0::CODEC_COMMAND_STATE_SET;
41 #define FD_SIZE sizeof(int)
42 namespace {
43 constexpr int NAME_LENGTH = 32;
44 constexpr int ROLE_MAX_LEN = 256;
45 }
46
47 namespace OHOS {
48 namespace Codec {
49 namespace Omx {
OnEvent(OMX_HANDLETYPE component,void * appData,OMX_EVENTTYPE event,uint32_t data1,uint32_t data2,void * eventData)50 OMX_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
OnEmptyBufferDone(OMX_HANDLETYPE component,void * appData,OMX_BUFFERHEADERTYPE * buffer)61 OMX_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
OnFillBufferDone(OMX_HANDLETYPE component,void * appData,OMX_BUFFERHEADERTYPE * buffer)71 OMX_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
81 OMX_CALLBACKTYPE ComponentNode::callbacks_ = {&ComponentNode::OnEvent, &ComponentNode::OnEmptyBufferDone,
82 &ComponentNode::OnFillBufferDone};
83
ComponentNode(const sptr<ICodecCallback> & callbacks,int64_t appData,std::shared_ptr<ComponentMgr> & mgr)84 ComponentNode::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 isIPCMode_ = (HdfRemoteGetCallingPid() == getpid() ? false : true);
92 }
93
~ComponentNode()94 ComponentNode::~ComponentNode()
95 {
96 std::unique_lock<std::shared_mutex> lk(poolMutex_);
97 omxCallback_ = nullptr;
98 bufferPool_.clear();
99 bufferIdCount_ = 0;
100 comp_ = nullptr;
101 mgr_ = nullptr;
102 }
103
OpenHandle(const std::string & name)104 int32_t ComponentNode::OpenHandle(const std::string &name)
105 {
106 if (comp_ != nullptr) {
107 return HDF_SUCCESS;
108 }
109
110 OMX_COMPONENTTYPE *comp = nullptr;
111 auto err = mgr_->CreateComponentInstance(name.c_str(), &callbacks_, this, &comp);
112 if (err != OMX_ErrorNone) {
113 CODEC_LOGE("CreateComponentInstance err = %{public}x ", err);
114 return err;
115 }
116 this->comp_ = (OMX_HANDLETYPE)comp;
117 compName_ = name;
118 return HDF_SUCCESS;
119 }
120
CloseHandle()121 int32_t ComponentNode::CloseHandle()
122 {
123 if (comp_ == nullptr) {
124 CODEC_LOGE("comp_ is null");
125 return HDF_FAILURE;
126 }
127
128 auto err = mgr_->DeleteComponentInstance(reinterpret_cast<OMX_COMPONENTTYPE *>(comp_));
129 if (err != OMX_ErrorNone) {
130 CODEC_LOGE("DeleteComponentInstance err = %{public}x ", err);
131 return err;
132 }
133 return HDF_SUCCESS;
134 }
135
GetComponentVersion(CompVerInfo & verInfo)136 int32_t ComponentNode::GetComponentVersion(CompVerInfo &verInfo)
137 {
138 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
139 char name[NAME_LENGTH] = {0};
140 OMX_UUIDTYPE uuid = {0};
141 OMX_VERSIONTYPE compVersion = {.nVersion = 0};
142 OMX_VERSIONTYPE sepcVersion = {.nVersion = 0};
143 int32_t err = OMX_GetComponentVersion(comp_, name, &compVersion, &sepcVersion, &uuid);
144 if (err != OMX_ErrorNone) {
145 CODEC_LOGE("OMX_GetComponentVersion err = %{public}x ", err);
146 return err;
147 }
148
149 verInfo.compName = name;
150 verInfo.compUUID.insert(verInfo.compUUID.end(), uuid, uuid + sizeof(OMX_UUIDTYPE));
151 err = memcpy_s(&verInfo.compVersion, sizeof(verInfo.compVersion), &compVersion, sizeof(sepcVersion));
152 if (err != HDF_SUCCESS) {
153 CODEC_LOGE("memset_s return err [%{public}d].", err);
154 return err;
155 }
156
157 err = memcpy_s(&verInfo.specVersion, sizeof(verInfo.specVersion), &sepcVersion, sizeof(sepcVersion));
158 if (err != HDF_SUCCESS) {
159 CODEC_LOGE("memset_s return err [%{public}d].", err);
160 return err;
161 }
162 return err;
163 }
164
SendCommand(CodecCommandType cmd,uint32_t param,int8_t * cmdData)165 int32_t ComponentNode::SendCommand(CodecCommandType cmd, uint32_t param, int8_t *cmdData)
166 {
167 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
168 OMX_COMMANDTYPE omxCmd = static_cast<OMX_COMMANDTYPE>(cmd);
169 auto err = OMX_SendCommand(comp_, omxCmd, param, cmdData);
170 if (err != OMX_ErrorNone) {
171 CODEC_LOGE("OMX_SendCommand err = %{public}x ", err);
172 }
173 return err;
174 }
175
GetParameter(OMX_INDEXTYPE paramIndex,int8_t * param)176 int32_t ComponentNode::GetParameter(OMX_INDEXTYPE paramIndex, int8_t *param)
177 {
178 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
179 auto err = OMX_GetParameter(comp_, paramIndex, param);
180 if (err != OMX_ErrorNone) {
181 CODEC_LOGE("OMX_GetParameter err = %{public}x ", err);
182 }
183 return err;
184 }
185
SetParameter(OMX_INDEXTYPE paramIndex,const int8_t * param)186 int32_t ComponentNode::SetParameter(OMX_INDEXTYPE paramIndex, const int8_t *param)
187 {
188 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
189 auto err = OMX_SetParameter(comp_, paramIndex, const_cast<int8_t *>(param));
190 if (err != OMX_ErrorNone) {
191 CODEC_LOGE("OMX_SetParameter err = %{public}x ", err);
192 }
193 return err;
194 }
195
SetParameterWithBuffer(int32_t index,const std::vector<int8_t> & paramStruct,const OmxCodecBuffer & inBuffer)196 int32_t ComponentNode::SetParameterWithBuffer(int32_t index, const std::vector<int8_t>& paramStruct,
197 const OmxCodecBuffer& inBuffer)
198 {
199 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
200 if (index != HDI::Codec::V4_0::Codec_IndexParamOverlayBuffer) {
201 return OMX_ErrorNotImplemented;
202 }
203 if (paramStruct.size() != sizeof(HDI::Codec::V4_0::CodecParamOverlay)) {
204 return OMX_ErrorBadParameter;
205 }
206 if (inBuffer.bufferhandle == nullptr) {
207 CODEC_LOGE("null bufferhandle");
208 return OMX_ErrorBadParameter;
209 }
210 BufferHandle* handle = inBuffer.bufferhandle->GetBufferHandle();
211 if (handle == nullptr) {
212 CODEC_LOGE("null bufferhandle");
213 return OMX_ErrorBadParameter;
214 }
215 int ret = Mmap(inBuffer.bufferhandle);
216 if (ret != 0) {
217 CODEC_LOGE("mmap failed");
218 return ret;
219 }
220 auto paramSrc = reinterpret_cast<const HDI::Codec::V4_0::CodecParamOverlay *>(paramStruct.data());
221 CodecParamOverlayBuffer paramDst {
222 .size = sizeof(CodecParamOverlayBuffer),
223 .enable = paramSrc->enable,
224 .dstX = paramSrc->dstX,
225 .dstY = paramSrc->dstY,
226 .dstW = paramSrc->dstW,
227 .dstH = paramSrc->dstH,
228 .bufferHandle = handle,
229 };
230 auto err = OMX_SetParameter(comp_, static_cast<OMX_INDEXTYPE>(OMX_IndexParamOverlayBuffer),
231 reinterpret_cast<int8_t *>(¶mDst));
232 if (err != OMX_ErrorNone) {
233 CODEC_LOGE("OMX_SetParameter err = %{public}x ", err);
234 }
235 (void)Unmap(inBuffer.bufferhandle);
236 return err;
237 }
238
GetConfig(OMX_INDEXTYPE index,int8_t * config)239 int32_t ComponentNode::GetConfig(OMX_INDEXTYPE index, int8_t *config)
240 {
241 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
242 auto err = OMX_GetConfig(comp_, index, config);
243 if (err != OMX_ErrorNone) {
244 CODEC_LOGE("OMX_GetConfig err = %{public}x ", err);
245 }
246 return err;
247 }
248
SetConfig(OMX_INDEXTYPE index,const int8_t * config)249 int32_t ComponentNode::SetConfig(OMX_INDEXTYPE index, const int8_t *config)
250 {
251 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
252 auto err = OMX_SetConfig(comp_, index, const_cast<int8_t *>(config));
253 if (err != OMX_ErrorNone) {
254 CODEC_LOGE("OMX_SetConfig err = %{public}x ", err);
255 }
256 return err;
257 }
258
GetExtensionIndex(const char * parameterName,uint32_t & index)259 int32_t ComponentNode::GetExtensionIndex(const char *parameterName, uint32_t &index)
260 {
261 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
262 OMX_INDEXTYPE indexType = OMX_IndexComponentStartUnused;
263 auto err = OMX_GetExtensionIndex(comp_, const_cast<char *>(parameterName), &indexType);
264 if (err != OMX_ErrorNone) {
265 CODEC_LOGE("OMX_GetExtensionIndex ret value[%{public}x]", err);
266 return err;
267 }
268 index = indexType;
269 return err;
270 }
271
GetState(CodecStateType & state)272 int32_t ComponentNode::GetState(CodecStateType &state)
273 {
274 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
275 OMX_STATETYPE status = OMX_StateInvalid;
276 auto err = OMX_GetState(comp_, &status);
277 if (err != OMX_ErrorNone) {
278 CODEC_LOGE("OMX_GetState ret value[%{public}x]", err);
279 return err;
280 }
281 state = static_cast<CodecStateType>(status);
282 return err;
283 }
284
ComponentTunnelRequest(uint32_t port,int32_t omxHandleTypeTunneledComp,uint32_t tunneledPort,OHOS::HDI::Codec::V4_0::CodecTunnelSetupType & tunnelSetup)285 int32_t ComponentNode::ComponentTunnelRequest(uint32_t port, int32_t omxHandleTypeTunneledComp, uint32_t tunneledPort,
286 OHOS::HDI::Codec::V4_0::CodecTunnelSetupType &tunnelSetup)
287 {
288 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
289 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_);
290 unsigned long tunneledComp = static_cast<unsigned long>(omxHandleTypeTunneledComp);
291 if (comType->ComponentTunnelRequest == nullptr) {
292 CODEC_LOGE("The requested function is not implemented.");
293 return OMX_ErrorNotImplemented;
294 }
295 auto err = comType->ComponentTunnelRequest(comp_, port, reinterpret_cast<OMX_HANDLETYPE>(tunneledComp),
296 tunneledPort, reinterpret_cast<OMX_TUNNELSETUPTYPE *>(&tunnelSetup));
297 if (err != OMX_ErrorNone) {
298 CODEC_LOGE("ComponentTunnelRequest err = %{public}x ", err);
299 }
300 return err;
301 }
302
SetCallbacks(const sptr<ICodecCallback> & callbacks,int64_t appData)303 int32_t ComponentNode::SetCallbacks(const sptr<ICodecCallback> &callbacks, int64_t appData)
304 {
305 this->omxCallback_ = callbacks;
306 appData_ = appData;
307 return OMX_ErrorNone;
308 }
309
UseEglImage(struct OmxCodecBuffer & buffer,uint32_t portIndex,const int8_t * eglImage)310 int32_t ComponentNode::UseEglImage(struct OmxCodecBuffer &buffer, uint32_t portIndex, const int8_t *eglImage)
311 {
312 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
313 OMX_BUFFERHEADERTYPE *pBufferHdrType = nullptr;
314 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_);
315 if (comType->UseEGLImage == nullptr) {
316 CODEC_LOGE("The requested function is not implemented.");
317 return OMX_ErrorNotImplemented;
318 }
319 auto err = OMX_UseEGLImage(comp_, &pBufferHdrType, portIndex, 0, const_cast<int8_t *>(eglImage));
320 if (err != OMX_ErrorNone) {
321 CODEC_LOGE("OMX_UseEGLImage error[0x%{public}x]", err);
322 return err;
323 }
324 (void)buffer;
325 return OMX_ErrorNotImplemented;
326 }
327
ComponentRoleEnum(std::vector<uint8_t> & role,uint32_t index)328 int32_t ComponentNode::ComponentRoleEnum(std::vector<uint8_t> &role, uint32_t index)
329 {
330 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
331 CHECK_AND_RETURN_RET_LOG(index < ROLE_MAX_LEN, HDF_ERR_INVALID_PARAM, "index is too large");
332 uint8_t omxRole[ROLE_MAX_LEN] = {0};
333 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_);
334 if (comType->ComponentRoleEnum == nullptr) {
335 CODEC_LOGE("The requested function is not implemented.");
336 return OMX_ErrorNotImplemented;
337 }
338 int32_t err = comType->ComponentRoleEnum(comp_, omxRole, index);
339 if (err != OMX_ErrorNone) {
340 CODEC_LOGE("ComponentRoleEnum ret err [0x%{public}x] ", err);
341 return err;
342 }
343 role.insert(role.end(), omxRole, omxRole + strlen(reinterpret_cast<const char *>(omxRole)));
344 return OMX_ErrorNone;
345 }
346
ComponentDeInit()347 int32_t ComponentNode::ComponentDeInit()
348 {
349 CHECK_AND_RETURN_RET_LOG(comp_ != nullptr, OMX_ErrorInvalidComponent, "comp_ is null");
350 OMX_COMPONENTTYPE *comType = static_cast<OMX_COMPONENTTYPE *>(comp_);
351 auto err = comType->ComponentDeInit(comp_);
352 if (err != OMX_ErrorNone) {
353 CODEC_LOGE("ComponentDeInit err = %{public}x ", err);
354 }
355 return err;
356 }
357
OnEvent(CodecEventType event,uint32_t data1,uint32_t data2,void * eventData)358 int32_t ComponentNode::OnEvent(CodecEventType event, uint32_t data1, uint32_t data2, void *eventData)
359 {
360 CODEC_LOGD("eventType: [%{public}d], data1: [%{public}x], data2: [%{public}x]", event, data1, data2);
361 if (omxCallback_ == nullptr) {
362 CODEC_LOGE("omxCallback_ is null");
363 return OMX_ErrorNone;
364 }
365 (void)eventData;
366 EventInfo info = {.appData = appData_, .data1 = data1, .data2 = data2};
367 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnEvent");
368 (void)omxCallback_->EventHandler(event, info);
369
370 return OMX_ErrorNone;
371 }
372
OnEmptyBufferDone(OMX_BUFFERHEADERTYPE * buffer)373 int32_t ComponentNode::OnEmptyBufferDone(OMX_BUFFERHEADERTYPE *buffer)
374 {
375 if ((omxCallback_ == nullptr) || (buffer == nullptr)) {
376 CODEC_LOGE("omxCallback_ or buffer is null");
377 return OMX_ErrorBadParameter;
378 }
379 sptr<ICodecBuffer> codecBuffer = GetBufferInfoByHeader(buffer);
380 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "buffer not exist");
381
382 OmxCodecBuffer codecOmxBuffer;
383 int32_t ret = codecBuffer->EmptyBufferDone(*buffer, codecOmxBuffer);
384 CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "EmptyBufferDone failed");
385
386 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnEmptyBufferDone");
387 (void)omxCallback_->EmptyBufferDone(appData_, OHOS::Codec::Omx::Convert(codecOmxBuffer, isIPCMode_));
388 return OMX_ErrorNone;
389 }
390
OnFillBufferDone(OMX_BUFFERHEADERTYPE * buffer)391 int32_t ComponentNode::OnFillBufferDone(OMX_BUFFERHEADERTYPE *buffer)
392 {
393 if ((omxCallback_ == nullptr) || (buffer == nullptr)) {
394 CODEC_LOGE("omxCallback_ or buffer is null");
395 return OMX_ErrorBadParameter;
396 }
397
398 sptr<ICodecBuffer> codecBuffer = GetBufferInfoByHeader(buffer);
399 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "buffer not exist");
400
401 OmxCodecBuffer codecOmxBuffer;
402 int32_t ret = codecBuffer->FillBufferDone(*buffer, codecOmxBuffer);
403 CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "FillBufferDone failed");
404
405 HITRACE_METER_NAME(HITRACE_TAG_HDF, "HDFCodecOnFillBufferDone");
406 (void)omxCallback_->FillBufferDone(appData_, OHOS::Codec::Omx::Convert(codecOmxBuffer, isIPCMode_));
407 return OMX_ErrorNone;
408 }
409
UseBuffer(uint32_t portIndex,OmxCodecBuffer & buffer)410 int32_t ComponentNode::UseBuffer(uint32_t portIndex, OmxCodecBuffer &buffer)
411 {
412 uint32_t bufferId = GenerateBufferId();
413 buffer.bufferId = bufferId;
414 bool doCopy = compName_.find(AUDIO_CODEC_NAME) == std::string::npos;
415 OMX_BUFFERHEADERTYPE *omxHeader = nullptr;
416 sptr<ICodecBuffer> codecBuffer = ICodecBuffer::UseBuffer(comp_, portIndex, buffer, omxHeader, doCopy);
417 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "codecBuffer is null");
418 {
419 std::unique_lock<std::shared_mutex> lk(poolMutex_);
420 bufferPool_.push_back(BufferInfo{bufferId, portIndex, codecBuffer, omxHeader});
421 }
422 return OMX_ErrorNone;
423 }
424
AllocateBuffer(uint32_t portIndex,OmxCodecBuffer & buffer)425 int32_t ComponentNode::AllocateBuffer(uint32_t portIndex, OmxCodecBuffer &buffer)
426 {
427 uint32_t bufferId = GenerateBufferId();
428 buffer.bufferId = bufferId;
429 OMX_BUFFERHEADERTYPE *omxHeader = nullptr;
430 sptr<ICodecBuffer> codecBuffer = ICodecBuffer::AllocateBuffer(comp_, portIndex, buffer, omxHeader);
431 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "codecBuffer is null");
432 {
433 std::unique_lock<std::shared_mutex> lk(poolMutex_);
434 bufferPool_.push_back(BufferInfo{bufferId, portIndex, codecBuffer, omxHeader});
435 }
436 return OMX_ErrorNone;
437 }
438
FreeBuffer(uint32_t portIndex,const OmxCodecBuffer & buffer)439 int32_t ComponentNode::FreeBuffer(uint32_t portIndex, const OmxCodecBuffer &buffer)
440 {
441 sptr<ICodecBuffer> codecBuffer = nullptr;
442 {
443 std::unique_lock<std::shared_mutex> poolLock(poolMutex_);
444 uint32_t bufferId = buffer.bufferId;
445 auto iter = std::find_if(bufferPool_.begin(), bufferPool_.end(), [bufferId, portIndex](const BufferInfo& info) {
446 return info.bufferId == bufferId && info.portIndex == portIndex;
447 });
448 if (iter == bufferPool_.end()) {
449 CODEC_LOGE("Can not find buffer, port=%{public}u, id=%{public}u", portIndex, bufferId);
450 return OMX_ErrorBadParameter;
451 }
452 codecBuffer = iter->icodecBuf;
453 bufferPool_.erase(iter);
454 }
455 if (codecBuffer != nullptr) {
456 codecBuffer->FreeBuffer();
457 }
458 return 0;
459 }
460
EmptyThisBuffer(OmxCodecBuffer & buffer)461 int32_t ComponentNode::EmptyThisBuffer(OmxCodecBuffer &buffer)
462 {
463 sptr<ICodecBuffer> codecBuffer = GetBufferById(buffer.bufferId);
464 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "buffer not exist");
465 return codecBuffer->EmptyThisBuffer(buffer);
466 }
467
FillThisBuffer(OmxCodecBuffer & buffer)468 int32_t ComponentNode::FillThisBuffer(OmxCodecBuffer &buffer)
469 {
470 sptr<ICodecBuffer> codecBuffer = GetBufferById(buffer.bufferId);
471 CHECK_AND_RETURN_RET_LOG(codecBuffer != nullptr, OMX_ErrorBadParameter, "buffer not exist");
472 return codecBuffer->FillThisBuffer(buffer);
473 }
474
GenerateBufferId()475 uint32_t ComponentNode::GenerateBufferId()
476 {
477 std::shared_lock<std::shared_mutex> lk(poolMutex_);
478 uint32_t bufferId = 0;
479 do {
480 if (++bufferIdCount_ == 0) {
481 ++bufferIdCount_;
482 }
483 bufferId = bufferIdCount_;
484 } while (std::any_of(bufferPool_.begin(), bufferPool_.end(), [bufferId](const BufferInfo& info) {
485 return info.bufferId == bufferId;
486 }));
487 CODEC_LOGD("bufferId=%{public}u", bufferId);
488 return bufferId;
489 }
490
GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE * buffer)491 sptr<ICodecBuffer> ComponentNode::GetBufferInfoByHeader(OMX_BUFFERHEADERTYPE *buffer)
492 {
493 std::shared_lock<std::shared_mutex> lk(poolMutex_);
494 auto iter = std::find_if(bufferPool_.begin(), bufferPool_.end(), [buffer](const BufferInfo& info) {
495 return info.omxHeader == buffer;
496 });
497 if (iter == bufferPool_.end()) {
498 CODEC_LOGE("Can not find buffer");
499 return nullptr;
500 }
501 return iter->icodecBuf;
502 }
503
GetBufferById(uint32_t bufferId)504 sptr<ICodecBuffer> ComponentNode::GetBufferById(uint32_t bufferId)
505 {
506 std::shared_lock<std::shared_mutex> lk(poolMutex_);
507 auto iter = std::find_if(bufferPool_.begin(), bufferPool_.end(), [bufferId](const BufferInfo& info) {
508 return info.bufferId == bufferId;
509 });
510 if (iter == bufferPool_.end()) {
511 CODEC_LOGE("Can not find bufferID [%{public}d]", bufferId);
512 return nullptr;
513 }
514 return iter->icodecBuf;
515 }
516
WaitStateChange(CodecStateType objState,CodecStateType & status)517 void ComponentNode::WaitStateChange(CodecStateType objState, CodecStateType &status)
518 {
519 int32_t ret;
520 uint32_t count = 0;
521 while (status != objState && count < maxStateWaitCount) {
522 usleep(maxStateWaitTime);
523 ret = GetState(status);
524 if (ret != HDF_SUCCESS) {
525 HDF_LOGE("%{public}s: GetState error [%{public}x]", __func__, ret);
526 return;
527 }
528 count++;
529 }
530 }
531
GetBuffCount(uint32_t & inputBuffCount,uint32_t & outputBuffCount)532 void ComponentNode::GetBuffCount(uint32_t &inputBuffCount, uint32_t &outputBuffCount)
533 {
534 std::shared_lock<std::shared_mutex> lk(poolMutex_);
535 for (const BufferInfo& info : bufferPool_) {
536 if (info.portIndex == 0) {
537 inputBuffCount++;
538 } else {
539 outputBuffCount++;
540 }
541 }
542 }
543
ReleaseOMXResource()544 void ComponentNode::ReleaseOMXResource()
545 {
546 std::unique_lock<std::shared_mutex> lk(poolMutex_);
547 if (bufferPool_.empty()) {
548 return;
549 }
550 CodecStateType status = CODEC_STATE_INVALID;
551 int32_t ret = GetState(status);
552 if (ret != HDF_SUCCESS) {
553 HDF_LOGE("ReleaseOMXResource GetState error [%{public}x]", ret);
554 return;
555 }
556 if (status == CODEC_STATE_EXECUTING) {
557 SendCommand(CODEC_COMMAND_STATE_SET, CODEC_STATE_IDLE, NULL);
558 WaitStateChange(CODEC_STATE_IDLE, status);
559 }
560 if (status == CODEC_STATE_IDLE) {
561 SendCommand(CODEC_COMMAND_STATE_SET, CODEC_STATE_LOADED, NULL);
562 bufferPool_.clear();
563 WaitStateChange(CODEC_STATE_LOADED, status);
564 }
565 bufferPool_.clear();
566 HDF_LOGI("%{public}s: Release OMX Resource success!", __func__);
567 }
568
569 } // namespace Omx
570 } // namespace Codec
571 } // namespace OHOS
572