• 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 <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