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