• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "player_server_task_mgr.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "qos.h"
20 
21 using namespace OHOS::QOS;
22 
23 namespace {
24     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_PLAYER, "PlayerServerTaskMgr" };
25 }
26 
27 namespace OHOS {
28 namespace Media {
PlayerServerTaskMgr()29 PlayerServerTaskMgr::PlayerServerTaskMgr()
30 {
31     MEDIA_LOGD("enter ctor, instance: 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
32 }
33 
~PlayerServerTaskMgr()34 PlayerServerTaskMgr::~PlayerServerTaskMgr()
35 {
36     MEDIA_LOGD("enter dtor, instance: 0x%{public}06" PRIXPTR "", FAKE_POINTER(this));
37     (void)Reset();
38 }
39 
Init()40 int32_t PlayerServerTaskMgr::Init()
41 {
42     std::unique_lock<std::mutex> lock(mutex_);
43     if (isInited_) {
44         return MSERR_OK;
45     }
46 
47     taskThread_ = std::make_unique<TaskQueue>("PlayerEngine");
48     int32_t ret = taskThread_->Start();
49     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "task thread start failed");
50     isInited_ = true;
51 
52     return MSERR_OK;
53 }
54 
EnqueueTask(const std::shared_ptr<ITaskHandler> & task,PlayerServerTaskType type,const std::string & taskName)55 int32_t PlayerServerTaskMgr::EnqueueTask(const std::shared_ptr<ITaskHandler> &task, PlayerServerTaskType type,
56     const std::string &taskName)
57 {
58     (void)taskThread_->EnqueueTask(task);
59     currTwoPhaseTask_ = task;
60     currTwoPhaseType_ = type;
61     currTwoPhaseTaskName_ = taskName;
62     if (taskName.compare("volume") == 0) {
63         MEDIA_LOGD("0x%{public}06" PRIXPTR " task[%{public}s] start",
64             FAKE_POINTER(this), currTwoPhaseTaskName_.c_str());
65     } else {
66         MEDIA_LOGI("0x%{public}06" PRIXPTR " task[%{public}s] start",
67             FAKE_POINTER(this), currTwoPhaseTaskName_.c_str());
68     }
69 
70     return MSERR_OK;
71 }
72 
LaunchTask(const std::shared_ptr<ITaskHandler> & task,PlayerServerTaskType type,const std::string & taskName,const std::shared_ptr<ITaskHandler> & cancelTask)73 int32_t PlayerServerTaskMgr::LaunchTask(const std::shared_ptr<ITaskHandler> &task, PlayerServerTaskType type,
74     const std::string &taskName, const std::shared_ptr<ITaskHandler> &cancelTask)
75 {
76     std::unique_lock<std::mutex> lock(mutex_);
77     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
78 
79     if (taskName == "play" || taskName == "prepare") {
80         taskThread_->SetQos(QosLevel::QOS_USER_INTERACTIVE);
81     } else if (taskName == "pause") {
82         taskThread_->ResetQos();
83     }
84 
85     (void)cancelTask;
86     if (type != PlayerServerTaskType::STATE_CHANGE && type != PlayerServerTaskType::LIGHT_TASK) {
87         return MSERR_OK;
88     }
89     if (currTwoPhaseTask_ == nullptr) {
90         return EnqueueTask(task, type, taskName);
91     }
92 
93     if (taskName.compare("volume") == 0) {
94         MEDIA_LOGD("0x%{public}06" PRIXPTR " task[%{public}s] is in processing, the new task[%{public}s]",
95             FAKE_POINTER(this), currTwoPhaseTaskName_.c_str(), taskName.c_str());
96     } else {
97         MEDIA_LOGI("0x%{public}06" PRIXPTR " task[%{public}s] is in processing, the new task[%{public}s]",
98             FAKE_POINTER(this), currTwoPhaseTaskName_.c_str(), taskName.c_str());
99     }
100 
101     pendingTwoPhaseTasks_.push_back({ type, task, nullptr, taskName });
102     return MSERR_OK;
103 }
104 
SpeedTask(const std::shared_ptr<ITaskHandler> & task,const std::shared_ptr<ITaskHandler> & cancelTask,const std::string & taskName,int32_t speedMode)105 int32_t PlayerServerTaskMgr::SpeedTask(const std::shared_ptr<ITaskHandler> &task,
106     const std::shared_ptr<ITaskHandler> &cancelTask,
107     const std::string &taskName, int32_t speedMode)
108 {
109     std::unique_lock<std::mutex> lock(mutex_);
110     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
111     if (currTwoPhaseTask_ == nullptr) {
112         EnqueueTask(task, PlayerServerTaskType::RATE_CHANGE, taskName);
113         MEDIA_LOGI("speed task[%{public}s] start", currTwoPhaseTaskName_.c_str());
114         return MSERR_OK;
115     }
116     MEDIA_LOGI("current task[%{public}s] is in processing, new task[%{public}s] wait",
117         currTwoPhaseTaskName_.c_str(), taskName.c_str());
118     for (auto &item : pendingTwoPhaseTasks_) {
119         if (item.type == PlayerServerTaskType::RATE_CHANGE &&
120             item.speedMode_ != speedMode) {
121             item.type = PlayerServerTaskType::CANCEL_TASK;
122             MEDIA_LOGI("replace old speed task");
123         }
124     }
125 
126     pendingTwoPhaseTasks_.push_back({
127         PlayerServerTaskType::RATE_CHANGE, task, cancelTask, taskName, -1, -1, speedMode
128     });
129     return MSERR_OK;
130 }
131 
EnqueueSeekTask(const std::shared_ptr<ITaskHandler> & task,PlayerServerTaskType type,const std::string & taskName,int32_t seekMode,int32_t seekTime)132 int32_t PlayerServerTaskMgr::EnqueueSeekTask(const std::shared_ptr<ITaskHandler> &task,
133     PlayerServerTaskType type, const std::string &taskName, int32_t seekMode, int32_t seekTime)
134 {
135     (void)taskThread_->EnqueueTask(task);
136     currTwoPhaseTask_ = task;
137     currTwoPhaseType_ = type;
138     currTwoPhaseTaskName_ = taskName;
139     currentSeekMode_ = seekMode;
140     currentSeekTime_ = seekTime;
141     MEDIA_LOGI("0x%{public}06" PRIXPTR " seek task[%{public}s] start",
142         FAKE_POINTER(this), currTwoPhaseTaskName_.c_str());
143     return MSERR_OK;
144 }
145 
SeekTask(const std::shared_ptr<ITaskHandler> & task,const std::shared_ptr<ITaskHandler> & cancelTask,const std::string & taskName,int32_t seekMode,int32_t seekTime)146 int32_t PlayerServerTaskMgr::SeekTask(const std::shared_ptr<ITaskHandler> &task,
147     const std::shared_ptr<ITaskHandler> &cancelTask,
148     const std::string &taskName, int32_t seekMode, int32_t seekTime)
149 {
150     std::unique_lock<std::mutex> lock(mutex_);
151     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
152 
153     if (currTwoPhaseTask_ == nullptr) {
154         return EnqueueSeekTask(task, PlayerServerTaskType::SEEKING, taskName, seekMode, seekTime);
155     }
156     MEDIA_LOGI("current task[%{public}s] is in processing, new task[%{public}s] wait",
157         currTwoPhaseTaskName_.c_str(), taskName.c_str());
158     for (auto &item : pendingTwoPhaseTasks_) {
159         if (item.type == PlayerServerTaskType::SEEKING) {
160             item.type = PlayerServerTaskType::CANCEL_TASK;
161             MEDIA_LOGI("replace old seek task");
162         }
163     }
164 
165     if (currentSeekMode_ == seekMode && currentSeekTime_ == seekTime) {
166         pendingTwoPhaseTasks_.push_back({
167             PlayerServerTaskType::CANCEL_TASK, task, cancelTask, taskName, seekMode, seekTime
168         });
169         MEDIA_LOGI("abandon old seek task");
170     } else {
171         pendingTwoPhaseTasks_.push_back({
172             PlayerServerTaskType::SEEKING, task, cancelTask, taskName, seekMode, seekTime
173         });
174     }
175     return MSERR_OK;
176 }
177 
FreezeTask(const std::shared_ptr<ITaskHandler> & task,const std::shared_ptr<ITaskHandler> & cancelTask,const std::string & taskName)178 int32_t PlayerServerTaskMgr::FreezeTask(const std::shared_ptr<ITaskHandler> &task,
179     const std::shared_ptr<ITaskHandler> &cancelTask, const std::string &taskName)
180 {
181     std::unique_lock<std::mutex> lock(mutex_);
182     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
183 
184     if (currTwoPhaseTask_ == nullptr) {
185         return EnqueueTask(task, PlayerServerTaskType::FREEZE_TASK, taskName);
186     }
187     MEDIA_LOGI("current task[%{public}s] is in processing, new task[%{public}s] wait",
188         currTwoPhaseTaskName_.c_str(), taskName.c_str());
189 
190     pendingTwoPhaseTasks_.push_back({
191         PlayerServerTaskType::FREEZE_TASK, task, cancelTask, taskName
192     });
193     return MSERR_OK;
194 }
195 
UnFreezeTask(const std::shared_ptr<ITaskHandler> & task,const std::shared_ptr<ITaskHandler> & cancelTask,const std::string & taskName)196 int32_t PlayerServerTaskMgr::UnFreezeTask(const std::shared_ptr<ITaskHandler> &task,
197     const std::shared_ptr<ITaskHandler> &cancelTask, const std::string &taskName)
198 {
199     std::unique_lock<std::mutex> lock(mutex_);
200     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
201 
202     if (currTwoPhaseTask_ == nullptr) {
203         return EnqueueTask(task, PlayerServerTaskType::UNFREEZE_TASK, taskName);
204     }
205     MEDIA_LOGI("current task[%{public}s] is in processing, new task[%{public}s] wait",
206         currTwoPhaseTaskName_.c_str(), taskName.c_str());
207 
208     pendingTwoPhaseTasks_.push_back({
209         PlayerServerTaskType::UNFREEZE_TASK, task, cancelTask, taskName
210     });
211     return MSERR_OK;
212 }
213 
SeekContinousTask(const std::shared_ptr<ITaskHandler> & task,const std::string & taskName)214 int32_t PlayerServerTaskMgr::SeekContinousTask(const std::shared_ptr<ITaskHandler> &task, const std::string &taskName)
215 {
216     std::unique_lock<std::mutex> lock(mutex_);
217     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
218     if (currTwoPhaseTask_ == nullptr) {
219         return EnqueueTask(task, PlayerServerTaskType::SEEKING, taskName);
220     }
221     MEDIA_LOGI("0x%{public}06" PRIXPTR " task[%{public}s] is in processing, the new task[%{public}s]",
222         FAKE_POINTER(this), currTwoPhaseTaskName_.c_str(), taskName.c_str());
223     pendingTwoPhaseTasks_.push_back({ PlayerServerTaskType::SEEKING, task, nullptr, taskName });
224     return MSERR_OK;
225 }
226 
SetVideoSurfaeTask(const std::shared_ptr<ITaskHandler> & task,const std::string & taskName)227 int32_t PlayerServerTaskMgr::SetVideoSurfaeTask(const std::shared_ptr<ITaskHandler> &task, const std::string &taskName)
228 {
229     std::unique_lock<std::mutex> lock(mutex_);
230     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
231     if (currTwoPhaseTask_ == nullptr) {
232         return EnqueueTask(task, PlayerServerTaskType::SET_VIDEO_SURFACE, taskName);
233     }
234     MEDIA_LOGI("0x%{public}06" PRIXPTR " task[%{public}s] is in processing, the new task[%{public}s]",
235         FAKE_POINTER(this), currTwoPhaseTaskName_.c_str(), taskName.c_str());
236     pendingTwoPhaseTasks_.push_back({ PlayerServerTaskType::SET_VIDEO_SURFACE, task, nullptr, taskName });
237     return MSERR_OK;
238 }
239 
MarkTaskDone(const std::string & taskName)240 int32_t PlayerServerTaskMgr::MarkTaskDone(const std::string &taskName)
241 {
242     std::unique_lock<std::mutex> lock(mutex_);
243     CHECK_AND_RETURN_RET_LOG(isInited_, MSERR_INVALID_OPERATION, "not init");
244 
245     if (taskName.compare("volume done") == 0) {
246         MEDIA_LOGD("0x%{public}06" PRIXPTR " task[%{public}s] end", FAKE_POINTER(this), taskName.c_str());
247     } else {
248         MEDIA_LOGI("0x%{public}06" PRIXPTR " task[%{public}s] end", FAKE_POINTER(this), taskName.c_str());
249     }
250     currTwoPhaseTask_ = nullptr;
251     currTwoPhaseType_ = PlayerServerTaskType::BUTT;
252     currTwoPhaseTaskName_ = "None";
253     currentSeekMode_ = -1;
254     currentSeekTime_ = -1;
255 
256     if (!pendingTwoPhaseTasks_.empty()) {
257         auto item = pendingTwoPhaseTasks_.front();
258         pendingTwoPhaseTasks_.pop_front();
259         currTwoPhaseType_ = item.type;
260         if (item.type == PlayerServerTaskType::CANCEL_TASK) {
261             currTwoPhaseTask_ = item.cancelTask;
262         } else {
263             currTwoPhaseTask_ = item.task;
264         }
265         currTwoPhaseTaskName_ = item.taskName;
266         if (item.type == PlayerServerTaskType::SEEKING) {
267             currentSeekMode_ = item.seekMode_;
268             currentSeekTime_ = item.seekTime_;
269         }
270 
271         CHECK_AND_RETURN_RET_LOG(currTwoPhaseTask_ != nullptr, MSERR_OK, "task is nullptr");
272         int32_t ret = taskThread_->EnqueueTask(currTwoPhaseTask_);
273         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret,
274             "execute the stack top task failed, type: %{public}hhu", item.type);
275 
276         MEDIA_LOGD("0x%{public}06" PRIXPTR " task[%{public}s] start",
277             FAKE_POINTER(this), currTwoPhaseTaskName_.c_str());
278     }
279     return MSERR_OK;
280 }
281 
ClearAllTask()282 void PlayerServerTaskMgr::ClearAllTask()
283 {
284     MEDIA_LOGD("enter");
285     std::unique_lock<std::mutex> lock(mutex_);
286     CHECK_AND_RETURN_LOG(isInited_, "not init");
287 
288     currTwoPhaseTask_ = nullptr;
289     currTwoPhaseType_ = PlayerServerTaskType::BUTT;
290     pendingTwoPhaseTasks_.clear();
291 
292     auto dummyTask = std::make_shared<TaskHandler<void>>([this]() {
293         MEDIA_LOGD("0x%{public}06" PRIXPTR " execute dummy task...", FAKE_POINTER(this));
294     });
295     (void)taskThread_->EnqueueTask(dummyTask, true, 0);
296     MEDIA_LOGD("exit");
297 }
298 
Reset()299 int32_t PlayerServerTaskMgr::Reset()
300 {
301     MEDIA_LOGD("enter");
302     std::unique_lock<std::mutex> lock(mutex_);
303 
304     currTwoPhaseTask_ = nullptr;
305     currTwoPhaseType_ = PlayerServerTaskType::BUTT;
306     pendingTwoPhaseTasks_.clear();
307     isInited_ = false;
308 
309     if (taskThread_ != nullptr) {
310         std::unique_ptr<TaskQueue> tmp;
311         std::swap(tmp, taskThread_);
312 
313         lock.unlock();
314         int32_t ret = tmp->Stop();
315         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "stop task thread failed");
316         lock.lock();
317     }
318 
319     MEDIA_LOGD("exit");
320     return MSERR_OK;
321 }
322 }
323 }