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