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