1 /*
2 * Copyright (c) 2024-2024 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, "VideoController 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,const std::shared_ptr<VideoJobRepository> & repository,const std::shared_ptr<DeferredVideoProcessor> & processor)71 DeferredVideoController::DeferredVideoController(const int32_t userId,
72 const std::shared_ptr<VideoJobRepository>& repository, const std::shared_ptr<DeferredVideoProcessor>& processor)
73 : userId_(userId), videoProcessor_(processor), repository_(repository)
74 {
75 DP_DEBUG_LOG("entered, userid: %{public}d", userId_);
76 }
77
~DeferredVideoController()78 DeferredVideoController::~DeferredVideoController()
79 {
80 DP_DEBUG_LOG("entered.");
81 StopSuspendLock();
82 }
83
Initialize()84 void DeferredVideoController::Initialize()
85 {
86 DP_DEBUG_LOG("entered.");
87 videoJobChangeListener_ = std::make_shared<VideoJobRepositoryListener>(weak_from_this());
88 DP_CHECK_ERROR_RETURN_LOG(repository_ == nullptr, "VideoJobRepository is nullptr.");
89
90 repository_->RegisterJobListener(videoJobChangeListener_);
91 videoStrategyCenter_ = CreateShared<VideoStrategyCenter>(userId_, repository_);
92 videoStrategyCenter_->Initialize();
93 videoStateChangeListener_ = std::make_shared<StateListener>(weak_from_this());
94 videoStrategyCenter_->RegisterStateChangeListener(videoStateChangeListener_);
95 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
96
97 videoProcessor_->Initialize();
98 }
99
HandleServiceDied()100 void DeferredVideoController::HandleServiceDied()
101 {
102 DP_DEBUG_LOG("entered.");
103 DP_CHECK_ERROR_RETURN_LOG(repository_ == nullptr, "VideoJobRepository is nullptr.");
104
105 if (repository_->GetRunningJobCounts() > 0) {
106 StopSuspendLock();
107 }
108 }
109
HandleSuccess(const DeferredVideoWorkPtr & work)110 void DeferredVideoController::HandleSuccess(const DeferredVideoWorkPtr& work)
111 {
112 DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "Video work is nullptr.");
113
114 auto videoId = work->GetDeferredVideoJob()->GetVideoId();
115 int dupFd = dup(work->GetDeferredVideoJob()->GetOutputFd()->GetFd());
116 auto out = sptr<IPCFileDescriptor>::MakeSptr(dupFd);
117 DP_INFO_LOG("DPS_VIDEO: HandleSuccess videoId: %{public}s, outFd: %{public}d", videoId.c_str(), out->GetFd());
118 HandleNormalSchedule(work);
119 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
120
121 videoProcessor_->OnProcessDone(userId_, videoId, out);
122 }
123
HandleError(const DeferredVideoWorkPtr & work,DpsError errorCode)124 void DeferredVideoController::HandleError(const DeferredVideoWorkPtr& work, DpsError errorCode)
125 {
126 DP_CHECK_ERROR_RETURN_LOG(work == nullptr, "Video work is nullptr.");
127
128 auto videoId = work->GetDeferredVideoJob()->GetVideoId();
129 DP_INFO_LOG("DPS_VIDEO: HandleError videoId: %{public}s", videoId.c_str());
130 if (errorCode == DpsError::DPS_ERROR_VIDEO_PROC_INTERRUPTED) {
131 StopSuspendLock();
132 }
133 HandleNormalSchedule(work);
134 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
135
136 videoProcessor_->OnError(userId_, videoId, errorCode);
137 }
138
OnVideoJobChanged(const DeferredVideoJobPtr & jobPtr)139 void DeferredVideoController::OnVideoJobChanged(const DeferredVideoJobPtr& jobPtr)
140 {
141 DP_INFO_LOG("DPS_VIDEO: videoId: %{public}s", jobPtr->GetVideoId().c_str());
142 TryDoSchedule();
143 }
144
OnSchedulerChanged(const ScheduleType & type,const ScheduleInfo & scheduleInfo)145 void DeferredVideoController::OnSchedulerChanged(const ScheduleType& type, const ScheduleInfo& scheduleInfo)
146 {
147 DP_INFO_LOG("DPS_VIDEO: Video isNeedStop: %{public}d, isCharging: %{public}d",
148 scheduleInfo.isNeedStop, scheduleInfo.isCharging);
149 if (scheduleInfo.isNeedStop) {
150 PauseRequests(type);
151 } else {
152 TryDoSchedule();
153 }
154 }
155
TryDoSchedule()156 void DeferredVideoController::TryDoSchedule()
157 {
158 DP_CHECK_ERROR_RETURN_LOG(repository_ == nullptr || repository_->GetRunningJobCounts() > 0, "Not schedule job.");
159
160 auto work = videoStrategyCenter_->GetWork();
161 DP_INFO_LOG("DPS_VIDEO: strategy get work: %{public}d", work != nullptr);
162 if (work == nullptr) {
163 StopSuspendLock();
164 return;
165 }
166
167 DP_CHECK_EXECUTE(work->IsSuspend(), StartSuspendLock());
168 PostProcess(work);
169 }
170
PauseRequests(const ScheduleType & type)171 void DeferredVideoController::PauseRequests(const ScheduleType& type)
172 {
173 DP_DEBUG_LOG("entered.");
174 DP_CHECK_ERROR_RETURN_LOG(repository_ == nullptr, "VideoJobRepository is nullptr.");
175
176 DP_CHECK_RETURN(repository_->GetRunningJobCounts() <= 0);
177 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
178
179 videoProcessor_->PauseRequest(type);
180 }
181
PostProcess(const DeferredVideoWorkPtr & work)182 void DeferredVideoController::PostProcess(const DeferredVideoWorkPtr& work)
183 {
184 DP_DEBUG_LOG("entered");
185 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
186
187 videoProcessor_->PostProcess(work);
188 }
189
SetDefaultExecutionMode()190 void DeferredVideoController::SetDefaultExecutionMode()
191 {
192 DP_DEBUG_LOG("entered");
193 DP_CHECK_ERROR_RETURN_LOG(videoProcessor_ == nullptr, "DeferredVideoProcessor is nullptr.");
194
195 videoProcessor_->SetDefaultExecutionMode();
196 }
197
StartSuspendLock()198 void DeferredVideoController::StartSuspendLock()
199 {
200 DP_CHECK_RETURN(normalTimeId_ != INVALID_TIMEID);
201 uint32_t processTime = static_cast<uint32_t>(
202 std::min(videoStrategyCenter_->GetAvailableTime(), ONCE_PROCESS_TIME));
203 normalTimeId_ = DpsTimer::GetInstance().StartTimer([&]() {OnTimerOut();}, processTime);
204 DPSProwerManager::GetInstance().SetAutoSuspend(false, processTime + DELAY_TIME);
205 DP_INFO_LOG("DpsTimer start: normal schedule timeId: %{public}u, processTime: %{public}u.",
206 normalTimeId_, processTime);
207 }
208
StopSuspendLock()209 void DeferredVideoController::StopSuspendLock()
210 {
211 DP_CHECK_RETURN(normalTimeId_ == INVALID_TIMEID);
212 DPSProwerManager::GetInstance().SetAutoSuspend(true);
213 DP_INFO_LOG("DpsTimer stop: normal schedule timeId: %{public}d.", normalTimeId_);
214 DpsTimer::GetInstance().StopTimer(normalTimeId_);
215 }
216
HandleNormalSchedule(const DeferredVideoWorkPtr & work)217 void DeferredVideoController::HandleNormalSchedule(const DeferredVideoWorkPtr& work)
218 {
219 DP_CHECK_RETURN(!work->IsSuspend());
220
221 DP_INFO_LOG("DPS_VIDEO: HandleNormalSchedule videoId: %{public}s",
222 work->GetDeferredVideoJob()->GetVideoId().c_str());
223 auto usedTime = static_cast<int32_t>(work->GetExecutionTime());
224 videoStrategyCenter_->UpdateAvailableTime(false, usedTime);
225 }
226
OnTimerOut()227 void DeferredVideoController::OnTimerOut()
228 {
229 DP_INFO_LOG("DpsTimer end: normal schedule time out timeId: %{public}u", normalTimeId_);
230 normalTimeId_ = INVALID_TIMEID;
231 videoStrategyCenter_->UpdateSingleTime(false);
232 PauseRequests(NORMAL_TIME_STATE);
233 }
234 } // namespace DeferredProcessing
235 } // namespace CameraStandard
236 } // namespace OHOS