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