• 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.h"
17 #include <map>
18 #include <unordered_set>
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "engine_factory_repo.h"
22 #include "player_server_state.h"
23 #include "media_dfx.h"
24 #include "ipc_skeleton.h"
25 #include "av_common.h"
26 
27 namespace {
28     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "PlayerServer"};
29 #ifdef SUPPORT_VIDEO
30     constexpr uint32_t VIDEO_MAX_NUMBER = 13; // max video player
31 #endif
32     constexpr int32_t MAX_SUBTITLE_TRACK_NUN = 8;
33 }
34 
35 namespace OHOS {
36 namespace Media {
37 const std::string START_TAG = "PlayerCreate->Start";
38 const std::string STOP_TAG = "PlayerStop->Destroy";
39 static const std::unordered_map<int32_t, std::string> STATUS_TO_STATUS_DESCRIPTION_TABLE = {
40     {PLAYER_STATE_ERROR, "PLAYER_STATE_ERROR"},
41     {PLAYER_IDLE, "PLAYER_IDLE"},
42     {PLAYER_INITIALIZED, "PLAYER_INITIALIZED"},
43     {PLAYER_PREPARING, "PLAYER_PREPARING"},
44     {PLAYER_PREPARED, "PLAYER_PREPARED"},
45     {PLAYER_STARTED, "PLAYER_STARTED"},
46     {PLAYER_PAUSED, "PLAYER_PAUSED"},
47     {PLAYER_STOPPED, "PLAYER_STOPPED"},
48     {PLAYER_PLAYBACK_COMPLETE, "PLAYER_PLAYBACK_COMPLETE"},
49 };
50 #ifdef SUPPORT_VIDEO
51 class VideoPlayerManager : public NoCopyable {
52 public:
53     static VideoPlayerManager &GetInstance();
54     int32_t RegisterVideoPlayer(PlayerServer *player);
55     void UnRegisterVideoPlayer(PlayerServer *player);
56 private:
57     VideoPlayerManager() = default;
58     ~VideoPlayerManager() = default;
59     std::unordered_set<PlayerServer *> videoPlayerList;
60     std::mutex mutex_;
61 };
62 
GetInstance()63 VideoPlayerManager &VideoPlayerManager::GetInstance()
64 {
65     static VideoPlayerManager instance;
66     return instance;
67 }
68 
RegisterVideoPlayer(PlayerServer * player)69 int32_t VideoPlayerManager::RegisterVideoPlayer(PlayerServer *player)
70 {
71     std::lock_guard<std::mutex> lock(mutex_);
72     if (videoPlayerList.find(player) != videoPlayerList.end()) {
73         return MSERR_OK;
74     }
75     CHECK_AND_RETURN_RET_LOG(videoPlayerList.size() < VIDEO_MAX_NUMBER, MSERR_DATA_SOURCE_OBTAIN_MEM_ERROR,
76         "failed to start VideoPlayer");
77     videoPlayerList.insert(player);
78     return MSERR_OK;
79 }
80 
UnRegisterVideoPlayer(PlayerServer * player)81 void VideoPlayerManager::UnRegisterVideoPlayer(PlayerServer *player)
82 {
83     std::lock_guard<std::mutex> lock(mutex_);
84     if (videoPlayerList.erase(player) == 0) {
85         MEDIA_LOGI("0x%{public}06" PRIXPTR " Not in videoPlayer list", FAKE_POINTER(player));
86     }
87 }
88 #endif
Create()89 std::shared_ptr<IPlayerService> PlayerServer::Create()
90 {
91     std::shared_ptr<PlayerServer> server = std::make_shared<PlayerServer>();
92     CHECK_AND_RETURN_RET_LOG(server != nullptr, nullptr, "failed to new PlayerServer");
93 
94     (void)server->Init();
95     return server;
96 }
97 
PlayerServer()98 PlayerServer::PlayerServer()
99 {
100     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
101 }
102 
~PlayerServer()103 PlayerServer::~PlayerServer()
104 {
105     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
106 #ifdef SUPPORT_VIDEO
107     VideoPlayerManager::GetInstance().UnRegisterVideoPlayer(this);
108 #endif
109 }
110 
Init()111 int32_t PlayerServer::Init()
112 {
113     MediaTrace trace("PlayerServer::Init");
114 
115     idleState_ = std::make_shared<IdleState>(*this);
116     initializedState_ = std::make_shared<InitializedState>(*this);
117     preparingState_ = std::make_shared<PreparingState>(*this);
118     preparedState_ = std::make_shared<PreparedState>(*this);
119     playingState_ = std::make_shared<PlayingState>(*this);
120     pausedState_ = std::make_shared<PausedState>(*this);
121     stoppedState_ = std::make_shared<StoppedState>(*this);
122     playbackCompletedState_ = std::make_shared<PlaybackCompletedState>(*this);
123     appTokenId_ = IPCSkeleton::GetCallingTokenID();
124     appUid_ = IPCSkeleton::GetCallingUid();
125     appPid_ = IPCSkeleton::GetCallingPid();
126     MEDIA_LOGD("Get app uid: %{public}d, app pid: %{public}d, app tokenId: %{public}u", appUid_, appPid_, appTokenId_);
127 
128     PlayerServerStateMachine::Init(idleState_);
129     return MSERR_OK;
130 }
131 
SetSource(const std::string & url)132 int32_t PlayerServer::SetSource(const std::string &url)
133 {
134     std::lock_guard<std::mutex> lock(mutex_);
135     MediaTrace trace("PlayerServer::SetSource url");
136     MEDIA_LOGW("KPI-TRACE: PlayerServer SetSource in(url)");
137     config_.url = url;
138     int32_t ret = InitPlayEngine(url);
139     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetSource Failed!");
140     return ret;
141 }
142 
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)143 int32_t PlayerServer::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
144 {
145     std::lock_guard<std::mutex> lock(mutex_);
146     MediaTrace trace("PlayerServer::SetSource dataSrc");
147     CHECK_AND_RETURN_RET_LOG(dataSrc != nullptr, MSERR_INVALID_VAL, "data source is nullptr");
148     MEDIA_LOGW("KPI-TRACE: PlayerServer SetSource in(dataSrc)");
149     dataSrc_ = dataSrc;
150     std::string url = "media data source";
151     config_.url = url;
152     int32_t ret = InitPlayEngine(url);
153     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "InitPlayEngine Failed!");
154     int64_t size = 0;
155     (void)dataSrc_->GetSize(size);
156     if (size == -1) {
157         config_.looping = false;
158         config_.speedMode = SPEED_FORWARD_1_00_X;
159         isLiveStream_ = true;
160     }
161     return ret;
162 }
163 
SetSource(int32_t fd,int64_t offset,int64_t size)164 int32_t PlayerServer::SetSource(int32_t fd, int64_t offset, int64_t size)
165 {
166     std::lock_guard<std::mutex> lock(mutex_);
167     MediaTrace trace("PlayerServer::SetSource fd");
168     MEDIA_LOGW("KPI-TRACE: PlayerServer SetSource in(fd)");
169     int32_t ret;
170     if (uriHelper_ != nullptr) {
171         ret = InitPlayEngine(uriHelper_->FormattedUri());
172         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetSource Failed!");
173     } else {
174         auto uriHelper = std::make_unique<UriHelper>(fd, offset, size);
175         CHECK_AND_RETURN_RET_LOG(uriHelper->AccessCheck(UriHelper::URI_READ),
176             MSERR_INVALID_VAL, "Failed to read the fd");
177         ret = InitPlayEngine(uriHelper->FormattedUri());
178         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetSource Failed!");
179         uriHelper_ = std::move(uriHelper);
180     }
181     config_.url = "file descriptor source";
182 
183     return ret;
184 }
185 
InitPlayEngine(const std::string & url)186 int32_t PlayerServer::InitPlayEngine(const std::string &url)
187 {
188     if (lastOpStatus_ != PLAYER_IDLE) {
189         MEDIA_LOGE("current state is: %{public}s, not support SetSource", GetStatusDescription(lastOpStatus_).c_str());
190         return MSERR_INVALID_OPERATION;
191     }
192 
193     int32_t ret = taskMgr_.Init();
194     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "task mgr init failed");
195     MEDIA_LOGD("current url is : %{public}s", url.c_str());
196     auto engineFactory = EngineFactoryRepo::Instance().GetEngineFactory(IEngineFactory::Scene::SCENE_PLAYBACK, url);
197     CHECK_AND_RETURN_RET_LOG(engineFactory != nullptr, MSERR_CREATE_PLAYER_ENGINE_FAILED,
198         "failed to get engine factory");
199     playerEngine_ = engineFactory->CreatePlayerEngine(appUid_, appPid_, appTokenId_);
200     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_CREATE_PLAYER_ENGINE_FAILED,
201         "failed to create player engine");
202 
203     if (dataSrc_ == nullptr) {
204         ret = playerEngine_->SetSource(url);
205     } else {
206         ret = playerEngine_->SetSource(dataSrc_);
207     }
208     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetSource Failed!");
209 
210     std::shared_ptr<IPlayerEngineObs> obs = shared_from_this();
211     ret = playerEngine_->SetObs(obs);
212     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetObs Failed!");
213 
214     lastOpStatus_ = PLAYER_INITIALIZED;
215     ChangeState(initializedState_);
216 
217     Format format;
218     OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_INITIALIZED, format);
219     return MSERR_OK;
220 }
221 
AddSubSource(const std::string & url)222 int32_t PlayerServer::AddSubSource(const std::string &url)
223 {
224     std::lock_guard<std::mutex> lock(mutex_);
225     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
226 
227     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
228         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
229         MEDIA_LOGE("Can not add sub source, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
230         return MSERR_INVALID_OPERATION;
231     }
232 
233     if (subtitleTrackNum_ >= MAX_SUBTITLE_TRACK_NUN) {
234         MEDIA_LOGE("Can not add sub source, subtitle track num is %{public}u, exceed the max num", subtitleTrackNum_);
235         return MSERR_INVALID_OPERATION;
236     }
237 
238     MEDIA_LOGD("PlayerServer AddSubSource in(url)");
239     auto task = std::make_shared<TaskHandler<void>>([this, url]() {
240         MediaTrace::TraceBegin("PlayerServer::AddSubSource", FAKE_POINTER(this));
241         (void)playerEngine_->AddSubSource(url);
242     });
243     (void)taskMgr_.LaunchTask(task, PlayerServerTaskType::STATE_CHANGE, "subsource");
244 
245     return MSERR_OK;
246 }
247 
AddSubSource(int32_t fd,int64_t offset,int64_t size)248 int32_t PlayerServer::AddSubSource(int32_t fd, int64_t offset, int64_t size)
249 {
250     std::lock_guard<std::mutex> lock(mutex_);
251     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
252 
253     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
254         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
255         MEDIA_LOGE("Can not add sub source, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
256         return MSERR_INVALID_OPERATION;
257     }
258 
259     if (subtitleTrackNum_ >= MAX_SUBTITLE_TRACK_NUN) {
260         MEDIA_LOGE("Can not add sub source, subtitle track num is %{public}u, exceed the max num", subtitleTrackNum_);
261         return MSERR_INVALID_OPERATION;
262     }
263 
264     auto uriHelper = std::make_shared<UriHelper>(fd, offset, size);
265     CHECK_AND_RETURN_RET_LOG(uriHelper->AccessCheck(UriHelper::URI_READ), MSERR_INVALID_VAL, "Failed to read the fd");
266 
267     MEDIA_LOGD("PlayerServer AddSubSource in(fd)");
268     auto task = std::make_shared<TaskHandler<void>>([this, uriHelper]() {
269         MediaTrace::TraceBegin("PlayerServer::AddSubSource", FAKE_POINTER(this));
270         (void)playerEngine_->AddSubSource(uriHelper->FormattedUri());
271         subUriHelpers_.emplace_back(uriHelper);
272     });
273     (void)taskMgr_.LaunchTask(task, PlayerServerTaskType::STATE_CHANGE, "subsource");
274 
275     return MSERR_OK;
276 }
277 
Prepare()278 int32_t PlayerServer::Prepare()
279 {
280     std::lock_guard<std::mutex> lock(mutex_);
281     MEDIA_LOGD("KPI-TRACE: PlayerServer Prepare in");
282 
283     if (lastOpStatus_ == PLAYER_INITIALIZED || lastOpStatus_ == PLAYER_STOPPED) {
284         return OnPrepare(false);
285     } else {
286         MEDIA_LOGE("Can not Prepare, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
287         return MSERR_INVALID_OPERATION;
288     }
289 }
290 
PrepareAsync()291 int32_t PlayerServer::PrepareAsync()
292 {
293     std::lock_guard<std::mutex> lock(mutex_);
294     MEDIA_LOGD("KPI-TRACE: PlayerServer PrepareAsync in");
295 
296     if (lastOpStatus_ == PLAYER_INITIALIZED || lastOpStatus_ == PLAYER_STOPPED) {
297         return OnPrepare(false);
298     } else {
299         MEDIA_LOGE("Can not Prepare, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
300         return MSERR_INVALID_OPERATION;
301     }
302 }
303 
OnPrepare(bool sync)304 int32_t PlayerServer::OnPrepare(bool sync)
305 {
306     MEDIA_LOGD("KPI-TRACE: PlayerServer OnPrepare in");
307     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
308     int32_t ret = MSERR_OK;
309 
310     lastOpStatus_ = PLAYER_PREPARED;
311 
312     auto preparedTask = std::make_shared<TaskHandler<int32_t>>([this]() {
313         MediaTrace::TraceBegin("PlayerServer::PrepareAsync", FAKE_POINTER(this));
314 #ifdef SUPPORT_VIDEO
315         if (surface_ != nullptr) {
316             int32_t res = playerEngine_->SetVideoSurface(surface_);
317             CHECK_AND_RETURN_RET_LOG(res == MSERR_OK,
318                 static_cast<int32_t>(MSERR_INVALID_OPERATION), "Engine SetVideoSurface Failed!");
319         }
320 #endif
321         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
322         return currState->Prepare();
323     });
324 
325     ret = taskMgr_.LaunchTask(preparedTask, PlayerServerTaskType::STATE_CHANGE, "prepare");
326     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Prepare launch task failed");
327 
328     if (sync) {
329         (void)preparedTask->GetResult(); // wait HandlePrpare
330     }
331     MEDIA_LOGD("KPI-TRACE: PlayerServer OnPrepare out");
332     return MSERR_OK;
333 }
334 
HandlePrepare()335 int32_t PlayerServer::HandlePrepare()
336 {
337     int32_t ret = playerEngine_->PrepareAsync();
338     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Server Prepare Failed!");
339 
340     if (config_.leftVolume < 1.0f) {
341         (void)playerEngine_->SetVolume(config_.leftVolume, config_.rightVolume);
342     }
343     if (config_.looping) {
344         (void)playerEngine_->SetLooping(config_.looping);
345     }
346     if (config_.speedMode != SPEED_FORWARD_1_00_X) {
347         MediaTrace::TraceBegin("PlayerServer::SetPlaybackSpeed", FAKE_POINTER(this));
348         auto rateTask = std::make_shared<TaskHandler<void>>([this]() {
349             int ret = playerEngine_->SetPlaybackSpeed(config_.speedMode);
350             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Engine SetPlaybackSpeed Failed!");
351         });
352         auto cancelTask = std::make_shared<TaskHandler<void>>([this]() {
353             MEDIA_LOGI("Interrupted speed action");
354             taskMgr_.MarkTaskDone("interrupted speed done");
355         });
356 
357         (void)taskMgr_.SpeedTask(rateTask, cancelTask, "prepare-speed", config_.speedMode);
358     }
359 
360     if (config_.effectMode != OHOS::AudioStandard::AudioEffectMode::EFFECT_DEFAULT) {
361         MediaTrace::TraceBegin("PlayerServer::SetAudioEffectMode", FAKE_POINTER(this));
362         auto effectTask = std::make_shared<TaskHandler<void>>([this]() {
363             int ret = playerEngine_->SetAudioEffectMode(config_.effectMode);
364             taskMgr_.MarkTaskDone("SetAudioEffectMode done");
365             CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Engine SetAudioEffectMode Failed!");
366         });
367         (void)taskMgr_.LaunchTask(effectTask, PlayerServerTaskType::STATE_CHANGE, "SetAudioEffectMode", nullptr);
368     }
369 
370     return MSERR_OK;
371 }
372 
Play()373 int32_t PlayerServer::Play()
374 {
375     std::lock_guard<std::mutex> lock(mutex_);
376     MEDIA_LOGD("PlayerServer Play in");
377     if (lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE ||
378         lastOpStatus_ == PLAYER_PAUSED) {
379         return OnPlay();
380     } else {
381         MEDIA_LOGE("Can not Play, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
382         return MSERR_INVALID_OPERATION;
383     }
384 }
385 
OnPlay()386 int32_t PlayerServer::OnPlay()
387 {
388     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
389     if (lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE && dataSrc_ != nullptr) {
390         int64_t size = 0;
391         (void)dataSrc_->GetSize(size);
392         if (size == -1) {
393             MEDIA_LOGE("Can not play in complete status, it is live-stream");
394             OnErrorMessage(MSERR_EXT_API9_UNSUPPORT_CAPABILITY, "Can not play in complete status, it is live-stream");
395             return MSERR_INVALID_OPERATION;
396         }
397     }
398 
399     auto playingTask = std::make_shared<TaskHandler<void>>([this]() {
400         MediaTrace::TraceBegin("PlayerServer::Play", FAKE_POINTER(this));
401         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
402         (void)currState->Play();
403     });
404     MEDIA_LOGD("PlayerServer OnPlay in");
405     int ret = taskMgr_.LaunchTask(playingTask, PlayerServerTaskType::STATE_CHANGE, "play");
406     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Play failed");
407 
408     lastOpStatus_ = PLAYER_STARTED;
409     return MSERR_OK;
410 }
411 
HandlePlay()412 int32_t PlayerServer::HandlePlay()
413 {
414     int32_t ret = playerEngine_->Play();
415     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine Play Failed!");
416 
417     return MSERR_OK;
418 }
419 
BackGroundChangeState(PlayerStates state,bool isBackGroundCb)420 int32_t PlayerServer::BackGroundChangeState(PlayerStates state, bool isBackGroundCb)
421 {
422     backgroundState_ = state;
423     isBackgroundCb_ = isBackGroundCb;
424     if (state == PLAYER_PAUSED) {
425         isBackgroundChanged_ = true;
426         return PlayerServer::Pause();
427     } else if (state == PLAYER_STARTED) {
428         isBackgroundChanged_ = true;
429         return PlayerServer::Play();
430     }
431     return MSERR_INVALID_OPERATION;
432 }
433 
Pause()434 int32_t PlayerServer::Pause()
435 {
436     std::lock_guard<std::mutex> lock(mutex_);
437     MEDIA_LOGI("PlayerServer Pause in");
438 
439     if (lastOpStatus_ == PLAYER_STARTED) {
440         return OnPause();
441     } else {
442         MEDIA_LOGE("Can not Pause, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
443         return MSERR_INVALID_OPERATION;
444     }
445 }
446 
OnPause()447 int32_t PlayerServer::OnPause()
448 {
449     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
450     MEDIA_LOGI("PlayerServer OnPause in");
451 
452     auto pauseTask = std::make_shared<TaskHandler<void>>([this]() {
453         MediaTrace::TraceBegin("PlayerServer::Pause", FAKE_POINTER(this));
454         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
455         (void)currState->Pause();
456     });
457 
458     int ret = taskMgr_.LaunchTask(pauseTask, PlayerServerTaskType::STATE_CHANGE, "pause");
459     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Pause failed");
460 
461     lastOpStatus_ = PLAYER_PAUSED;
462     return MSERR_OK;
463 }
464 
HandlePause()465 int32_t PlayerServer::HandlePause()
466 {
467     int32_t ret = playerEngine_->Pause();
468     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine Pause Failed!");
469 
470     return MSERR_OK;
471 }
472 
Stop()473 int32_t PlayerServer::Stop()
474 {
475     std::lock_guard<std::mutex> lock(mutex_);
476 
477     if (lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
478         lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE || lastOpStatus_ == PLAYER_PAUSED) {
479         MediaTrace::TraceBegin("PlayerServer::Stop", FAKE_POINTER(this));
480         return OnStop(false);
481     } else {
482         MEDIA_LOGE("Can not Stop, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
483         return MSERR_INVALID_OPERATION;
484     }
485 }
486 
OnStop(bool sync)487 int32_t PlayerServer::OnStop(bool sync)
488 {
489     MEDIA_LOGD("PlayerServer OnStop in");
490     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
491     taskMgr_.ClearAllTask();
492 
493     auto stopTask = std::make_shared<TaskHandler<void>>([this]() {
494         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
495         (void)currState->Stop();
496     });
497 
498     (void)taskMgr_.LaunchTask(stopTask, PlayerServerTaskType::STATE_CHANGE, "stop");
499     if (sync) {
500         (void)stopTask->GetResult(); // wait HandleStop
501     }
502     lastOpStatus_ = PLAYER_STOPPED;
503     MEDIA_LOGD("PlayerServer OnStop out");
504     return MSERR_OK;
505 }
506 
HandleStop()507 int32_t PlayerServer::HandleStop()
508 {
509     int32_t ret = playerEngine_->Stop();
510     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine Stop Failed!");
511 
512     return MSERR_OK;
513 }
514 
Reset()515 int32_t PlayerServer::Reset()
516 {
517     std::lock_guard<std::mutex> lock(mutex_);
518     MediaTrace trace("PlayerServer::Reset");
519     if (lastOpStatus_ == PLAYER_IDLE) {
520         MEDIA_LOGE("Can not Reset, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
521         return MSERR_INVALID_OPERATION;
522     }
523     return OnReset();
524 }
525 
OnReset()526 int32_t PlayerServer::OnReset()
527 {
528     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
529     if (lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
530         lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE || lastOpStatus_ == PLAYER_PAUSED) {
531         disableStoppedCb_ = true;
532         (void)OnStop(true);
533     }
534 
535     taskMgr_.ClearAllTask();
536     auto idleTask = std::make_shared<TaskHandler<void>>([this]() {
537         ChangeState(idleState_);
538     });
539     (void)taskMgr_.LaunchTask(idleTask, PlayerServerTaskType::STATE_CHANGE, "reset");
540     (void)idleTask->GetResult();
541     (void)taskMgr_.Reset();
542     lastOpStatus_ = PLAYER_IDLE;
543     isLiveStream_ = false;
544     subtitleTrackNum_ = 0;
545 
546     return MSERR_OK;
547 }
548 
HandleReset()549 int32_t PlayerServer::HandleReset()
550 {
551     (void)playerEngine_->Reset();
552     playerEngine_ = nullptr;
553     dataSrc_ = nullptr;
554     config_.looping = false;
555     uriHelper_ = nullptr;
556     {
557         decltype(subUriHelpers_) temp;
558         temp.swap(subUriHelpers_);
559     }
560     lastErrMsg_.clear();
561     errorCbOnce_ = false;
562     disableStoppedCb_ = false;
563     disableNextSeekDone_ = false;
564     Format format;
565     OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_IDLE, format);
566     return MSERR_OK;
567 }
568 
Release()569 int32_t PlayerServer::Release()
570 {
571     std::lock_guard<std::mutex> lock(mutex_);
572     MediaTrace trace("PlayerServer::Release");
573     {
574         std::lock_guard<std::mutex> lockCb(mutexCb_);
575         playerCb_ = nullptr;
576     }
577     MEDIA_LOGD("PlayerServer Release in");
578     if (lastOpStatus_ != PLAYER_IDLE) {
579         (void)OnReset();
580     }
581 #ifdef SUPPORT_VIDEO
582     if (surface_ != nullptr) {
583         surface_ = nullptr;
584     }
585 #endif
586     return MSERR_OK;
587 }
588 
SetVolume(float leftVolume,float rightVolume)589 int32_t PlayerServer::SetVolume(float leftVolume, float rightVolume)
590 {
591     std::lock_guard<std::mutex> lock(mutex_);
592     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
593         MEDIA_LOGE("Can not SetVolume, currentState is PLAYER_STATE_ERROR");
594         return MSERR_INVALID_OPERATION;
595     }
596     MEDIA_LOGD("PlayerServer SetVolume in leftVolume %{public}f %{public}f", leftVolume, rightVolume);
597     constexpr float maxVolume = 1.0f;
598     if ((leftVolume < 0) || (leftVolume > maxVolume) || (rightVolume < 0) || (rightVolume > maxVolume)) {
599         MEDIA_LOGE("SetVolume failed, the volume should be set to a value ranging from 0 to 5");
600         return MSERR_INVALID_OPERATION;
601     }
602 
603     config_.leftVolume = leftVolume;
604     config_.rightVolume = rightVolume;
605     if (IsEngineStarted()) {
606         auto task = std::make_shared<TaskHandler<void>>([this]() {
607             (void)playerEngine_->SetVolume(config_.leftVolume, config_.rightVolume);
608             taskMgr_.MarkTaskDone("volume done");
609         });
610         (void)taskMgr_.LaunchTask(task, PlayerServerTaskType::STATE_CHANGE, "volume");
611     } else {
612         MEDIA_LOGI("Waiting for the engine state is <prepared> to take effect");
613     }
614 
615     Format format;
616     (void)format.PutFloatValue(PlayerKeys::PLAYER_VOLUME_LEVEL, leftVolume);
617     OnInfoNoChangeStatus(INFO_TYPE_VOLUME_CHANGE, 0, format);
618     return MSERR_OK;
619 }
620 
IsEngineStarted()621 bool PlayerServer::IsEngineStarted()
622 {
623     if (playerEngine_ != nullptr) {
624         if (GetCurrState() == preparedState_ || GetCurrState() == playingState_ ||
625             GetCurrState() == pausedState_ || GetCurrState() == playbackCompletedState_) {
626             return true;
627         }
628     }
629     return false;
630 }
631 
IsValidSeekMode(PlayerSeekMode mode)632 bool PlayerServer::IsValidSeekMode(PlayerSeekMode mode)
633 {
634     switch (mode) {
635         case SEEK_PREVIOUS_SYNC:
636         case SEEK_NEXT_SYNC:
637         case SEEK_CLOSEST_SYNC:
638         case SEEK_CLOSEST:
639             break;
640         default:
641             MEDIA_LOGE("Unknown seek mode %{public}d", mode);
642             return false;
643     }
644     return true;
645 }
646 
Seek(int32_t mSeconds,PlayerSeekMode mode)647 int32_t PlayerServer::Seek(int32_t mSeconds, PlayerSeekMode mode)
648 {
649     std::lock_guard<std::mutex> lock(mutex_);
650     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
651 
652     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
653         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
654         MEDIA_LOGE("Can not Seek, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
655         return MSERR_INVALID_OPERATION;
656     }
657 
658     if (IsValidSeekMode(mode) != true) {
659         MEDIA_LOGE("Seek failed, inValid mode");
660         return MSERR_INVALID_VAL;
661     }
662 
663     if (isLiveStream_) {
664         MEDIA_LOGE("Can not Seek, it is live-stream");
665         OnErrorMessage(MSERR_EXT_API9_UNSUPPORT_CAPABILITY, "Can not Seek, it is live-stream");
666         return MSERR_INVALID_OPERATION;
667     }
668 
669     MEDIA_LOGD("seek position %{public}d, seek mode is %{public}d", mSeconds, mode);
670     mSeconds = std::max(0, mSeconds);
671 
672     auto seekTask = std::make_shared<TaskHandler<void>>([this, mSeconds, mode]() {
673         MediaTrace::TraceBegin("PlayerServer::Seek", FAKE_POINTER(this));
674         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
675         (void)currState->Seek(mSeconds, mode);
676     });
677 
678     auto cancelTask = std::make_shared<TaskHandler<void>>([this, mSeconds]() {
679         MEDIA_LOGI("Interrupted seek action");
680         Format format;
681         OnInfoNoChangeStatus(INFO_TYPE_SEEKDONE, mSeconds, format);
682         taskMgr_.MarkTaskDone("interrupted seek done");
683     });
684 
685     int32_t ret = taskMgr_.SeekTask(seekTask, cancelTask, "seek", mode, mSeconds);
686     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "Seek failed");
687 
688     return MSERR_OK;
689 }
690 
HandleSeek(int32_t mSeconds,PlayerSeekMode mode)691 int32_t PlayerServer::HandleSeek(int32_t mSeconds, PlayerSeekMode mode)
692 {
693     int32_t ret = playerEngine_->Seek(mSeconds, mode);
694     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine Seek Failed!");
695 
696     return MSERR_OK;
697 }
698 
GetCurrentTime(int32_t & currentTime)699 int32_t PlayerServer::GetCurrentTime(int32_t &currentTime)
700 {
701     // delete lock, cannot be called concurrently with Reset or Release
702     currentTime = -1;
703     if (lastOpStatus_ == PLAYER_IDLE || lastOpStatus_ == PLAYER_STATE_ERROR) {
704         MEDIA_LOGE("Can not GetCurrentTime, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
705         return MSERR_INVALID_OPERATION;
706     }
707     if (isLiveStream_ && dataSrc_ == nullptr) {
708         MEDIA_LOGD("It is live-stream");
709         return MSERR_OK;
710     }
711 
712     MEDIA_LOGD("PlayerServer GetCurrentTime in, currentState is %{public}s",
713         GetStatusDescription(lastOpStatus_).c_str());
714     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PAUSED &&
715         lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
716         currentTime = 0;
717         MEDIA_LOGD("get position at state: %{public}s, return 0", GetStatusDescription(lastOpStatus_).c_str());
718         return MSERR_OK;
719     }
720 
721     if (playerEngine_ != nullptr) {
722         int32_t ret = playerEngine_->GetCurrentTime(currentTime);
723         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine GetCurrentTime Failed!");
724     }
725     return MSERR_OK;
726 }
727 
GetVideoTrackInfo(std::vector<Format> & videoTrack)728 int32_t PlayerServer::GetVideoTrackInfo(std::vector<Format> &videoTrack)
729 {
730     std::lock_guard<std::mutex> lock(mutex_);
731     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
732 
733     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
734         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
735         MEDIA_LOGE("Can not get track info, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
736         return MSERR_INVALID_OPERATION;
737     }
738     MEDIA_LOGD("PlayerServer GetVideoTrackInfo in");
739     int32_t ret = playerEngine_->GetVideoTrackInfo(videoTrack);
740     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine GetVideoTrackInfo Failed!");
741     return MSERR_OK;
742 }
743 
GetAudioTrackInfo(std::vector<Format> & audioTrack)744 int32_t PlayerServer::GetAudioTrackInfo(std::vector<Format> &audioTrack)
745 {
746     std::lock_guard<std::mutex> lock(mutex_);
747     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
748 
749     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
750         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
751         MEDIA_LOGE("Can not get track info, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
752         return MSERR_INVALID_OPERATION;
753     }
754     MEDIA_LOGD("PlayerServer GetAudioTrackInfo in");
755     int32_t ret = playerEngine_->GetAudioTrackInfo(audioTrack);
756     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine GetAudioTrackInfo Failed!");
757     return MSERR_OK;
758 }
759 
GetSubtitleTrackInfo(std::vector<Format> & subtitleTrack)760 int32_t PlayerServer::GetSubtitleTrackInfo(std::vector<Format> &subtitleTrack)
761 {
762     std::lock_guard<std::mutex> lock(mutex_);
763     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
764 
765     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
766         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
767         MEDIA_LOGE("Can not get track info, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
768         return MSERR_INVALID_OPERATION;
769     }
770     MEDIA_LOGD("PlayerServer GetSubtitleTrackInfo in");
771     int32_t ret = playerEngine_->GetSubtitleTrackInfo(subtitleTrack);
772     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine GetSubtitleTrackInfo Failed!");
773     return MSERR_OK;
774 }
775 
GetVideoWidth()776 int32_t PlayerServer::GetVideoWidth()
777 {
778     std::lock_guard<std::mutex> lock(mutex_);
779     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
780 
781     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
782         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_STOPPED &&
783         lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
784         MEDIA_LOGE("Can not get track info, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
785         return MSERR_INVALID_OPERATION;
786     }
787     MEDIA_LOGD("PlayerServer GetVideoWidth in");
788     return playerEngine_->GetVideoWidth();
789 }
790 
GetVideoHeight()791 int32_t PlayerServer::GetVideoHeight()
792 {
793     std::lock_guard<std::mutex> lock(mutex_);
794     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
795 
796     if (lastOpStatus_ != PLAYER_PREPARED && lastOpStatus_ != PLAYER_PAUSED &&
797         lastOpStatus_ != PLAYER_STARTED && lastOpStatus_ != PLAYER_STOPPED &&
798         lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE) {
799         MEDIA_LOGE("Can not get track info, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
800         return MSERR_INVALID_OPERATION;
801     }
802     MEDIA_LOGD("PlayerServer GetVideoHeight in");
803     return playerEngine_->GetVideoHeight();
804 }
805 
GetDuration(int32_t & duration)806 int32_t PlayerServer::GetDuration(int32_t &duration)
807 {
808     // delete lock, cannot be called concurrently with Reset or Release
809     if (lastOpStatus_ == PLAYER_IDLE || lastOpStatus_ == PLAYER_INITIALIZED || lastOpStatus_ == PLAYER_STATE_ERROR) {
810         MEDIA_LOGE("Can not GetDuration, currentState is %{public}s", GetStatusDescription(lastOpStatus_).c_str());
811         return MSERR_INVALID_OPERATION;
812     }
813 
814     MEDIA_LOGD("PlayerServer GetDuration in");
815     duration = -1;
816     if (playerEngine_ != nullptr) {
817         int ret = playerEngine_->GetDuration(duration);
818         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine GetDuration Failed!");
819     }
820     MEDIA_LOGD("PlayerServer GetDuration %{public}d", duration);
821     return MSERR_OK;
822 }
823 
ClearConfigInfo()824 void PlayerServer::ClearConfigInfo()
825 {
826     std::lock_guard<std::mutex> lock(mutex_);
827 
828     config_.looping = false;
829     config_.leftVolume = INVALID_VALUE;
830     config_.rightVolume = INVALID_VALUE;
831     config_.speedMode = SPEED_FORWARD_1_00_X;
832     config_.url = "";
833 }
834 
SetPlaybackSpeed(PlaybackRateMode mode)835 int32_t PlayerServer::SetPlaybackSpeed(PlaybackRateMode mode)
836 {
837     std::lock_guard<std::mutex> lock(mutex_);
838 
839     if ((lastOpStatus_ != PLAYER_STARTED) && (lastOpStatus_ != PLAYER_PREPARED) &&
840         (lastOpStatus_ != PLAYER_PAUSED) && (lastOpStatus_ != PLAYER_PLAYBACK_COMPLETE)) {
841         MEDIA_LOGE("Can not SetPlaybackSpeed, currentState is %{public}s",
842             GetStatusDescription(lastOpStatus_).c_str());
843         return MSERR_INVALID_OPERATION;
844     }
845     MEDIA_LOGD("PlayerServer SetPlaybackSpeed in, mode %{public}d", mode);
846     if (isLiveStream_) {
847         MEDIA_LOGE("Can not SetPlaybackSpeed, it is live-stream");
848         OnErrorMessage(MSERR_EXT_API9_UNSUPPORT_CAPABILITY, "Can not SetPlaybackSpeed, it is live-stream");
849         return MSERR_INVALID_OPERATION;
850     }
851 
852     auto rateTask = std::make_shared<TaskHandler<void>>([this, mode]() {
853         MediaTrace::TraceBegin("PlayerServer::SetPlaybackSpeed", FAKE_POINTER(this));
854         auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
855         (void)currState->SetPlaybackSpeed(mode);
856     });
857 
858     auto cancelTask = std::make_shared<TaskHandler<void>>([this, mode]() {
859         MEDIA_LOGI("Interrupted speed action");
860         Format format;
861         OnInfoNoChangeStatus(INFO_TYPE_SPEEDDONE, mode, format);
862         taskMgr_.MarkTaskDone("interrupted speed done");
863     });
864 
865     int ret = taskMgr_.SpeedTask(rateTask, cancelTask, "speed", config_.speedMode);
866     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "SetPlaybackSpeed failed");
867 
868     return MSERR_OK;
869 }
870 
HandleSetPlaybackSpeed(PlaybackRateMode mode)871 int32_t PlayerServer::HandleSetPlaybackSpeed(PlaybackRateMode mode)
872 {
873     if (config_.speedMode == mode) {
874         MEDIA_LOGD("The speed mode is same, mode = %{public}d", mode);
875         Format format;
876         OnInfoNoChangeStatus(INFO_TYPE_SPEEDDONE, mode, format);
877         taskMgr_.MarkTaskDone("set speed mode is same");
878         MediaTrace::TraceEnd("PlayerServer::SetPlaybackSpeed", FAKE_POINTER(this));
879         return MSERR_OK;
880     }
881 
882     if (playerEngine_ != nullptr) {
883         int ret = playerEngine_->SetPlaybackSpeed(mode);
884         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine SetPlaybackSpeed Failed!");
885     }
886     config_.speedMode = mode;
887     return MSERR_OK;
888 }
889 
HandleEos()890 void PlayerServer::HandleEos()
891 {
892     if (config_.looping.load()) {
893         auto seekTask = std::make_shared<TaskHandler<void>>([this]() {
894             MediaTrace::TraceBegin("PlayerServer::Seek", FAKE_POINTER(this));
895             auto currState = std::static_pointer_cast<BaseState>(GetCurrState());
896             (void)currState->Seek(0, SEEK_PREVIOUS_SYNC);
897         });
898 
899         auto cancelTask = std::make_shared<TaskHandler<void>>([this]() {
900             MEDIA_LOGI("Interrupted seek action");
901             taskMgr_.MarkTaskDone("interrupted seek done");
902             disableNextSeekDone_ = false;
903         });
904 
905         disableNextSeekDone_ = true;
906         int32_t ret = taskMgr_.SeekTask(seekTask, cancelTask, "eos seek", SEEK_PREVIOUS_SYNC, 0);
907         CHECK_AND_RETURN_LOG(ret == MSERR_OK, "Seek failed");
908     }
909 }
910 
GetPlaybackSpeed(PlaybackRateMode & mode)911 int32_t PlayerServer::GetPlaybackSpeed(PlaybackRateMode &mode)
912 {
913     std::lock_guard<std::mutex> lock(mutex_);
914 
915     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
916         MEDIA_LOGE("Can not GetDuration, currentState is PLAYER_STATE_ERROR");
917         return MSERR_INVALID_OPERATION;
918     }
919     MEDIA_LOGD("PlayerServer GetPlaybackSpeed in");
920 
921     mode = config_.speedMode;
922     return MSERR_OK;
923 }
924 
SelectBitRate(uint32_t bitRate)925 int32_t PlayerServer::SelectBitRate(uint32_t bitRate)
926 {
927     std::unique_lock<std::mutex> lock(mutex_);
928     if (playerEngine_ != nullptr) {
929         int ret = playerEngine_->SelectBitRate(bitRate);
930         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "Engine SelectBitRate Failed!");
931     }
932     return MSERR_OK;
933 }
934 
935 #ifdef SUPPORT_VIDEO
SetVideoSurface(sptr<Surface> surface)936 int32_t PlayerServer::SetVideoSurface(sptr<Surface> surface)
937 {
938     std::lock_guard<std::mutex> lock(mutex_);
939     CHECK_AND_RETURN_RET_LOG(VideoPlayerManager::GetInstance().RegisterVideoPlayer(this) == MSERR_OK,
940         MSERR_DATA_SOURCE_OBTAIN_MEM_ERROR, "video player is no more than 13");
941     CHECK_AND_RETURN_RET_LOG(surface != nullptr, MSERR_INVALID_VAL, "surface is nullptr");
942 
943     if (lastOpStatus_ != PLAYER_INITIALIZED) {
944         MEDIA_LOGE("current state: %{public}s, can not SetVideoSurface", GetStatusDescription(lastOpStatus_).c_str());
945         return MSERR_INVALID_OPERATION;
946     }
947     MEDIA_LOGD("PlayerServer SetVideoSurface in");
948     surface_ = surface;
949     return MSERR_OK;
950 }
951 #endif
952 
IsPlaying()953 bool PlayerServer::IsPlaying()
954 {
955     std::lock_guard<std::mutex> lock(mutex_);
956     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
957         MEDIA_LOGE("Can not judge IsPlaying, currentState is PLAYER_STATE_ERROR");
958         return false;
959     }
960 
961     return lastOpStatus_ == PLAYER_STARTED;
962 }
963 
IsPrepared()964 bool PlayerServer::IsPrepared()
965 {
966     std::lock_guard<std::mutex> lock(mutex_);
967     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
968         MEDIA_LOGE("Can not judge IsPrepared, currentState is PLAYER_STATE_ERROR");
969         return false;
970     }
971 
972     return lastOpStatus_ == PLAYER_PREPARED;
973 }
974 
IsCompleted()975 bool PlayerServer::IsCompleted()
976 {
977     std::lock_guard<std::mutex> lock(mutex_);
978     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
979         MEDIA_LOGE("Can not judge IsCompleted, currentState is PLAYER_STATE_ERROR");
980         return false;
981     }
982 
983     return lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE;
984 }
985 
IsLooping()986 bool PlayerServer::IsLooping()
987 {
988     std::lock_guard<std::mutex> lock(mutex_);
989     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
990         MEDIA_LOGE("Can not judge IsLooping, currentState is PLAYER_STATE_ERROR");
991         return false;
992     }
993 
994     return config_.looping;
995 }
996 
SetLooping(bool loop)997 int32_t PlayerServer::SetLooping(bool loop)
998 {
999     std::lock_guard<std::mutex> lock(mutex_);
1000     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
1001         MEDIA_LOGE("Can not SetLooping, currentState is PLAYER_STATE_ERROR");
1002         return MSERR_INVALID_OPERATION;
1003     }
1004     MEDIA_LOGD("PlayerServer SetLooping in, loop %{public}d", loop);
1005 
1006     if (isLiveStream_) {
1007         MEDIA_LOGE("Can not SetLooping, it is live-stream");
1008         OnErrorMessage(MSERR_EXT_API9_UNSUPPORT_CAPABILITY, "Can not SetLooping, it is live-stream");
1009         return MSERR_INVALID_OPERATION;
1010     }
1011 
1012     if (lastOpStatus_ == PLAYER_IDLE || lastOpStatus_ == PLAYER_INITIALIZED || GetCurrState() == preparingState_) {
1013         MEDIA_LOGI("Waiting for the engine state is <prepared> to take effect");
1014         config_.looping = loop;
1015         return MSERR_OK;
1016     }
1017 
1018     if (playerEngine_ != nullptr) {
1019         int32_t ret = playerEngine_->SetLooping(loop);
1020         CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetLooping Failed!");
1021     }
1022     config_.looping = loop;
1023     return MSERR_OK;
1024 }
1025 
SetParameter(const Format & param)1026 int32_t PlayerServer::SetParameter(const Format &param)
1027 {
1028     std::lock_guard<std::mutex> lock(mutex_);
1029     if (lastOpStatus_ == PLAYER_STATE_ERROR) {
1030         MEDIA_LOGE("Can not SetParameter, currentState is PLAYER_STATE_ERROR");
1031         return MSERR_INVALID_OPERATION;
1032     }
1033 
1034     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
1035 
1036     if (param.ContainKey(PlayerKeys::AUDIO_EFFECT_MODE)) {
1037         int32_t effectMode = OHOS::AudioStandard::AudioEffectMode::EFFECT_DEFAULT;
1038         CHECK_AND_RETURN_RET(param.GetIntValue(PlayerKeys::AUDIO_EFFECT_MODE, effectMode), MSERR_INVALID_VAL);
1039         return SetAudioEffectMode(effectMode);
1040     }
1041 
1042     int32_t ret = playerEngine_->SetParameter(param);
1043     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_OPERATION, "SetParameter Failed!");
1044 
1045     if (param.ContainKey(PlayerKeys::CONTENT_TYPE)) {
1046         config_.effectMode = OHOS::AudioStandard::AudioEffectMode::EFFECT_DEFAULT;
1047     }
1048 
1049     return MSERR_OK;
1050 }
1051 
SetAudioEffectMode(const int32_t effectMode)1052 int32_t PlayerServer::SetAudioEffectMode(const int32_t effectMode)
1053 {
1054     MEDIA_LOGD("SetAudioEffectMode in");
1055     CHECK_AND_RETURN_RET(lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
1056         lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE || lastOpStatus_ == PLAYER_PAUSED, MSERR_INVALID_OPERATION);
1057     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
1058     CHECK_AND_RETURN_RET_LOG(effectMode <= OHOS::AudioStandard::AudioEffectMode::EFFECT_DEFAULT &&
1059         effectMode >= OHOS::AudioStandard::AudioEffectMode::EFFECT_NONE, MSERR_INVALID_VAL,
1060         "Invalid effectMode parameter");
1061     int32_t ret = playerEngine_->SetAudioEffectMode(effectMode);
1062     if (ret == MSERR_OK) {
1063         config_.effectMode = effectMode;
1064     }
1065 
1066     return ret;
1067 }
1068 
SetPlayerCallback(const std::shared_ptr<PlayerCallback> & callback)1069 int32_t PlayerServer::SetPlayerCallback(const std::shared_ptr<PlayerCallback> &callback)
1070 {
1071     std::lock_guard<std::mutex> lock(mutex_);
1072     CHECK_AND_RETURN_RET_LOG(callback != nullptr, MSERR_INVALID_VAL, "callback is nullptr");
1073 
1074     if (lastOpStatus_ != PLAYER_IDLE && lastOpStatus_ != PLAYER_INITIALIZED) {
1075         MEDIA_LOGE("Can not SetPlayerCallback, currentState is %{public}s",
1076             GetStatusDescription(lastOpStatus_).c_str());
1077         return MSERR_INVALID_OPERATION;
1078     }
1079 
1080     {
1081         std::lock_guard<std::mutex> lockCb(mutexCb_);
1082         playerCb_ = callback;
1083     }
1084     return MSERR_OK;
1085 }
1086 
SelectTrack(int32_t index)1087 int32_t PlayerServer::SelectTrack(int32_t index)
1088 {
1089     std::lock_guard<std::mutex> lock(mutex_);
1090 
1091     CHECK_AND_RETURN_RET_LOG(lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
1092         lastOpStatus_ == PLAYER_PAUSED || lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE, MSERR_INVALID_OPERATION,
1093         "invalid state %{public}s", GetStatusDescription(lastOpStatus_).c_str());
1094     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
1095 
1096     auto task = std::make_shared<TaskHandler<void>>([this, index]() {
1097         MediaTrace::TraceBegin("PlayerServer::track", FAKE_POINTER(this));
1098         CHECK_AND_RETURN(IsEngineStarted());
1099         int32_t ret = playerEngine_->SelectTrack(index);
1100         CHECK_AND_RETURN_LOG(ret == MSERR_OK, "failed to SelectTrack");
1101     });
1102     int32_t ret = taskMgr_.LaunchTask(task, PlayerServerTaskType::STATE_CHANGE, "SelectTrack");
1103     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "SelectTrack launch task failed");
1104 
1105     return MSERR_OK;
1106 }
1107 
DeselectTrack(int32_t index)1108 int32_t PlayerServer::DeselectTrack(int32_t index)
1109 {
1110     std::lock_guard<std::mutex> lock(mutex_);
1111     CHECK_AND_RETURN_RET_LOG(lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
1112         lastOpStatus_ == PLAYER_PAUSED || lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE, MSERR_INVALID_OPERATION,
1113         "invalid state %{public}s", GetStatusDescription(lastOpStatus_).c_str());
1114     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
1115 
1116     auto task = std::make_shared<TaskHandler<void>>([this, index]() {
1117         MediaTrace::TraceBegin("PlayerServer::track", FAKE_POINTER(this));
1118         CHECK_AND_RETURN(IsEngineStarted());
1119         int32_t ret = playerEngine_->DeselectTrack(index);
1120         CHECK_AND_RETURN_LOG(ret == MSERR_OK, "failed to DeselectTrack");
1121     });
1122     int32_t ret = taskMgr_.LaunchTask(task, PlayerServerTaskType::STATE_CHANGE, "DeselectTrack");
1123     CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "DeselectTrack launch task failed");
1124 
1125     return MSERR_OK;
1126 }
1127 
GetCurrentTrack(int32_t trackType,int32_t & index)1128 int32_t PlayerServer::GetCurrentTrack(int32_t trackType, int32_t &index)
1129 {
1130     CHECK_AND_RETURN_RET_LOG(trackType >= MediaType::MEDIA_TYPE_AUD && trackType <= MediaType::MEDIA_TYPE_SUBTITLE,
1131         MSERR_INVALID_VAL, "Invalid trackType %{public}d", trackType);
1132 
1133     std::lock_guard<std::mutex> lock(mutex_);
1134     CHECK_AND_RETURN_RET_LOG(lastOpStatus_ == PLAYER_PREPARED || lastOpStatus_ == PLAYER_STARTED ||
1135         lastOpStatus_ == PLAYER_PAUSED || lastOpStatus_ == PLAYER_PLAYBACK_COMPLETE, MSERR_INVALID_OPERATION,
1136         "invalid state %{public}s", GetStatusDescription(lastOpStatus_).c_str());
1137     CHECK_AND_RETURN_RET_LOG(playerEngine_ != nullptr, MSERR_NO_MEMORY, "playerEngine_ is nullptr");
1138 
1139     return playerEngine_->GetCurrentTrack(trackType, index);
1140 }
1141 
FormatToString(std::string & dumpString,std::vector<Format> & videoTrack)1142 void PlayerServer::FormatToString(std::string &dumpString, std::vector<Format> &videoTrack)
1143 {
1144     for (auto iter = videoTrack.begin(); iter != videoTrack.end(); iter++) {
1145         dumpString += iter->Stringify();
1146         dumpString += '\n';
1147     }
1148 }
1149 
DumpInfo(int32_t fd)1150 int32_t PlayerServer::DumpInfo(int32_t fd)
1151 {
1152     std::string dumpString;
1153     if (playerEngine_ == nullptr) {
1154         dumpString +=
1155             "The engine is not created, note: engine can't be created until set source.\n";
1156     }
1157     dumpString += "PlayerServer current state is: " + GetStatusDescription(lastOpStatus_) + "\n";
1158     if (lastErrMsg_.size() != 0) {
1159         dumpString += "PlayerServer last error is: " + lastErrMsg_ + "\n";
1160     }
1161     dumpString += "PlayerServer url is: " + config_.url + "\n";
1162     dumpString += "PlayerServer play back speed is: " + std::to_string(config_.speedMode) + "\n";
1163     std::string loopflag = config_.looping ? "" : "not ";
1164     dumpString += "PlayerServer current " + loopflag + "in looping mode\n";
1165     dumpString += "PlayerServer left volume and right volume is: " +
1166         std::to_string(config_.leftVolume) + ", " + std::to_string(config_.rightVolume) + "\n";
1167     dumpString += "PlayerServer audio effect mode is: " + std::to_string(config_.effectMode) + "\n";
1168     if (playerEngine_ != nullptr) {
1169         dumpString += "PlayerServer enable HEBC: " + std::to_string(playerEngine_->GetHEBCMode()) + "\n";
1170     }
1171 
1172     std::vector<Format> videoTrack;
1173     (void)GetVideoTrackInfo(videoTrack);
1174     dumpString += "PlayerServer video tracks info: \n";
1175     FormatToString(dumpString, videoTrack);
1176 
1177     std::vector<Format> audioTrack;
1178     (void)GetAudioTrackInfo(audioTrack);
1179     dumpString += "PlayerServer audio tracks info: \n";
1180     FormatToString(dumpString, audioTrack);
1181 
1182     int32_t currentTime = -1;
1183     (void)GetCurrentTime(currentTime);
1184     dumpString += "PlayerServer current time is: " + std::to_string(currentTime) + "\n";
1185     write(fd, dumpString.c_str(), dumpString.size());
1186 
1187     return MSERR_OK;
1188 }
1189 
OnError(PlayerErrorType errorType,int32_t errorCode)1190 void PlayerServer::OnError(PlayerErrorType errorType, int32_t errorCode)
1191 {
1192     (void)errorType;
1193     auto errorMsg = MSErrorToExtErrorString(static_cast<MediaServiceErrCode>(errorCode));
1194     return OnErrorMessage(errorCode, errorMsg);
1195 }
1196 
OnErrorMessage(int32_t errorCode,const std::string & errorMsg)1197 void PlayerServer::OnErrorMessage(int32_t errorCode, const std::string &errorMsg)
1198 {
1199     std::lock_guard<std::mutex> lockCb(mutexCb_);
1200     lastErrMsg_ = errorMsg;
1201     FaultEventWrite(lastErrMsg_, "Player");
1202     if (playerCb_ != nullptr && !errorCbOnce_) {
1203         playerCb_->OnError(errorCode, errorMsg);
1204         errorCbOnce_ = true;
1205     }
1206 }
1207 
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)1208 void PlayerServer::OnInfo(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
1209 {
1210     std::lock_guard<std::mutex> lockCb(mutexCb_);
1211     // notify info
1212     int32_t ret = HandleMessage(type, extra, infoBody);
1213     if (type == INFO_TYPE_IS_LIVE_STREAM) {
1214         isLiveStream_ = true;
1215     } else if (type == INFO_TYPE_TRACK_NUM_UPDATE) {
1216         subtitleTrackNum_ = static_cast<uint32_t>(extra);
1217         return;
1218     }
1219 
1220     if (type == INFO_TYPE_DEFAULTTRACK || type == INFO_TYPE_TRACK_DONE || type == INFO_TYPE_ADD_SUBTITLE_DONE) {
1221         return;
1222     }
1223 
1224     if (playerCb_ != nullptr && ret == MSERR_OK) {
1225         if (isBackgroundChanged_ && type == INFO_TYPE_STATE_CHANGE && extra == backgroundState_) {
1226             MEDIA_LOGI("Background change state to %{public}d, Status reporting %{public}d", extra, isBackgroundCb_);
1227             if (isBackgroundCb_) {
1228                 Format newInfo = infoBody;
1229                 newInfo.PutIntValue(PlayerKeys::PLAYER_STATE_CHANGED_REASON, StateChangeReason::BACKGROUND);
1230                 playerCb_->OnInfo(type, extra, newInfo);
1231                 isBackgroundCb_ = false;
1232             }
1233             isBackgroundChanged_ = false;
1234         } else {
1235             playerCb_->OnInfo(type, extra, infoBody);
1236         }
1237     }
1238 }
1239 
OnInfoNoChangeStatus(PlayerOnInfoType type,int32_t extra,const Format & infoBody)1240 void PlayerServer::OnInfoNoChangeStatus(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
1241 {
1242     std::lock_guard<std::mutex> lockCb(mutexCb_);
1243 
1244     if (playerCb_ != nullptr) {
1245         playerCb_->OnInfo(type, extra, infoBody);
1246     }
1247 }
1248 
GetStatusDescription(int32_t status)1249 const std::string &PlayerServer::GetStatusDescription(int32_t status)
1250 {
1251     static const std::string ILLEGAL_STATE = "PLAYER_STATUS_ILLEGAL";
1252     if (status < PLAYER_STATE_ERROR || status > PLAYER_PLAYBACK_COMPLETE) {
1253         return ILLEGAL_STATE;
1254     }
1255 
1256     return STATUS_TO_STATUS_DESCRIPTION_TABLE.find(status)->second;
1257 }
1258 
GetStateName() const1259 std::string PlayerServerState::GetStateName() const
1260 {
1261     return name_;
1262 }
1263 
HandleMessage(PlayerOnInfoType type,int32_t extra,const Format & infoBody)1264 int32_t PlayerServerStateMachine::HandleMessage(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
1265 {
1266     if (currState_ != nullptr) {
1267         return currState_->OnMessageReceived(type, extra, infoBody);
1268     }
1269     return MSERR_OK;
1270 }
1271 
Init(const std::shared_ptr<PlayerServerState> & state)1272 void PlayerServerStateMachine::Init(const std::shared_ptr<PlayerServerState> &state)
1273 {
1274     currState_ = state;
1275 }
1276 
ChangeState(const std::shared_ptr<PlayerServerState> & state)1277 void PlayerServerStateMachine::ChangeState(const std::shared_ptr<PlayerServerState> &state)
1278 {
1279     {
1280         // Resolve the deadlock between reset and state callback
1281         std::unique_lock<std::recursive_mutex> lock(recMutex_);
1282 
1283         if (state == nullptr || (state == currState_)) {
1284             return;
1285         }
1286 
1287         if (currState_) {
1288             MEDIA_LOGD("exit state %{public}s", currState_->name_.c_str());
1289             currState_->StateExit();
1290         }
1291 
1292         MEDIA_LOGI("change state to %{public}s", state->name_.c_str());
1293         currState_ = state;
1294     }
1295     state->StateEnter();
1296 }
1297 
GetCurrState()1298 std::shared_ptr<PlayerServerState> PlayerServerStateMachine::GetCurrState()
1299 {
1300     std::unique_lock<std::recursive_mutex> lock(recMutex_);
1301     return currState_;
1302 }
1303 } // namespace Media
1304 } // namespace OHOS
1305