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