1 /*
2  * Copyright (c) 2022-2022 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 #ifndef OHOS_LITE
16 #include "test_player.hpp"
17 
18 #include <iostream>
19 #include <thread>
20 #include <chrono>
21 #include <scene/player/standard/hiplayer_impl.h>
22 
23 #include "foundation/log.h"
24 #include "media_errors.h"
25 
26 using namespace OHOS::Media;
27 
28 namespace OHOS::Media::Test {
29 bool g_playFinished = false;
30 bool g_seekFinished = false;
31 
32 class PlayerCallbackImpl : public IPlayerEngineObs {
33 public:
SetPlayer(IPlayerEngine * player)34     void SetPlayer(IPlayerEngine* player)
35     {
36         player_ = player;
37     }
38 
OnError(PlayerErrorType errorType,int32_t errorCode)39     void OnError(PlayerErrorType errorType, int32_t errorCode) override
40     {
41         if (errorCode == MSERR_SEEK_FAILED) {
42             g_seekFinished = true;
43         }
44     }
OnInfo(PlayerOnInfoType type,int32_t extra,const Format & infoBody)45     void OnInfo(PlayerOnInfoType type, int32_t extra, const Format& infoBody) override
46     {
47         if (type == INFO_TYPE_EOS && !g_playFinished) {
48             player_->Seek(0, PlayerSeekMode::SEEK_PREVIOUS_SYNC);
49         }
50         if (type == INFO_TYPE_STATE_CHANGE && extra == PLAYER_PLAYBACK_COMPLETE) {
51             g_playFinished = true;
52         }
53         if (type == INFO_TYPE_STATE_CHANGE && extra == PLAYER_STATE_ERROR) {
54             g_playFinished = true;
55         }
56         if (type == INFO_TYPE_SEEKDONE) {
57             g_seekFinished = true;
58         }
59     }
60 private:
61     IPlayerEngine* player_ {nullptr};
62 };
63 std::shared_ptr<IPlayerEngineObs> gCallback = std::make_shared<PlayerCallbackImpl>();
64 
65 class TestPlayerImpl : public TestPlayer {
66 public:
TestPlayerImpl(std::unique_ptr<IPlayerEngine> player)67     explicit TestPlayerImpl(std::unique_ptr<IPlayerEngine> player) : player_(std::move(player)) {}
68     int32_t SetSource(const TestSource& source) override;
69     int32_t SetSingleLoop(bool loop) override;
70     bool IsPlaying() override;
71     int32_t Prepare() override;
72     int32_t Play() override;
73     int32_t Pause() override;
74     int32_t Stop() override;
75     int32_t Reset() override;
76     int32_t Release() override;
77     int32_t Seek(int64_t timeMs, PlayerSeekMode mode = PlayerSeekMode::SEEK_NEXT_SYNC) override;
78     int32_t GetCurrentTime(int64_t& currentMs) override;
79     int32_t GetDuration(int64_t& durationMs) override;
80     int32_t SetVolume(float leftVolume, float rightVolume) override;
81     int32_t GetAudioTrackInfo(std::vector<Format> &audioTrack) override;
82     int32_t GetVideoTrackInfo(std::vector<Format> &videoTrack) override;
83     int32_t SetPlaybackSpeed(PlaybackRateMode mode) override;
84     int32_t GetPlaybackSpeed(PlaybackRateMode &mode) override;
85 private:
86     std::unique_ptr<IPlayerEngine> player_;
87     std::atomic<PlayerStates> pipelineStates_ {PlayerStates::PLAYER_IDLE};
88 };
89 
CreateTestSource(const std::string & url,TestSourceType type,Plugin::Seekable seekable)90 TestSource TestSource::CreateTestSource(const std::string& url, TestSourceType type, Plugin::Seekable seekable)
91 {
92     switch (type) {
93         case TestSourceType::URI:
94             return TestSource(url);
95         case TestSourceType::STREAM:
96             return TestSource(url, seekable);
97     }
98     return TestSource("");
99 }
100 
Create()101 std::unique_ptr<TestPlayer> TestPlayer::Create()
102 {
103     auto player = std::make_unique<HiPlayerImpl>(0, 0);
104     player -> Init();
105     std::static_pointer_cast<PlayerCallbackImpl>(gCallback)->SetPlayer(player.get());
106     player->SetObs(gCallback);
107     g_playFinished = false;
108     return std::make_unique<TestPlayerImpl>(std::move(player));
109 }
110 
SetSource(const TestSource & source)111 int32_t TestPlayerImpl::SetSource(const TestSource& source)
112 {
113     int32_t ret = -1;
114     if (source.type_ == TestSourceType::URI) {
115         ret = player_->SetSource(source.url_);
116     } else if (source.type_ == TestSourceType::STREAM) {
117         auto src = std::make_shared<IMediaDataSourceImpl>(source.url_, source.seekable_);
118         ret = player_->SetSource(src);
119     }
120     if (ret == 0) {
121         pipelineStates_.store(PlayerStates::PLAYER_INITIALIZED);
122     }
123     return ret;
124 }
125 
SetSingleLoop(bool loop)126 int32_t TestPlayerImpl::SetSingleLoop(bool loop)
127 {
128     return player_->SetLooping(loop);
129 }
130 
IsPlaying()131 bool TestPlayerImpl::IsPlaying()
132 {
133     if (g_playFinished) {
134         pipelineStates_.store(PlayerStates::PLAYER_PLAYBACK_COMPLETE);
135     }
136     return !g_playFinished;
137 }
138 
Prepare()139 int32_t TestPlayerImpl::Prepare()
140 {
141     int32_t ret = player_->Prepare();
142     if (ret == 0) {
143         pipelineStates_.store(PlayerStates::PLAYER_PREPARED);
144     }
145     return ret;
146 }
147 
Play()148 int32_t TestPlayerImpl::Play()
149 {
150     if (pipelineStates_.load()  == PlayerStates::PLAYER_PREPARED ||
151         pipelineStates_.load()  == PlayerStates::PLAYER_PLAYBACK_COMPLETE ||
152         pipelineStates_.load()  == PlayerStates::PLAYER_PAUSED) {
153         g_playFinished = false;
154         int32_t ret = player_->Play();
155         if (ret == 0) {
156             pipelineStates_.store(PlayerStates::PLAYER_STARTED);
157         }
158         return ret;
159     }
160     return MSERR_INVALID_OPERATION;
161 }
162 
Pause()163 int32_t TestPlayerImpl::Pause()
164 {
165     if (pipelineStates_.load()  != PlayerStates::PLAYER_STARTED) {
166         return MSERR_INVALID_OPERATION;
167     }
168 
169     int32_t ret = player_->Pause();
170     if (ret == 0) {
171         pipelineStates_.store(PlayerStates::PLAYER_PAUSED);
172     }
173     return ret;
174 }
175 
Stop()176 int32_t TestPlayerImpl::Stop()
177 {
178     if (pipelineStates_.load() == PlayerStates::PLAYER_PREPARED ||
179         pipelineStates_.load() == PlayerStates::PLAYER_STARTED ||
180         pipelineStates_.load() == PlayerStates::PLAYER_PLAYBACK_COMPLETE ||
181         pipelineStates_.load()== PlayerStates::PLAYER_PAUSED) {
182         g_playFinished = true;
183         int32_t ret = player_->Stop();
184         if (ret == 0) {
185             pipelineStates_.store(PlayerStates::PLAYER_STOPPED);
186         }
187         return ret;
188     }
189     return MSERR_INVALID_OPERATION;
190 }
191 
Reset()192 int32_t TestPlayerImpl::Reset()
193 {
194     if (pipelineStates_.load()  == PlayerStates::PLAYER_IDLE) {
195         return MSERR_INVALID_OPERATION;
196     }
197     int32_t ret = player_->Reset();
198     if (ret == 0) {
199         pipelineStates_.store(PlayerStates::PLAYER_IDLE);
200     }
201     return ret;
202 }
203 
Release()204 int32_t TestPlayerImpl::Release()
205 {
206     player_ = nullptr;
207     return ERR_OK;
208 }
209 
Seek(int64_t timeMs,PlayerSeekMode mode)210 int32_t TestPlayerImpl::Seek(int64_t timeMs, PlayerSeekMode mode)
211 {
212     int32_t ret = player_->Seek(timeMs, mode);
213     NZERO_RETURN(ret);
214     while (!g_seekFinished) {
215         std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 50
216     }
217     FALSE_RETURN_V(g_seekFinished, false);
218     g_seekFinished = false;
219     return ret;
220 }
221 
GetCurrentTime(int64_t & currentMs)222 int32_t TestPlayerImpl::GetCurrentTime(int64_t& currentMs)
223 {
224     int32_t currentTimeMS = 0;
225     int32_t ret = player_->GetCurrentTime(currentTimeMS);
226     currentMs = currentTimeMS;
227     return ret;
228 }
229 
GetDuration(int64_t & durationMs)230 int32_t TestPlayerImpl::GetDuration(int64_t& durationMs)
231 {
232     int32_t duration;
233     int32_t ret = player_->GetDuration(duration);
234     durationMs = duration;
235     return ret;
236 }
SetPlaybackSpeed(PlaybackRateMode mode)237 int32_t TestPlayerImpl::SetPlaybackSpeed(PlaybackRateMode mode)
238 {
239     return player_->SetPlaybackSpeed(mode);
240 }
241 
GetPlaybackSpeed(PlaybackRateMode & mode)242 int32_t TestPlayerImpl::GetPlaybackSpeed(PlaybackRateMode& mode)
243 {
244     return player_->GetPlaybackSpeed(mode);
245 }
246 
SetVolume(float leftVolume,float rightVolume)247 int32_t TestPlayerImpl::SetVolume(float leftVolume, float rightVolume)
248 {
249     int32_t ret = player_->SetVolume(leftVolume, rightVolume);
250     return ret;
251 }
252 
GetAudioTrackInfo(std::vector<Format> & audioTrack)253 int32_t TestPlayerImpl::GetAudioTrackInfo(std::vector<Format> &audioTrack)
254 {
255     int32_t ret = player_->GetAudioTrackInfo(audioTrack);
256     return ret;
257 }
258 
GetVideoTrackInfo(std::vector<Format> & videoTrack)259 int32_t TestPlayerImpl::GetVideoTrackInfo(std::vector<Format> &videoTrack)
260 {
261     int32_t ret = player_->GetVideoTrackInfo(videoTrack);
262     return ret;
263 }
264 }
265 #endif