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