• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device 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 "hdi_codec.h"
17 #include <unordered_map>
18 #include <hdf_base.h>
19 #include "codec_callback_type_stub.h"
20 #include "media_log.h"
21 #include "media_errors.h"
22 #include "hdi_init.h"
23 #include "hdi_codec_util.h"
24 #include "securec.h"
25 #include "media_dfx.h"
26 #include "scope_guard.h"
27 
28 using namespace std;
29 namespace {
30     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "HdiCodec"};
31     static const std::unordered_map<OMX_EVENTTYPE, std::string> OMX_EVENT_TO_STRING = {
32         {OMX_EventCmdComplete, "OMX_EventCmdComplete"},
33         {OMX_EventError, "OMX_EventError"},
34         {OMX_EventMark, "OMX_EventMark"},
35         {OMX_EventPortSettingsChanged, "OMX_EventPortSettingsChanged"},
36         {OMX_EventBufferFlag, "OMX_EventBufferFlag"},
37         {OMX_EventResourcesAcquired, "OMX_EventResourcesAcquired"},
38         {OMX_EventComponentResumed, "OMX_EventComponentResumed"},
39         {OMX_EventPortFormatDetected, "OMX_EventPortFormatDetected"},
40         {OMX_EventDynamicResourcesAvailable, "OMX_EventDynamicResourcesAvailable"},
41         {OMX_EventVendorStartUnused, "OMX_EventVendorStartUnused"},
42         {OMX_EventMax, "OMX_EventMax"},
43     };
44 }
45 namespace OHOS {
46 namespace Media {
HdiCodec(const string & component)47 HdiCodec::HdiCodec(const string& component)
48     : componentName_(component), taskQue_("HDICallback")
49 {
50     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
51 }
52 
~HdiCodec()53 HdiCodec::~HdiCodec()
54 {
55     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
56     DeinitInner();
57 }
58 
InitVersion()59 void HdiCodec::InitVersion()
60 {
61     (void)memset_s(&verInfo_, sizeof(verInfo_), 0, sizeof(verInfo_));
62     int32_t ret = HDF_SUCCESS;
63     LISTENER(ret = handle_->GetComponentVersion(handle_, &verInfo_),
64         "HdiCodec::GetComponentVersion", PlayerXCollie::timerTimeout)
65     CHECK_AND_RETURN_LOG(ret == HDF_SUCCESS, "get version failed");
66 }
67 
Init()68 int32_t HdiCodec::Init()
69 {
70     MEDIA_LOGD("Init");
71     (void)taskQue_.Start();
72     callback_ = CodecCallbackTypeStubGetInstance();
73     CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, GST_CODEC_ERROR, "GetCallBack failed");
74     callback_->EventHandler = &HdiCodec::Event;
75     callback_->EmptyBufferDone = &HdiCodec::EmptyBufferDone;
76     callback_->FillBufferDone = &HdiCodec::FillBufferDone;
77     appData_ = new AppData();
78     appData_->instance = weak_from_this();
79     int32_t ret;
80     {
81         MediaTrace trace("HdiCodec::Init");
82         std::weak_ptr<IGstCodec> codec = weak_from_this();
83         HdiInfo info = {componentName_, appData_, callback_, codec};
84         ret = HdiInit::GetInstance().GetHandle(&handle_, id_, info);
85         CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "GetHandle failed");
86         CHECK_AND_RETURN_RET_LOG(handle_ != nullptr, GST_CODEC_ERROR, "Handle is nullptr");
87         InitVersion();
88         InitParam(portParam_, verInfo_);
89         ret = HdiGetParameter(handle_, OMX_IndexParamVideoInit, portParam_);
90     }
91     CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "VideoInit failed");
92     inPortIndex_ = portParam_.nStartPortNumber;
93     outPortIndex_ = portParam_.nStartPortNumber + 1;
94     return GST_CODEC_OK;
95 }
96 
DeinitInner()97 void HdiCodec::DeinitInner()
98 {
99     if (handle_) {
100         MEDIA_LOGI("FreeHandle");
101         MediaTrace trace("HdiCodec::Deinit");
102         (void)HdiInit::GetInstance().FreeHandle(handle_, id_);
103     }
104     CodecComponentTypeRelease(handle_);
105     handle_ = nullptr;
106     if (appData_) {
107         delete appData_;
108         appData_ = nullptr;
109     }
110     if (callback_) {
111         CodecCallbackTypeStubRelease(callback_);
112         callback_ = nullptr;
113     }
114     (void)taskQue_.Stop();
115 }
116 
Deinit()117 void HdiCodec::Deinit()
118 {
119     MEDIA_LOGD("Deinit");
120     if (curState_ > OMX_StateLoaded) {
121         (void)WaitForState(OMX_StateLoaded);
122     }
123     DeinitInner();
124 }
125 
OnCodecDied()126 void HdiCodec::OnCodecDied()
127 {
128     MEDIA_LOGE("OnCodecDied");
129     MediaTrace trace("HdiCodec::OnCodecDied");
130 
131     {
132         unique_lock<mutex> lock(mutex_);
133         start_ = false;
134         isError_ = true;
135         cond_.notify_all();
136     }
137 
138     {
139         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
140         if (inBufferMgr_) {
141             inBufferMgr_->BufferReleased();
142         }
143         if (outBufferMgr_) {
144             outBufferMgr_->BufferReleased();
145         }
146     }
147 
148     {
149         std::unique_lock<std::shared_mutex> wLock(bufferMgrMutex_);
150         inBufferMgr_ = nullptr;
151         outBufferMgr_ = nullptr;
152     }
153 }
154 
SetHdiInBufferMgr(shared_ptr<HdiBufferMgr> bufferMgr)155 void HdiCodec::SetHdiInBufferMgr(shared_ptr<HdiBufferMgr> bufferMgr)
156 {
157     std::unique_lock<std::shared_mutex> wLock(bufferMgrMutex_);
158     inBufferMgr_ = bufferMgr;
159     inBufferMgr_->Init(handle_, inPortIndex_, verInfo_);
160 }
161 
SetHdiOutBufferMgr(shared_ptr<HdiBufferMgr> bufferMgr)162 void HdiCodec::SetHdiOutBufferMgr(shared_ptr<HdiBufferMgr> bufferMgr)
163 {
164     std::unique_lock<std::shared_mutex> wLock(bufferMgrMutex_);
165     outBufferMgr_ = bufferMgr;
166     outBufferMgr_->Init(handle_, outPortIndex_, verInfo_);
167 }
168 
SetHdiParamsMgr(shared_ptr<HdiParamsMgr> paramsMgr)169 void HdiCodec::SetHdiParamsMgr(shared_ptr<HdiParamsMgr> paramsMgr)
170 {
171     paramsMgr_ = paramsMgr;
172     paramsMgr_->Init(handle_, portParam_, verInfo_);
173 }
174 
SetParameter(GstCodecParamKey key,GstElement * element)175 int32_t HdiCodec::SetParameter(GstCodecParamKey key, GstElement *element)
176 {
177     CHECK_AND_RETURN_RET_LOG(paramsMgr_ != nullptr, GST_CODEC_ERROR, "paramsMgr_ is nullptr");
178     return paramsMgr_->SetParameter(key, element);
179 }
180 
GetParameter(GstCodecParamKey key,GstElement * element)181 int32_t HdiCodec::GetParameter(GstCodecParamKey key, GstElement *element)
182 {
183     CHECK_AND_RETURN_RET_LOG(paramsMgr_ != nullptr, GST_CODEC_ERROR, "paramsMgr_ is nullptr");
184     return paramsMgr_->GetParameter(key, element);
185 }
186 
Start()187 int32_t HdiCodec::Start()
188 {
189     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
190     MEDIA_LOGD("Start begin");
191     if (curState_ != OMX_StateExecuting) {
192         CHECK_AND_RETURN_RET_LOG(ChangeState(OMX_StateExecuting) == GST_CODEC_OK, GST_CODEC_ERROR, "Change failed");
193         CHECK_AND_RETURN_RET_LOG(WaitForState(OMX_StateExecuting) == GST_CODEC_OK, GST_CODEC_ERROR, "Wait failed");
194     }
195     {
196         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
197         CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
198         CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
199         MediaTrace trace("HdiCodec::Start");
200         inBufferMgr_->Start();
201         outBufferMgr_->Start();
202     }
203     unique_lock<mutex> lock(mutex_);
204     start_ = true;
205     MEDIA_LOGD("Start end");
206     return GST_CODEC_OK;
207 }
208 
Stop()209 int32_t HdiCodec::Stop()
210 {
211     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_OK, "codec error");
212     {
213         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
214         CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
215         CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
216         MediaTrace trace("HdiCodec::Stop");
217         inBufferMgr_->Stop(false);
218         outBufferMgr_->Stop(false);
219     }
220     if (curState_ == OMX_StateExecuting) {
221         CHECK_AND_RETURN_RET_LOG(ChangeState(OMX_StateIdle) == GST_CODEC_OK, GST_CODEC_ERROR, "ChangeState failed");
222         CHECK_AND_RETURN_RET_LOG(WaitForState(OMX_StateIdle) == GST_CODEC_OK, GST_CODEC_ERROR, "Wait failed");
223     }
224     if (curState_ == OMX_StateIdle) {
225         CHECK_AND_RETURN_RET_LOG(ChangeState(OMX_StateLoaded) == GST_CODEC_OK, GST_CODEC_ERROR, "ChangeState failed");
226     }
227     unique_lock<mutex> lock(mutex_);
228     start_ = false;
229     return GST_CODEC_OK;
230 }
231 
ChangeState(OMX_STATETYPE state)232 int32_t HdiCodec::ChangeState(OMX_STATETYPE state)
233 {
234     MEDIA_LOGD("Change state from %{public}u to %{public}u", targetState_, state);
235     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
236     if (targetState_ != state && curState_ != state) {
237         auto ret = HdiSendCommand(handle_, OMX_CommandStateSet, state, 0);
238         CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "HdiSendCommand failed");
239         targetState_ = state;
240     }
241     return GST_CODEC_OK;
242 }
243 
UseInputBuffers(std::vector<GstBuffer * > buffers)244 int32_t HdiCodec::UseInputBuffers(std::vector<GstBuffer*> buffers)
245 {
246     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
247     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
248     CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
249     MediaTrace trace("HdiCodec::UseInputBuffers");
250     return inBufferMgr_->UseBuffers(buffers);
251 }
252 
PushInputBuffer(GstBuffer * buffer)253 int32_t HdiCodec::PushInputBuffer(GstBuffer *buffer)
254 {
255     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
256     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
257     CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
258     return inBufferMgr_->PushBuffer(buffer);
259 }
260 
Flush(GstCodecDirect direct)261 int32_t HdiCodec::Flush(GstCodecDirect direct)
262 {
263     MEDIA_LOGD("Flush start");
264     if (!start_) {
265         return GST_CODEC_OK;
266     }
267 
268     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
269     CHECK_AND_RETURN_RET_LOG(handle_ != nullptr, GST_CODEC_ERROR, "Handle is nullptr");
270     CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
271     CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
272     int32_t ret = HDF_SUCCESS;
273     if (direct == GST_CODEC_ALL) {
274         inBufferMgr_->Flush(true);
275         outBufferMgr_->Flush(true);
276         ret = HdiSendCommand(handle_, OMX_CommandFlush, -1, 0);
277     }
278     CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "HdiSendCommand failed");
279     inBufferMgr_->WaitFlushed();
280     outBufferMgr_->WaitFlushed();
281     startFormatChange_.store(false);
282     MEDIA_LOGD("Flush end");
283     return GST_CODEC_OK;
284 }
285 
ActiveBufferMgr(GstCodecDirect direct,bool active)286 int32_t HdiCodec::ActiveBufferMgr(GstCodecDirect direct, bool active)
287 {
288     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
289     CHECK_AND_RETURN_RET_LOG(handle_ != nullptr, GST_CODEC_ERROR, "Handle is nullptr");
290     int32_t ret = HDF_SUCCESS;
291     // do not deal with input
292     if (direct == GST_CODEC_OUTPUT) {
293         if (active) {
294             ret = HdiSendCommand(handle_, OMX_CommandPortEnable, outPortIndex_, 0);
295             unique_lock<mutex> lock(mutex_);
296             outState_ = ACTIVING;
297         } else {
298             MEDIA_LOGD("OMX_CommandPortDisable out %{public}u", outPortIndex_);
299             ret = HdiSendCommand(handle_, OMX_CommandPortDisable, outPortIndex_, 0);
300             unique_lock<mutex> lock(mutex_);
301             outState_ = DEACTIVING;
302         }
303     }
304     CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "port change fail");
305     return GST_CODEC_OK;
306 }
307 
FreeInputBuffers()308 int32_t HdiCodec::FreeInputBuffers()
309 {
310     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
311     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_OK, "codec error");
312     CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
313     CHECK_AND_RETURN_RET_LOG(inBufferMgr_->FreeBuffers() == GST_CODEC_OK, GST_CODEC_ERROR, "Freebuffer fail");
314     if (inState_ == DEACTIVING) {
315         WaitForEvent(OMX_CommandPortDisable);
316     }
317     return GST_CODEC_OK;
318 }
319 
UseOutputBuffers(std::vector<GstBuffer * > buffers)320 int32_t HdiCodec::UseOutputBuffers(std::vector<GstBuffer*> buffers)
321 {
322     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
323     MEDIA_LOGD("UseOutputBuffers");
324     MediaTrace trace("HdiCodec::UseOutputBuffers");
325     if (curState_ < OMX_StateIdle) {
326         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
327         CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
328         CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
329         CHECK_AND_RETURN_RET_LOG(ChangeState(OMX_StateIdle) == GST_CODEC_OK,
330             GST_CODEC_ERROR, "ChangeState failed");
331         // m40 need input and output allocate or use common
332         CHECK_AND_RETURN_RET_LOG(inBufferMgr_->Preprocessing() == GST_CODEC_OK,
333             GST_CODEC_ERROR, "Allocatebuffer fail");
334         CHECK_AND_RETURN_RET_LOG(outBufferMgr_->UseBuffers(buffers) == GST_CODEC_OK,
335             GST_CODEC_ERROR, "UseBuffers fail");
336         CHECK_AND_RETURN_RET_LOG(WaitForState(OMX_StateIdle) == GST_CODEC_OK,
337             GST_CODEC_ERROR, "Wait failed");
338     } else if (outState_ == ACTIVING) {
339         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
340         CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
341         CHECK_AND_RETURN_RET_LOG(outBufferMgr_->UseBuffers(buffers) == GST_CODEC_OK,
342             GST_CODEC_ERROR, "Usebuffer fail");
343         WaitForEvent(OMX_CommandPortEnable);
344     }
345     return GST_CODEC_OK;
346 }
347 
PushOutputBuffer(GstBuffer * buffer)348 int32_t HdiCodec::PushOutputBuffer(GstBuffer *buffer)
349 {
350     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
351     CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
352     return outBufferMgr_->PushBuffer(buffer);
353 }
354 
PullOutputBuffer(GstBuffer ** buffer)355 int32_t HdiCodec::PullOutputBuffer(GstBuffer **buffer)
356 {
357     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_ERROR, "codec error");
358     CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
359     int32_t ret = GST_CODEC_OK;
360     {
361         unique_lock<mutex> lock(mutex_);
362         if ((ret_ != GST_CODEC_OK && ret_ != GST_CODEC_FORMAT_CHANGE) ||
363             (ret_ == GST_CODEC_FORMAT_CHANGE && outBufferMgr_->GetWaitDisPlayBufNum() == 0)) {
364             MEDIA_LOGD("change ret from ret %{public}d to ret %{public}d", ret, ret_);
365             ret = ret_;
366             ret_ = GST_CODEC_OK;
367             return ret;
368         }
369     }
370     {
371         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
372         CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
373         ret = outBufferMgr_->PullBuffer(buffer);
374     }
375     MEDIA_LOGD("ret %{public}d", ret);
376     {
377         unique_lock<mutex> lock(mutex_);
378         if ((ret_ != GST_CODEC_OK && ret_ != GST_CODEC_FORMAT_CHANGE) ||
379             (ret_ == GST_CODEC_FORMAT_CHANGE && outBufferMgr_->GetWaitDisPlayBufNum() == 0)) {
380             MEDIA_LOGD("change ret from ret %{public}d to ret %{public}d", ret, ret_);
381             ret = ret_;
382             ret_ = GST_CODEC_OK;
383             return ret;
384         }
385     }
386     return ret;
387 }
388 
SetOutputPool(GstBufferPool * pool)389 void HdiCodec::SetOutputPool(GstBufferPool *pool)
390 {
391     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
392     CHECK_AND_RETURN_LOG(outBufferMgr_ != nullptr, "outBufferMgr_ is nullptr");
393     outBufferMgr_->SetOutputPool(pool);
394 }
395 
FreeOutputBuffers()396 int32_t HdiCodec::FreeOutputBuffers()
397 {
398     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
399     CHECK_AND_RETURN_RET_LOG(!isError_, GST_CODEC_OK, "codec error");
400     CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
401     MEDIA_LOGD("FreeOutputBuffers");
402     CHECK_AND_RETURN_RET_LOG(outBufferMgr_->FreeBuffers() == GST_CODEC_OK, GST_CODEC_ERROR, "Freebuffers fail");
403     if (outState_ == DEACTIVING) {
404         WaitForEvent(OMX_CommandPortDisable);
405     }
406     return GST_CODEC_OK;
407 }
408 
Event(CodecCallbackType * self,OMX_EVENTTYPE event,EventInfo * info)409 int32_t HdiCodec::Event(CodecCallbackType *self, OMX_EVENTTYPE event, EventInfo *info)
410 {
411     MediaTrace trace("HdiCodec::Event");
412     (void)self;
413     CHECK_AND_RETURN_RET_LOG(info != nullptr, HDF_ERR_INVALID_PARAM, "appData is null");
414     if (OMX_EVENT_TO_STRING.find(event) != OMX_EVENT_TO_STRING.end()) {
415         MEDIA_LOGD("Event %{public}s %{public}d data1 %{public}d data2 %{public}d",
416             OMX_EVENT_TO_STRING.at(event).c_str(), event, info->data1, info->data2);
417     } else {
418         MEDIA_LOGW("Unknown event %{public}d data1 %{public}d data2 %{public}d",
419             event, info->data1, info->data2);
420     }
421     AppData *mAppData = reinterpret_cast<AppData *>(info->appData);
422     auto instance = mAppData->instance.lock();
423     CHECK_AND_RETURN_RET_LOG(instance != nullptr, HDF_ERR_INVALID_PARAM, "HdiCodec is null");
424     return instance->OnEvent(event, info);
425 }
426 
OnEvent(OMX_EVENTTYPE event,EventInfo * info)427 int32_t HdiCodec::OnEvent(OMX_EVENTTYPE event, EventInfo *info)
428 {
429     auto task = std::make_shared<TaskHandler<void>>([this, event, info] {
430         switch (event) {
431             case OMX_EventCmdComplete:
432                 return HandelEventCmdComplete(info->data1, info->data2);
433             case OMX_EventPortSettingsChanged:
434                 return HandleEventPortSettingsChanged(info->data1, info->data2);
435             case OMX_EventBufferFlag:
436                 return HandleEventBufferFlag(info->data1, info->data2);
437             case OMX_EventError:
438                 return HandleEventError(info->data1);
439             default:
440                 break;
441         }
442     });
443     (void)taskQue_.EnqueueTask(task);
444     (void)task->GetResult();
445     return HDF_SUCCESS;
446 }
447 
WaitForState(OMX_STATETYPE state)448 int32_t HdiCodec::WaitForState(OMX_STATETYPE state)
449 {
450     WaitForEvent(OMX_CommandStateSet);
451     CHECK_AND_RETURN_RET_LOG(curState_ == state, GST_CODEC_ERROR, "Wait state failed");
452     return GST_CODEC_OK;
453 }
454 
WaitForEvent(OMX_U32 cmd)455 void HdiCodec::WaitForEvent(OMX_U32 cmd)
456 {
457     unique_lock<mutex> lock(mutex_);
458     int32_t newCmd = static_cast<int32_t>(cmd);
459     MEDIA_LOGD("wait eventdone %{public}d lastcmd %{public}d cmd %{public}u", eventDone_, lastCmd_, cmd);
460     static constexpr int32_t timeout = 2;
461     cond_.wait_for(lock, std::chrono::seconds(timeout),
462         [this, &newCmd]() { return (eventDone_ && (lastCmd_ == newCmd || lastCmd_ == -1)) || isError_; });
463     eventDone_ = false;
464 }
465 
HandelEventStateSet(OMX_U32 data)466 void HdiCodec::HandelEventStateSet(OMX_U32 data)
467 {
468     MEDIA_LOGD("change curState_ from %{public}u to %{public}u", curState_, data);
469     curState_ = static_cast<OMX_STATETYPE>(data);
470     eventDone_ = true;
471 }
472 
HandelEventFlush(OMX_U32 data)473 void HdiCodec::HandelEventFlush(OMX_U32 data)
474 {
475     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
476     if (data == inPortIndex_) {
477         CHECK_AND_RETURN_LOG(inBufferMgr_ != nullptr, "inBufferMgr_ is nullptr");
478         inBufferMgr_->Flush(false);
479     } else {
480         CHECK_AND_RETURN_LOG(outBufferMgr_ != nullptr, "outBufferMgr_ is nullptr");
481         outBufferMgr_->Flush(false);
482     }
483 }
484 
HandelEventPortDisable(OMX_U32 data)485 void HdiCodec::HandelEventPortDisable(OMX_U32 data)
486 {
487     if (data != inPortIndex_) {
488         outState_ = DEACTIVATED;
489     }
490     eventDone_ = true;
491 }
492 
HandelEventPortEnable(OMX_U32 data)493 void HdiCodec::HandelEventPortEnable(OMX_U32 data)
494 {
495     if (data != inPortIndex_) {
496         outState_ = ACTIVATED;
497     }
498     eventDone_ = true;
499 }
500 
HandelEventCmdComplete(OMX_U32 data1,OMX_U32 data2)501 void HdiCodec::HandelEventCmdComplete(OMX_U32 data1, OMX_U32 data2)
502 {
503     unique_lock<mutex> lock(mutex_);
504     lastCmd_ = (int32_t)data1;
505     switch (data1) {
506         case OMX_CommandStateSet:
507             HandelEventStateSet(data2);
508             break;
509         case OMX_CommandFlush:
510             HandelEventFlush(data2);
511             break;
512         case OMX_CommandPortDisable:
513             HandelEventPortDisable(data2);
514             break;
515         case OMX_CommandPortEnable:
516             HandelEventPortEnable(data2);
517             break;
518         default:
519             break;
520     }
521     cond_.notify_all();
522 }
523 
HandleEventPortSettingsChanged(OMX_U32 data1,OMX_U32 data2)524 void HdiCodec::HandleEventPortSettingsChanged(OMX_U32 data1, OMX_U32 data2)
525 {
526     MEDIA_LOGD("handle change");
527     unique_lock<mutex> lock(mutex_);
528     if (data2 == OMX_IndexParamPortDefinition) {
529         MEDIA_LOGD("GST_CODEC_FORMAT_CHANGE");
530         ret_ = GST_CODEC_FORMAT_CHANGE;
531         startFormatChange_.store(true);
532         std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
533         CHECK_AND_RETURN_LOG(data1 != inPortIndex_, "inPortIndex_ setting changed");
534         if (data1 != inPortIndex_) {
535             CHECK_AND_RETURN_LOG(outBufferMgr_ != nullptr, "outBufferMgr_ is nullptr");
536             outBufferMgr_->Stop(true);
537         }
538     }
539     MEDIA_LOGD("handle change end");
540 }
541 
HandleEventBufferFlag(OMX_U32 data1,OMX_U32 data2)542 void HdiCodec::HandleEventBufferFlag(OMX_U32 data1, OMX_U32 data2)
543 {
544     unique_lock<mutex> lock(mutex_);
545     if (data1 == 1 && (data2 & OMX_BUFFERFLAG_EOS)) {
546         MEDIA_LOGD("it is eos, wait buffer eos");
547     }
548 }
549 
HandleEventError(OMX_U32 data)550 void HdiCodec::HandleEventError(OMX_U32 data)
551 {
552     (void)data;
553     unique_lock<mutex> lock(mutex_);
554     ret_ = GST_CODEC_ERROR;
555     eventDone_ = true;
556     lastCmd_ = -1;
557     cond_.notify_all();
558 }
559 
EmptyBufferDone(CodecCallbackType * self,int64_t appData,const OmxCodecBuffer * buffer)560 int32_t HdiCodec::EmptyBufferDone(CodecCallbackType *self, int64_t appData, const OmxCodecBuffer *buffer)
561 {
562     MediaTrace trace("HdiCodec::EmptyBufferDone");
563     MEDIA_LOGD("EmptyBufferDone");
564     (void)self;
565     AppData *mAppData = reinterpret_cast<AppData *>(appData);
566     CHECK_AND_RETURN_RET_LOG(mAppData != nullptr, HDF_ERR_INVALID_PARAM, "appData is null");
567     auto instance = mAppData->instance.lock();
568     CHECK_AND_RETURN_RET_LOG(instance != nullptr, HDF_ERR_INVALID_PARAM, "HdiCodec is null");
569     CHECK_AND_RETURN_RET_LOG(instance->OnEmptyBufferDone(buffer) == GST_CODEC_OK,
570         OMX_ErrorBadParameter, "empty buffer done failed");
571     return HDF_SUCCESS;
572 }
573 
OnEmptyBufferDone(const OmxCodecBuffer * buffer)574 int32_t HdiCodec::OnEmptyBufferDone(const OmxCodecBuffer *buffer)
575 {
576     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
577     CHECK_AND_RETURN_RET_LOG(inBufferMgr_ != nullptr, GST_CODEC_ERROR, "inBufferMgr_ is nullptr");
578     auto task = std::make_shared<TaskHandler<int32_t>>([this, buffer] {
579         return inBufferMgr_->CodecBufferAvailable(buffer);
580     });
581     (void)taskQue_.EnqueueTask(task);
582     auto result = task->GetResult();
583     int32_t ret = GST_CODEC_OK;
584     if (result.HasResult()) {
585         ret = result.Value();
586     }
587     return ret;
588 }
589 
FillBufferDone(CodecCallbackType * self,int64_t appData,const OmxCodecBuffer * buffer)590 int32_t HdiCodec::FillBufferDone(CodecCallbackType *self, int64_t appData, const OmxCodecBuffer *buffer)
591 {
592     MediaTrace trace("HdiCodec::FillBufferDone");
593     MEDIA_LOGD("FillBufferDone");
594     (void)self;
595     AppData *mAppData = reinterpret_cast<AppData *>(appData);
596     CHECK_AND_RETURN_RET_LOG(mAppData != nullptr, OMX_ErrorBadParameter, "appData is null");
597     auto instance = mAppData->instance.lock();
598     CHECK_AND_RETURN_RET_LOG(instance != nullptr, OMX_ErrorBadParameter, "HdiCodec is null");
599     if (instance->OnFillBufferDone(buffer) != GST_CODEC_OK) {
600         MEDIA_LOGE("fill buffer done failed");
601         return OMX_ErrorBadParameter;
602     }
603     return HDF_SUCCESS;
604 }
605 
OnFillBufferDone(const OmxCodecBuffer * buffer)606 int32_t HdiCodec::OnFillBufferDone(const OmxCodecBuffer *buffer)
607 {
608     std::shared_lock<std::shared_mutex> rLock(bufferMgrMutex_);
609     CHECK_AND_RETURN_RET_LOG(outBufferMgr_ != nullptr, GST_CODEC_ERROR, "outBufferMgr_ is nullptr");
610     auto task = std::make_shared<TaskHandler<int32_t>>([this, buffer] {
611         return outBufferMgr_->CodecBufferAvailable(buffer);
612     });
613     (void)taskQue_.EnqueueTask(task);
614     auto result = task->GetResult();
615     int32_t ret = GST_CODEC_OK;
616     if (result.HasResult()) {
617         ret = result.Value();
618     }
619     return ret;
620 }
621 
IsFormatChanged()622 bool HdiCodec::IsFormatChanged()
623 {
624     bool ret = startFormatChange_.load();
625     startFormatChange_.store(false);
626     return ret;
627 }
628 }  // namespace Media
629 }  // namespace OHOS
630