1 /*
2 * Copyright (c) 2023-2025 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 #define HST_LOG_TAG "Filter"
17 #define MEDIA_PIPELINE
18
19 #include "filter/filter.h"
20 #include "osal/utils/util.h"
21 #include "common/log.h"
22 #include <algorithm>
23 #include "parameters.h"
24
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_FOUNDATION, "Filter" };
27 constexpr uint32_t THREAD_PRIORITY_41 = 7;
28 }
29
30 namespace OHOS {
31 namespace Media {
32 namespace Pipeline {
Filter(std::string name,FilterType type,bool isAyncMode)33 Filter::Filter(std::string name, FilterType type, bool isAyncMode)
34 : name_(std::move(name)), filterType_(type), isAsyncMode_(isAyncMode)
35 {
36 }
37
~Filter()38 Filter::~Filter()
39 {
40 nextFiltersMap_.clear();
41 }
42
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback)43 void Filter::Init(const std::shared_ptr<EventReceiver>& receiver, const std::shared_ptr<FilterCallback>& callback)
44 {
45 receiver_ = receiver;
46 callback_ = callback;
47 }
48
Init(const std::shared_ptr<EventReceiver> & receiver,const std::shared_ptr<FilterCallback> & callback,const std::shared_ptr<InterruptMonitor> & monitor)49 void Filter::Init(const std::shared_ptr<EventReceiver>& receiver,
50 const std::shared_ptr<FilterCallback>& callback, const std::shared_ptr<InterruptMonitor>& monitor)
51 {
52 Init(receiver, callback);
53 interruptMonitor_ = monitor;
54 }
55
LinkPipeLine(const std::string & groupId,bool needTurbo,bool needInit)56 void Filter::LinkPipeLine(const std::string &groupId, bool needTurbo, bool needInit)
57 {
58 groupId_ = groupId;
59 MEDIA_LOG_I("Filter %{public}s LinkPipeLine:%{public}s, isAsyncMode_:%{public}d",
60 name_.c_str(), groupId.c_str(), isAsyncMode_);
61 Status ret = Status::OK;
62 if (!isAsyncMode_) {
63 if (needInit) {
64 ret = DoInitAfterLink();
65 }
66 SetErrCode(ret);
67 ChangeState(ret == Status::OK ? FilterState::INITIALIZED : FilterState::ERROR);
68 return;
69 }
70
71 TaskType taskType = TaskType::SINGLETON;
72 switch (filterType_) {
73 case FilterType::FILTERTYPE_ASINK: // fall-through
74 case FilterType::AUDIO_CAPTURE:
75 taskType = TaskType::AUDIO;
76 break;
77 default:
78 break;
79 }
80
81 filterTask_ = std::make_unique<Task>(name_, groupId_, taskType, TaskPriority::HIGH, false);
82
83 if (needTurbo) {
84 filterTask_->UpdateThreadPriority(THREAD_PRIORITY_41, "media_service");
85 }
86
87 MEDIA_LOG_I("needInit is: " PUBLIC_LOG_U32, needInit);
88
89 filterTask_->SubmitJobOnce([this, needInit] {
90 Status ret = Status::OK;
91 if (needInit) {
92 ret = DoInitAfterLink();
93 }
94 SetErrCode(ret);
95 ChangeState(ret == Status::OK ? FilterState::INITIALIZED : FilterState::ERROR);
96 });
97 }
98
Prepare()99 Status Filter::Prepare()
100 {
101 MEDIA_LOG_D("Prepare %{public}s, pState:%{public}d", name_.c_str(), curState_);
102 if (filterTask_) {
103 filterTask_->SubmitJobOnce([this] {
104 PrepareDone();
105 });
106 } else {
107 return PrepareDone();
108 }
109 return Status::OK;
110 }
111
PrepareDone()112 Status Filter::PrepareDone()
113 {
114 MEDIA_LOG_I("Prepare enter %{public}s", name_.c_str());
115 if (curState_ == FilterState::ERROR) {
116 // if DoInitAfterLink error, do not prepare.
117 return Status::ERROR_INVALID_OPERATION;
118 }
119 // next filters maybe added in DoPrepare, so we must DoPrepare first
120 Status ret = DoPrepare();
121 SetErrCode(ret);
122 if (ret != Status::OK) {
123 ChangeState(FilterState::ERROR);
124 return ret;
125 }
126 for (auto iter : nextFiltersMap_) {
127 for (auto filter : iter.second) {
128 auto ret = filter->Prepare();
129 if (ret != Status::OK) {
130 return ret;
131 }
132 }
133 }
134 ChangeState(FilterState::READY);
135 return ret;
136 }
137
Start()138 Status Filter::Start()
139 {
140 MEDIA_LOG_D("Start %{public}s, pState:%{public}d", name_.c_str(), curState_);
141 if (filterTask_) {
142 filterTask_->SubmitJobOnce([this] {
143 StartDone();
144 filterTask_->Start();
145 });
146 for (auto iter : nextFiltersMap_) {
147 for (auto filter : iter.second) {
148 filter->Start();
149 }
150 }
151 } else {
152 for (auto iter : nextFiltersMap_) {
153 for (auto filter : iter.second) {
154 filter->Start();
155 }
156 }
157 return StartDone();
158 }
159 return Status::OK;
160 }
161
StartDone()162 Status Filter::StartDone()
163 {
164 MEDIA_LOG_I("Start in %{public}s", name_.c_str());
165 Status ret = DoStart();
166 SetErrCode(ret);
167 ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
168 return ret;
169 }
170
SetIsInPrePausing(bool isInPrePausing)171 void Filter::SetIsInPrePausing(bool isInPrePausing)
172 {
173 MEDIA_LOG_D("SetIsInPrePausing %{public}s, pState:%{public}d, isInPrePausing:%{public}d",
174 name_.c_str(), curState_, isInPrePausing);
175 DoSetIsInPrePausing(isInPrePausing);
176 for (auto iter : nextFiltersMap_) {
177 for (auto filter : iter.second) {
178 FALSE_GOON_NOEXEC(filter, filter->SetIsInPrePausing(isInPrePausing));
179 }
180 }
181 }
182
Pause()183 Status Filter::Pause()
184 {
185 MEDIA_LOG_D("Pause %{public}s, pState:%{public}d", name_.c_str(), curState_);
186 // In offload case, we need pause to interrupt audio_sink_plugin write function, so do not use asyncmode
187 auto ret = PauseDone();
188 if (filterTask_) {
189 filterTask_->Pause();
190 }
191 for (auto iter : nextFiltersMap_) {
192 for (auto filter : iter.second) {
193 filter->Pause();
194 }
195 }
196 return ret;
197 }
198
Freeze()199 Status Filter::Freeze()
200 {
201 MEDIA_LOG_I("Freeze %{public}s, pState:%{public}d, innerState:%{public}d",
202 name_.c_str(), curState_, state_);
203 // In offload case, we need pause to interrupt audio_sink_plugin write function, so do not use asyncmode
204 auto ret = DoFreeze();
205 if (filterTask_) {
206 filterTask_->Pause();
207 }
208 for (auto iter : nextFiltersMap_) {
209 for (auto filter : iter.second) {
210 auto curRet = filter->Freeze();
211 if (curRet != Status::OK) {
212 ret = curRet;
213 }
214 }
215 }
216 return ret;
217 }
218
UnFreeze()219 Status Filter::UnFreeze()
220 {
221 MEDIA_LOG_I("UnFreeze %{public}s, pState:%{public}d, innerState:%{public}d",
222 name_.c_str(), curState_, state_);
223 auto ret = DoUnFreeze();
224 if (filterTask_ && state_ == FilterState::RUNNING) {
225 filterTask_->Start();
226 }
227 for (auto iter : nextFiltersMap_) {
228 for (auto filter : iter.second) {
229 auto curRet = filter->UnFreeze();
230 if (curRet != Status::OK) {
231 ret = curRet;
232 }
233 }
234 }
235 return ret;
236 }
237
DoFreeze()238 Status Filter::DoFreeze()
239 {
240 return Status::OK;
241 }
242
DoUnFreeze()243 Status Filter::DoUnFreeze()
244 {
245 return Status::OK;
246 }
247
PauseDragging()248 Status Filter::PauseDragging()
249 {
250 MEDIA_LOG_D("PauseDragging %{public}s, pState:%{public}d", name_.c_str(), curState_);
251 auto ret = DoPauseDragging();
252 if (filterTask_) {
253 filterTask_->Pause();
254 }
255 for (auto iter : nextFiltersMap_) {
256 for (auto filter : iter.second) {
257 auto curRet = filter->PauseDragging();
258 if (curRet != Status::OK) {
259 ret = curRet;
260 }
261 }
262 }
263 return ret;
264 }
265
PauseAudioAlign()266 Status Filter::PauseAudioAlign()
267 {
268 MEDIA_LOG_D("PauseAudioAlign %{public}s, pState:%{public}d", name_.c_str(), curState_);
269 auto ret = DoPauseAudioAlign();
270 if (filterTask_) {
271 filterTask_->Pause();
272 }
273 for (auto iter : nextFiltersMap_) {
274 for (auto filter : iter.second) {
275 auto curRet = filter->PauseAudioAlign();
276 if (curRet != Status::OK) {
277 ret = curRet;
278 }
279 }
280 }
281 return ret;
282 }
283
PauseDone()284 Status Filter::PauseDone()
285 {
286 MEDIA_LOG_I("Pause in %{public}s", name_.c_str());
287 Status ret = DoPause();
288 SetErrCode(ret);
289 ChangeState(ret == Status::OK ? FilterState::PAUSED : FilterState::ERROR);
290 return ret;
291 }
292
Resume()293 Status Filter::Resume()
294 {
295 MEDIA_LOG_D("Resume %{public}s, pState:%{public}d", name_.c_str(), curState_);
296 if (filterTask_) {
297 filterTask_->SubmitJobOnce([this]() {
298 ResumeDone();
299 filterTask_->Start();
300 });
301 for (auto iter : nextFiltersMap_) {
302 for (auto filter : iter.second) {
303 filter->Resume();
304 }
305 }
306 } else {
307 for (auto iter : nextFiltersMap_) {
308 for (auto filter : iter.second) {
309 filter->Resume();
310 }
311 }
312 return ResumeDone();
313 }
314 return Status::OK;
315 }
316
ResumeDone()317 Status Filter::ResumeDone()
318 {
319 MEDIA_LOG_I("Resume in %{public}s", name_.c_str());
320 Status ret = DoResume();
321 SetErrCode(ret);
322 ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
323 return ret;
324 }
325
ResumeDragging()326 Status Filter::ResumeDragging()
327 {
328 MEDIA_LOG_D("ResumeDragging %{public}s, pState:%{public}d", name_.c_str(), curState_);
329 auto ret = Status::OK;
330 ret = DoResumeDragging();
331 if (filterTask_) {
332 filterTask_->Start();
333 }
334 for (auto iter : nextFiltersMap_) {
335 for (auto filter : iter.second) {
336 auto curRet = filter->ResumeDragging();
337 if (curRet != Status::OK) {
338 ret = curRet;
339 }
340 }
341 }
342 return ret;
343 }
344
ResumeAudioAlign()345 Status Filter::ResumeAudioAlign()
346 {
347 MEDIA_LOG_D("ResumeAudioAlign %{public}s, pState:%{public}d", name_.c_str(), curState_);
348 auto ret = Status::OK;
349 ret = DoResumeAudioAlign();
350 if (filterTask_) {
351 filterTask_->Start();
352 }
353 for (auto iter : nextFiltersMap_) {
354 for (auto filter : iter.second) {
355 auto curRet = filter->ResumeAudioAlign();
356 if (curRet != Status::OK) {
357 ret = curRet;
358 }
359 }
360 }
361 return ret;
362 }
363
Stop()364 Status Filter::Stop()
365 {
366 MEDIA_LOG_D("Stop %{public}s, pState:%{public}d", name_.c_str(), curState_);
367 // In offload case, we need stop to interrupt audio_sink_plugin write function, so do not use asyncmode
368 auto ret = StopDone();
369 if (filterTask_) {
370 filterTask_->Stop();
371 }
372 for (auto iter : nextFiltersMap_) {
373 for (auto filter : iter.second) {
374 filter->Stop();
375 }
376 }
377 return ret;
378 }
379
StopDone()380 Status Filter::StopDone()
381 {
382 MEDIA_LOG_I("Stop in %{public}s", name_.c_str());
383 Status ret = DoStop();
384 SetErrCode(ret);
385 ChangeState(ret == Status::OK ? FilterState::STOPPED : FilterState::ERROR);
386 return ret;
387 }
388
Flush()389 Status Filter::Flush()
390 {
391 MEDIA_LOG_D("Flush %{public}s, pState:%{public}d", name_.c_str(), curState_);
392 for (auto iter : nextFiltersMap_) {
393 for (auto filter : iter.second) {
394 filter->Flush();
395 }
396 }
397 {
398 AutoLock lock(generationMutex_);
399 jobIdxBase_ = jobIdx_;
400 }
401 return DoFlush();
402 }
403
Release()404 Status Filter::Release()
405 {
406 MEDIA_LOG_D("Release %{public}s, pState:%{public}d", name_.c_str(), curState_);
407 if (filterTask_) {
408 filterTask_->SubmitJobOnce([this]() {
409 ReleaseDone();
410 });
411 for (auto iter : nextFiltersMap_) {
412 for (auto filter : iter.second) {
413 filter->Release();
414 }
415 }
416 } else {
417 for (auto iter : nextFiltersMap_) {
418 for (auto filter : iter.second) {
419 filter->Release();
420 }
421 }
422 return ReleaseDone();
423 }
424 return Status::OK;
425 }
426
ReleaseDone()427 Status Filter::ReleaseDone()
428 {
429 MEDIA_LOG_I("Release in %{public}s", name_.c_str());
430 Status ret = DoRelease();
431 SetErrCode(ret);
432 // at this point, the final state should be RELEASED
433 ChangeState(FilterState::RELEASED);
434 return ret;
435 }
436
ClearAllNextFilters()437 Status Filter::ClearAllNextFilters()
438 {
439 nextFiltersMap_.clear();
440 return Status::OK;
441 }
442
SetPlayRange(int64_t start,int64_t end)443 Status Filter::SetPlayRange(int64_t start, int64_t end)
444 {
445 MEDIA_LOG_D("SetPlayRange %{public}s, pState:%{public}ld", name_.c_str(), curState_);
446 for (auto iter : nextFiltersMap_) {
447 for (auto filter : iter.second) {
448 filter->SetPlayRange(start, end);
449 }
450 }
451 return DoSetPlayRange(start, end);
452 }
453
Preroll()454 Status Filter::Preroll()
455 {
456 Status ret = DoPreroll();
457 if (ret != Status::OK) {
458 return ret;
459 }
460 for (auto iter : nextFiltersMap_) {
461 for (auto filter : iter.second) {
462 ret = filter->Preroll();
463 if (ret != Status::OK) {
464 return ret;
465 }
466 }
467 }
468 return Status::OK;
469 }
470
WaitPrerollDone(bool render)471 Status Filter::WaitPrerollDone(bool render)
472 {
473 Status ret = Status::OK;
474 for (auto iter : nextFiltersMap_) {
475 for (auto filter : iter.second) {
476 auto curRet = filter->WaitPrerollDone(render);
477 if (curRet != Status::OK) {
478 ret = curRet;
479 }
480 }
481 }
482 auto curRet = DoWaitPrerollDone(render);
483 if (curRet != Status::OK) {
484 ret = curRet;
485 }
486 return ret;
487 }
488
StartFilterTask()489 void Filter::StartFilterTask()
490 {
491 if (filterTask_) {
492 filterTask_->Start();
493 }
494 }
495
PauseFilterTask()496 void Filter::PauseFilterTask()
497 {
498 if (filterTask_) {
499 filterTask_->Pause();
500 }
501 }
502
StopFilterTask()503 void Filter::StopFilterTask()
504 {
505 if (filterTask_) {
506 filterTask_->Stop();
507 }
508 }
509
ProcessInputBuffer(int sendArg,int64_t delayUs)510 Status Filter::ProcessInputBuffer(int sendArg, int64_t delayUs)
511 {
512 MEDIA_LOG_D("Filter::ProcessInputBuffer %{public}s", name_.c_str());
513 FALSE_RETURN_V_MSG(!isAsyncMode_ || filterTask_, Status::ERROR_INVALID_OPERATION, "no filterTask in async mode");
514 if (filterTask_) {
515 int64_t processIdx;
516 {
517 AutoLock lock(generationMutex_);
518 processIdx = ++jobIdx_;
519 }
520 filterTask_->SubmitJob([this, sendArg, processIdx]() {
521 // drop frame after flush
522 bool isDrop;
523 {
524 AutoLock lock(generationMutex_);
525 isDrop = processIdx <= jobIdxBase_;
526 }
527 DoProcessInputBuffer(sendArg, isDrop);
528 }, delayUs, false);
529 } else {
530 Task::SleepInTask(delayUs / 1000); // 1000 convert to ms
531 DoProcessInputBuffer(sendArg, false);
532 }
533 return Status::OK;
534 }
535
ProcessOutputBuffer(int sendArg,int64_t delayUs,bool byIdx,uint32_t idx,int64_t renderTime)536 Status Filter::ProcessOutputBuffer(int sendArg, int64_t delayUs, bool byIdx, uint32_t idx, int64_t renderTime)
537 {
538 MEDIA_LOG_D("Filter::ProcessOutputBuffer %{public}s", name_.c_str());
539 FALSE_RETURN_V_MSG(!isAsyncMode_ || filterTask_, Status::ERROR_INVALID_OPERATION, "no filterTask in async mode");
540 if (filterTask_) {
541 int64_t processIdx;
542 {
543 AutoLock lock(generationMutex_);
544 processIdx = ++jobIdx_;
545 }
546 filterTask_->SubmitJob([this, sendArg, processIdx, byIdx, idx, renderTime]() {
547 // drop frame after flush
548 bool isDrop;
549 {
550 AutoLock lock(generationMutex_);
551 isDrop = processIdx <= jobIdxBase_;
552 }
553 DoProcessOutputBuffer(sendArg, isDrop, byIdx, idx, renderTime);
554 }, delayUs, false);
555 } else {
556 Task::SleepInTask(delayUs / 1000); // 1000 convert to ms
557 DoProcessOutputBuffer(sendArg, false, false, idx, renderTime);
558 }
559 return Status::OK;
560 }
561
SetPerfRecEnabled(bool perfRecNeeded)562 Status Filter::SetPerfRecEnabled(bool perfRecNeeded)
563 {
564 auto ret = DoSetPerfRecEnabled(perfRecNeeded);
565 for (auto iter : nextFiltersMap_) {
566 for (auto filter : iter.second) {
567 filter->SetPerfRecEnabled(perfRecNeeded);
568 }
569 }
570 return ret;
571 }
572
DoSetPerfRecEnabled(bool perfRecNeeded)573 Status Filter::DoSetPerfRecEnabled(bool perfRecNeeded)
574 {
575 isPerfRecEnabled_ = perfRecNeeded;
576 return Status::OK;
577 }
578
DoInitAfterLink()579 Status Filter::DoInitAfterLink()
580 {
581 MEDIA_LOG_I("Filter::DoInitAfterLink");
582 return Status::OK;
583 }
584
DoPrepare()585 Status Filter::DoPrepare()
586 {
587 return Status::OK;
588 }
589
DoStart()590 Status Filter::DoStart()
591 {
592 return Status::OK;
593 }
594
DoPause()595 Status Filter::DoPause()
596 {
597 return Status::OK;
598 }
599
DoPauseDragging()600 Status Filter::DoPauseDragging()
601 {
602 return Status::OK;
603 }
604
DoPauseAudioAlign()605 Status Filter::DoPauseAudioAlign()
606 {
607 return Status::OK;
608 }
609
DoResume()610 Status Filter::DoResume()
611 {
612 return Status::OK;
613 }
614
DoResumeDragging()615 Status Filter::DoResumeDragging()
616 {
617 return Status::OK;
618 }
619
DoResumeAudioAlign()620 Status Filter::DoResumeAudioAlign()
621 {
622 return Status::OK;
623 }
624
DoStop()625 Status Filter::DoStop()
626 {
627 return Status::OK;
628 }
629
DoFlush()630 Status Filter::DoFlush()
631 {
632 return Status::OK;
633 }
634
DoRelease()635 Status Filter::DoRelease()
636 {
637 return Status::OK;
638 }
639
DoPreroll()640 Status Filter::DoPreroll()
641 {
642 return Status::OK;
643 }
644
DoWaitPrerollDone(bool render)645 Status Filter::DoWaitPrerollDone(bool render)
646 {
647 return Status::OK;
648 }
649
DoSetPlayRange(int64_t start,int64_t end)650 Status Filter::DoSetPlayRange(int64_t start, int64_t end)
651 {
652 return Status::OK;
653 }
654
DoProcessInputBuffer(int recvArg,bool dropFrame)655 Status Filter::DoProcessInputBuffer(int recvArg, bool dropFrame)
656 {
657 return Status::OK;
658 }
659
DoProcessOutputBuffer(int recvArg,bool dropFrame,bool byIdx,uint32_t idx,int64_t renderTimee)660 Status Filter::DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, uint32_t idx, int64_t renderTimee)
661 {
662 return Status::OK;
663 }
664
DoReleaseOnMuted(bool isNeedRelease)665 Status Filter::DoReleaseOnMuted(bool isNeedRelease)
666 {
667 return Status::OK;
668 }
669
DoReInitAndStart()670 Status Filter::DoReInitAndStart()
671 {
672 return Status::OK;
673 }
674
ChangeState(FilterState state)675 void Filter::ChangeState(FilterState state)
676 {
677 AutoLock lock(stateMutex_);
678 curState_ = state == FilterState::RELEASED ? state : (curState_ ==
679 FilterState::ERROR ? FilterState::ERROR : state);
680 MEDIA_LOG_I("%{public}s > %{public}d, target: %{public}d", name_.c_str(), curState_, state);
681 cond_.NotifyOne();
682 }
683
WaitAllState(FilterState state)684 Status Filter::WaitAllState(FilterState state)
685 {
686 AutoLock lock(stateMutex_);
687 MEDIA_LOG_I("%{public}s wait %{public}d", name_.c_str(), state);
688 if (curState_ != state) {
689 bool result = cond_.WaitFor(lock, 30000, [this, state] { // 30000 ms timeout
690 return curState_ == state || (state != FilterState::RELEASED && curState_ == FilterState::ERROR);
691 });
692 if (!result) {
693 SetErrCode(Status::ERROR_TIMED_OUT);
694 return Status::ERROR_TIMED_OUT;
695 }
696 if (curState_ != state) {
697 MEDIA_LOG_E("Filter(%{public}s) wait state %{public}d fail, curState %{public}d",
698 name_.c_str(), state, curState_);
699 return GetErrCode();
700 }
701 }
702
703 Status res = Status::OK;
704 for (auto iter : nextFiltersMap_) {
705 for (auto filter : iter.second) {
706 if (filter->WaitAllState(state) != Status::OK) {
707 res = filter->GetErrCode();
708 }
709 }
710 }
711 return res;
712 }
713
ReleaseOnMuted(bool isNeedRelease)714 Status Filter::ReleaseOnMuted(bool isNeedRelease)
715 {
716 if (filterTask_) {
717 MEDIA_LOG_I("ReleaseOnMuted Async");
718 filterTask_->SubmitJobOnce([this, isNeedRelease] {
719 Status ret = DoReleaseOnMuted(isNeedRelease);
720 SetErrCode(ret);
721 ChangeState(ret == Status::OK ? FilterState::CREATED : FilterState::ERROR);
722 if (ret == Status::OK) {
723 MEDIA_LOG_I("ReleaseOnMuted success");
724 }
725 });
726 } else {
727 Status ret = DoReleaseOnMuted(isNeedRelease);
728 SetErrCode(ret);
729 ChangeState(ret == Status::OK ? FilterState::CREATED : FilterState::ERROR);
730 FALSE_RETURN_V_MSG(ret == Status::OK, ret, "ReleaseOnMuted failed");
731 return ret;
732 }
733
734 return Status::OK;
735 }
736
ReInitAndStart()737 Status Filter::ReInitAndStart()
738 {
739 if (filterTask_) {
740 MEDIA_LOG_I("ReInitAndStart Async");
741 filterTask_->SubmitJobOnce([this] {
742 Status ret = DoReInitAndStart();
743 SetErrCode(ret);
744 ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
745 if (ret == Status::OK) {
746 MEDIA_LOG_I("DoReInitAndStart success");
747 }
748 });
749 } else {
750 Status ret = DoReInitAndStart();
751 SetErrCode(ret);
752 ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
753 FALSE_RETURN_V_MSG(ret == Status::OK, ret, "ReInitAndStart failed");
754 return ret;
755 }
756
757 return Status::OK;
758 }
759
SetErrCode(Status errCode)760 void Filter::SetErrCode(Status errCode)
761 {
762 errCode_ = errCode;
763 }
764
GetErrCode()765 Status Filter::GetErrCode()
766 {
767 return errCode_;
768 }
769
SetParameter(const std::shared_ptr<Meta> & meta)770 void Filter::SetParameter(const std::shared_ptr<Meta>& meta)
771 {
772 meta_ = meta;
773 }
774
GetParameter(std::shared_ptr<Meta> & meta)775 void Filter::GetParameter(std::shared_ptr<Meta>& meta)
776 {
777 meta = meta_;
778 }
779
LinkNext(const std::shared_ptr<Filter> &,StreamType)780 Status Filter::LinkNext(const std::shared_ptr<Filter>&, StreamType)
781 {
782 return Status::OK;
783 }
784
UpdateNext(const std::shared_ptr<Filter> &,StreamType)785 Status Filter::UpdateNext(const std::shared_ptr<Filter>&, StreamType)
786 {
787 return Status::OK;
788 }
789
UnLinkNext(const std::shared_ptr<Filter> &,StreamType)790 Status Filter::UnLinkNext(const std::shared_ptr<Filter>&, StreamType)
791 {
792 return Status::OK;
793 }
794
GetFilterType()795 FilterType Filter::GetFilterType()
796 {
797 return filterType_;
798 };
799
OnLinked(StreamType,const std::shared_ptr<Meta> &,const std::shared_ptr<FilterLinkCallback> &)800 Status Filter::OnLinked(StreamType, const std::shared_ptr<Meta>&, const std::shared_ptr<FilterLinkCallback>&)
801 {
802 return Status::OK;
803 };
804
OnUpdated(StreamType,const std::shared_ptr<Meta> &,const std::shared_ptr<FilterLinkCallback> &)805 Status Filter::OnUpdated(StreamType, const std::shared_ptr<Meta>&, const std::shared_ptr<FilterLinkCallback>&)
806 {
807 return Status::OK;
808 }
809
OnUnLinked(StreamType,const std::shared_ptr<FilterLinkCallback> &)810 Status Filter::OnUnLinked(StreamType, const std::shared_ptr<FilterLinkCallback>&)
811 {
812 return Status::OK;
813 }
814
815 } // namespace Pipeline
816 } // namespace Media
817 } // namespace OHOS
818