• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *>(&paramDst));
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