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