1 /*
2 * Copyright (c) 2023-2023 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 "deferred_video_controller.h"
17
18 #include "dp_power_manager.h"
19 #include "dp_timer.h"
20
21 namespace OHOS {
22 namespace CameraStandard {
23 namespace DeferredProcessing {
24 class DeferredVideoController::StateListener : public IVideoStateChangeListener {
25 public:
StateListener(const std::weak_ptr<DeferredVideoController> & controller)26 explicit StateListener(const std::weak_ptr<DeferredVideoController>& controller) : controller_(controller)
27 {
28 DP_DEBUG_LOG("entered.");
29 }
30
~StateListener()31 ~StateListener() override
32 {
33 DP_DEBUG_LOG("entered.");
34 }
35
OnSchedulerChanged(const ScheduleType & type,const ScheduleInfo & scheduleInfo)36 void OnSchedulerChanged(const ScheduleType& type, const ScheduleInfo& scheduleInfo) override
37 {
38 auto controller = controller_.lock();
39 DP_CHECK_ERROR_RETURN_LOG(controller == nullptr, "video controller is nullptr.");
40 controller->OnSchedulerChanged(type, scheduleInfo);
41 }
42
43 private:
44 std::weak_ptr<DeferredVideoController> controller_;
45 };
46
47 class DeferredVideoController::VideoJobRepositoryListener : public IVideoJobRepositoryListener {
48 public:
VideoJobRepositoryListener(const std::weak_ptr<DeferredVideoController> & controller)49 explicit VideoJobRepositoryListener(const std::weak_ptr<DeferredVideoController>& controller)
50 : controller_(controller)
51 {
52 DP_DEBUG_LOG("entered.");
53 }
54
~VideoJobRepositoryListener()55 ~VideoJobRepositoryListener()
56 {
57 DP_DEBUG_LOG("entered.");
58 }
59
OnVideoJobChanged(const DeferredVideoJobPtr & jobPtr)60 void OnVideoJobChanged(const DeferredVideoJobPtr& jobPtr) override
61 {
62 auto controller = controller_.lock();
63 DP_CHECK_ERROR_RETURN_LOG(controller == nullptr, "video controller is nullptr.");
64 controller->OnVideoJobChanged(jobPtr);
65 }
66
67 private:
68 std::weak_ptr<DeferredVideoController> controller_;
69 };
70
DeferredVideoController(const int32_t userId,std::shared_ptr<VideoJobRepository> repository,std::shared_ptr<DeferredVideoProcessor> processor)71 DeferredVideoController::DeferredVideoController(const int32_t userId, std::shared_ptr<VideoJobRepository> repository,
72 std::shared_ptr<DeferredVideoProcessor> processor)
73 : userId_(userId),
74 videoProcessor_(processor),
75 videoJobRepository_(repository)
76 {
77 DP_DEBUG_LOG("entered, userid: %{public}d", userId_);
78 }
79
~DeferredVideoController()80 DeferredVideoController::~DeferredVideoController()
81 {
82 DP_DEBUG_LOG("entered.");
83 videoProcessor_ = nullptr;
84 videoJobRepository_ = nullptr;
85 videoStrategyCenter_ = nullptr;
86 videoStateChangeListener_ = nullptr;
87 videoJobChangeListener_ = nullptr;
88 StopSuspendLock();
89 }
90
Initialize()91 void DeferredVideoController::Initialize()
92 {
93 DP_DEBUG_LOG("entered.");
94 videoJobChangeListener_ = std::make_shared<VideoJobRepositoryListener>(weak_from_this());
95 videoJobRepository_->RegisterJobListener(videoJobChangeListener_);
96 videoStrategyCenter_ = CreateShared<VideoStrategyCenter>(userId_, videoJobRepository_);
97
98 videoStrategyCenter_->Initialize();
99 videoStateChangeListener_ = std::make_shared<StateListener>(weak_from_this());
100 videoStrategyCenter_->RegisterStateChangeListener(videoStateChangeListener_);
101 }
102
HandleServiceDied()103 void DeferredVideoController::HandleServiceDied()
104 {
105 DP_DEBUG_LOG("entered.");
106 std::vector<std::string> errorTasks;
107 videoJobRepository_->GetRunningJobList(errorTasks);
108 if (!errorTasks.empty()) {
109 StopSuspendLock();
110 }
111 }
112
HandleSuccess(const int32_t userId,const DeferredVideoWorkPtr & work)113 void DeferredVideoController::HandleSuccess(const int32_t userId, const DeferredVideoWorkPtr& work)
114 {
115 auto videoId = work->GetDeferredVideoJob()->GetVideoId();
116 auto out = work->GetDeferredVideoJob()->GetOutputFd();
117 DP_INFO_LOG("handle success, videoId: %{public}s, outFd: %{public}d", videoId.c_str(), out->GetFd());
118 HandleNormalSchedule(work);
119 videoProcessor_->OnProcessDone(userId, videoId, out);
120 }
121
HandleError(const int32_t userId,const DeferredVideoWorkPtr & work,DpsError errorCode)122 void DeferredVideoController::HandleError(const int32_t userId, const DeferredVideoWorkPtr& work, DpsError errorCode)
123 {
124 auto videoId = work->GetDeferredVideoJob()->GetVideoId();
125 DP_INFO_LOG("handle error videoId: %{public}s", videoId.c_str());
126 if (errorCode == DpsError::DPS_ERROR_VIDEO_PROC_INTERRUPTED) {
127 StopSuspendLock();
128 }
129 HandleNormalSchedule(work);
130 videoProcessor_->OnError(userId, videoId, errorCode);
131 }
132
OnVideoJobChanged(const DeferredVideoJobPtr & jobPtr)133 void DeferredVideoController::OnVideoJobChanged(const DeferredVideoJobPtr& jobPtr)
134 {
135 DP_INFO_LOG("entered, videoId: %{public}s", jobPtr->GetVideoId().c_str());
136 TryDoSchedule();
137 }
138
OnSchedulerChanged(const ScheduleType & type,const ScheduleInfo & scheduleInfo)139 void DeferredVideoController::OnSchedulerChanged(const ScheduleType& type, const ScheduleInfo& scheduleInfo)
140 {
141 DP_INFO_LOG("video schedule isNeedStop: %{public}d, isCharging: %{public}d",
142 scheduleInfo.isNeedStop, scheduleInfo.isCharging);
143 if (scheduleInfo.isNeedStop) {
144 PauseRequests(type);
145 } else {
146 TryDoSchedule();
147 }
148 }
149
TryDoSchedule()150 void DeferredVideoController::TryDoSchedule()
151 {
152 DP_DEBUG_LOG("entered.");
153 std::lock_guard<std::recursive_mutex> lock(mutex_);
154 auto work = videoStrategyCenter_->GetWork();
155 DP_INFO_LOG("strategy get work: %{public}d", work != nullptr);
156 if (work == nullptr) {
157 StopSuspendLock();
158 return;
159 }
160
161 DP_CHECK_EXECUTE(work->IsSuspend(), StartSuspendLock());
162 PostProcess(work);
163 }
164
PauseRequests(const ScheduleType & type)165 void DeferredVideoController::PauseRequests(const ScheduleType& type)
166 {
167 DP_CHECK_RETURN(videoJobRepository_->GetRunningJobCounts() == 0);
168 videoProcessor_->PauseRequest(type);
169 }
170
PostProcess(const DeferredVideoWorkPtr & work)171 void DeferredVideoController::PostProcess(const DeferredVideoWorkPtr& work)
172 {
173 DP_DEBUG_LOG("entered");
174 videoProcessor_->PostProcess(work);
175 }
176
SetDefaultExecutionMode()177 void DeferredVideoController::SetDefaultExecutionMode()
178 {
179 DP_DEBUG_LOG("entered");
180 videoProcessor_->SetDefaultExecutionMode();
181 }
182
StartSuspendLock()183 void DeferredVideoController::StartSuspendLock()
184 {
185 DP_CHECK_RETURN(normalTimeId_ != INVALID_TIMEID);
186 uint32_t processTime = static_cast<uint32_t>(
187 std::min(videoStrategyCenter_->GetAvailableTime(), ONCE_PROCESS_TIME));
188 normalTimeId_ = DpsTimer::GetInstance().StartTimer([&]() {OnTimerOut();}, processTime);
189 DPSProwerManager::GetInstance().SetAutoSuspend(false, processTime + DELAY_TIME);
190 DP_INFO_LOG("DpsTimer start: normal schedule timeId: %{public}d, processTime: %{public}d.",
191 static_cast<int32_t>(normalTimeId_), processTime);
192 }
193
StopSuspendLock()194 void DeferredVideoController::StopSuspendLock()
195 {
196 DPSProwerManager::GetInstance().SetAutoSuspend(true);
197 DP_CHECK_RETURN(normalTimeId_ == INVALID_TIMEID);
198 DP_INFO_LOG("DpsTimer stop: normal schedule timeId: %{public}d.", normalTimeId_);
199 DpsTimer::GetInstance().StopTimer(normalTimeId_);
200 }
201
HandleNormalSchedule(const DeferredVideoWorkPtr & work)202 void DeferredVideoController::HandleNormalSchedule(const DeferredVideoWorkPtr& work)
203 {
204 DP_CHECK_RETURN(!work->IsSuspend());
205
206 DP_DEBUG_LOG("handle normal schedule videoId: %{public}s", work->GetDeferredVideoJob()->GetVideoId().c_str());
207 auto usedTime = static_cast<int32_t>(work->GetExecutionTime());
208 videoStrategyCenter_->UpdateAvailableTime(false, usedTime);
209 }
210
OnTimerOut()211 void DeferredVideoController::OnTimerOut()
212 {
213 DP_INFO_LOG("DpsTimer executed: normal schedule time out.");
214 normalTimeId_ = INVALID_TIMEID;
215 videoStrategyCenter_->UpdateSingleTime(false);
216 PauseRequests(NORMAL_TIME_STATE);
217 }
218 } // namespace DeferredProcessing
219 } // namespace CameraStandard
220 } // namespace OHOS