1fa7767c5Sopenharmony_ci/*
2fa7767c5Sopenharmony_ci * Copyright (c) 2021-2021 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
16fa7767c5Sopenharmony_ci#define HST_LOG_TAG "HiPlayerImpl"
17fa7767c5Sopenharmony_ci
18fa7767c5Sopenharmony_ci#include "hiplayer_impl.h"
19fa7767c5Sopenharmony_ci#include "foundation/log.h"
20fa7767c5Sopenharmony_ci#include "foundation/utils/steady_clock.h"
21fa7767c5Sopenharmony_ci#include "pipeline/factory/filter_factory.h"
22fa7767c5Sopenharmony_ci#include "plugin/common/plugin_time.h"
23fa7767c5Sopenharmony_cinamespace {
24fa7767c5Sopenharmony_ciconst float MAX_MEDIA_VOLUME = 100.0f;
25fa7767c5Sopenharmony_ci}
26fa7767c5Sopenharmony_ci
27fa7767c5Sopenharmony_cinamespace OHOS {
28fa7767c5Sopenharmony_cinamespace Media {
29fa7767c5Sopenharmony_ciusing namespace Pipeline;
30fa7767c5Sopenharmony_ci
31fa7767c5Sopenharmony_ciHiPlayerImpl::HiPlayerImpl()
32fa7767c5Sopenharmony_ci    : fsm_(*this),
33fa7767c5Sopenharmony_ci      curFsmState_(StateId::IDLE),
34fa7767c5Sopenharmony_ci      volume_(-1.0f),
35fa7767c5Sopenharmony_ci      mediaStats_()
36fa7767c5Sopenharmony_ci{
37fa7767c5Sopenharmony_ci    MEDIA_LOG_I("hiPlayerImpl ctor");
38fa7767c5Sopenharmony_ci    FilterFactory::Instance().Init();
39fa7767c5Sopenharmony_ci    syncManager_ = std::make_shared<MediaSyncManager>();
40fa7767c5Sopenharmony_ci
41fa7767c5Sopenharmony_ci    audioSource_ =
42fa7767c5Sopenharmony_ci        FilterFactory::Instance().CreateFilterWithType<MediaSourceFilter>("builtin.player.mediasource", "mediaSource");
43fa7767c5Sopenharmony_ci
44fa7767c5Sopenharmony_ci#ifdef UNIT_TEST
45fa7767c5Sopenharmony_ci    demuxer_ = FilterFactory::Instance().CreateFilterWithType<DemuxerFilter>("builtin.player.demuxer", "demuxer");
46fa7767c5Sopenharmony_ci    audioDecoder_ = FilterFactory::Instance().CreateFilterWithType<AudioDecoderFilter>("builtin.player.audiodecoder",
47fa7767c5Sopenharmony_ci                                                                                       "audiodecoder");
48fa7767c5Sopenharmony_ci    audioSink_ =
49fa7767c5Sopenharmony_ci        FilterFactory::Instance().CreateFilterWithType<AudioSinkFilter>("builtin.player.audiosink", "audiosink");
50fa7767c5Sopenharmony_ci#else
51fa7767c5Sopenharmony_ci    demuxer_ = FilterFactory::Instance().CreateFilterWithType<DemuxerFilter>("builtin.player.demuxer", "demuxer");
52fa7767c5Sopenharmony_ci    audioSink_ =
53fa7767c5Sopenharmony_ci        FilterFactory::Instance().CreateFilterWithType<AudioSinkFilter>("builtin.player.audiosink", "audioSink");
54fa7767c5Sopenharmony_ci#ifdef VIDEO_SUPPORT
55fa7767c5Sopenharmony_ci    videoSink =
56fa7767c5Sopenharmony_ci        FilterFactory::Instance().CreateFilterWithType<VideoSinkFilter>("builtin.player.videosink", "videoSink");
57fa7767c5Sopenharmony_ci    FALSE_RETURN(videoSink != nullptr);
58fa7767c5Sopenharmony_ci    videoSink->SetSyncCenter(syncManager_);
59fa7767c5Sopenharmony_ci#endif
60fa7767c5Sopenharmony_ci#endif
61fa7767c5Sopenharmony_ci    FALSE_RETURN(audioSource_ != nullptr);
62fa7767c5Sopenharmony_ci    FALSE_RETURN(demuxer_ != nullptr);
63fa7767c5Sopenharmony_ci    FALSE_RETURN(audioSink_ != nullptr);
64fa7767c5Sopenharmony_ci    audioSink_->SetSyncCenter(syncManager_);
65fa7767c5Sopenharmony_ci    pipeline_ = std::make_shared<PipelineCore>();
66fa7767c5Sopenharmony_ci}
67fa7767c5Sopenharmony_ci
68fa7767c5Sopenharmony_civoid HiPlayerImpl::UpdateStateNoLock(PlayerStates newState, bool notifyUpward)
69fa7767c5Sopenharmony_ci{
70fa7767c5Sopenharmony_ci    if (pipelineStates_ == newState) {
71fa7767c5Sopenharmony_ci        return;
72fa7767c5Sopenharmony_ci    }
73fa7767c5Sopenharmony_ci    pipelineStates_ = newState;
74fa7767c5Sopenharmony_ci    if (pipelineStates_ == PlayerStates::PLAYER_IDLE) {
75fa7767c5Sopenharmony_ci        MEDIA_LOG_W("do not report idle since audio player will report idle");
76fa7767c5Sopenharmony_ci        return;
77fa7767c5Sopenharmony_ci    }
78fa7767c5Sopenharmony_ci    if (notifyUpward) {
79fa7767c5Sopenharmony_ci        auto ptr = callback_.lock();
80fa7767c5Sopenharmony_ci        if (ptr != nullptr) {
81fa7767c5Sopenharmony_ci            while (!pendingStates_.empty()) {
82fa7767c5Sopenharmony_ci                auto pendingState = pendingStates_.front();
83fa7767c5Sopenharmony_ci                pendingStates_.pop();
84fa7767c5Sopenharmony_ci                MEDIA_LOG_I("sending pending state change: " PUBLIC_LOG_S, StringnessPlayerState(pendingState).c_str());
85fa7767c5Sopenharmony_ci            }
86fa7767c5Sopenharmony_ci            MEDIA_LOG_I("State change to : " PUBLIC_LOG_S, StringnessPlayerState(pipelineStates_.load()).c_str());
87fa7767c5Sopenharmony_ci        }
88fa7767c5Sopenharmony_ci    }
89fa7767c5Sopenharmony_ci}
90fa7767c5Sopenharmony_ci
91fa7767c5Sopenharmony_ciHiPlayerImpl::~HiPlayerImpl()
92fa7767c5Sopenharmony_ci{
93fa7767c5Sopenharmony_ci    MEDIA_LOG_D("dtor called.");
94fa7767c5Sopenharmony_ci    fsm_.SendEventAsync(Intent::STOP);
95fa7767c5Sopenharmony_ci    fsm_.Stop();
96fa7767c5Sopenharmony_ci#ifdef VIDEO_SUPPORT
97fa7767c5Sopenharmony_ci    videoSink.reset();
98fa7767c5Sopenharmony_ci#endif
99fa7767c5Sopenharmony_ci    audioSink_.reset();
100fa7767c5Sopenharmony_ci    syncManager_.reset();
101fa7767c5Sopenharmony_ci}
102fa7767c5Sopenharmony_ci
103fa7767c5Sopenharmony_cistd::shared_ptr<HiPlayerImpl> HiPlayerImpl::CreateHiPlayerImpl()
104fa7767c5Sopenharmony_ci{
105fa7767c5Sopenharmony_ci    return std::shared_ptr<HiPlayerImpl>(new (std::nothrow) HiPlayerImpl());
106fa7767c5Sopenharmony_ci}
107fa7767c5Sopenharmony_ci
108fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Init()
109fa7767c5Sopenharmony_ci{
110fa7767c5Sopenharmony_ci    mediaStats_.Reset();
111fa7767c5Sopenharmony_ci    if (initialized_.load()) {
112fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::SUCCESS);
113fa7767c5Sopenharmony_ci    }
114fa7767c5Sopenharmony_ci    pipeline_->Init(this, this);
115fa7767c5Sopenharmony_ci    ErrorCode ret = pipeline_->AddFilters({audioSource_.get(), demuxer_.get()});
116fa7767c5Sopenharmony_ci    if (ret == ErrorCode::SUCCESS) {
117fa7767c5Sopenharmony_ci        ret = pipeline_->LinkFilters({audioSource_.get(), demuxer_.get()});
118fa7767c5Sopenharmony_ci    }
119fa7767c5Sopenharmony_ci    if (ret == ErrorCode::SUCCESS) {
120fa7767c5Sopenharmony_ci        fsm_.SetStateCallback(this);
121fa7767c5Sopenharmony_ci        fsm_.Start();
122fa7767c5Sopenharmony_ci        initialized_ = true;
123fa7767c5Sopenharmony_ci    } else {
124fa7767c5Sopenharmony_ci        pipeline_->RemoveFilterChain(audioSource_.get());
125fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
126fa7767c5Sopenharmony_ci    }
127fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ret);
128fa7767c5Sopenharmony_ci}
129fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetSource(const Source& source)
130fa7767c5Sopenharmony_ci{
131fa7767c5Sopenharmony_ci    PROFILE_BEGIN("SetSource begin");
132fa7767c5Sopenharmony_ci    auto ret = Init();
133fa7767c5Sopenharmony_ci    if (ret == CppExt::to_underlying(ErrorCode::SUCCESS)) {
134fa7767c5Sopenharmony_ci        std::shared_ptr<MediaSource> mediaSource = std::make_shared<MediaSource>(source.GetSourceUri());
135fa7767c5Sopenharmony_ci        if (source.GetSourceType() == OHOS::Media::SourceType::SOURCE_TYPE_STREAM) {
136fa7767c5Sopenharmony_ci            mediaSource = std::make_shared<MediaSource>(source.GetDataConsumer());
137fa7767c5Sopenharmony_ci        }
138fa7767c5Sopenharmony_ci        ret = CppExt::to_underlying(fsm_.SendEvent(Intent::SET_SOURCE, mediaSource));
139fa7767c5Sopenharmony_ci    }
140fa7767c5Sopenharmony_ci    if (ret != CppExt::to_underlying(ErrorCode::SUCCESS)) {
141fa7767c5Sopenharmony_ci        MEDIA_LOG_E("SetSource error: " PUBLIC_LOG_D32, ret);
142fa7767c5Sopenharmony_ci    }
143fa7767c5Sopenharmony_ci    PROFILE_END("SetSource end.");
144fa7767c5Sopenharmony_ci    return ret;
145fa7767c5Sopenharmony_ci}
146fa7767c5Sopenharmony_ci
147fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Prepare()
148fa7767c5Sopenharmony_ci{
149fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Prepare entered, current fsm state: " PUBLIC_LOG_S ".", fsm_.GetCurrentState().c_str());
150fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
151fa7767c5Sopenharmony_ci    auto ret = fsm_.SendEvent(Intent::PREPARE);
152fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
153fa7767c5Sopenharmony_ci        PROFILE_END("Prepare failed,");
154fa7767c5Sopenharmony_ci        MEDIA_LOG_E("prepare failed with error " PUBLIC_LOG_D32, ret);
155fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ret);
156fa7767c5Sopenharmony_ci    }
157fa7767c5Sopenharmony_ci    OSAL::ScopedLock lock(stateMutex_);
158fa7767c5Sopenharmony_ci    if (curFsmState_ == StateId::PREPARING) { // Wait state change to ready
159fa7767c5Sopenharmony_ci        cond_.Wait(lock, [this] { return curFsmState_ != StateId::PREPARING; });
160fa7767c5Sopenharmony_ci    }
161fa7767c5Sopenharmony_ci    MEDIA_LOG_D("Prepare finished, current fsm state: " PUBLIC_LOG "s.", fsm_.GetCurrentState().c_str());
162fa7767c5Sopenharmony_ci    PROFILE_END("Prepare finished, current fsm state: " PUBLIC_LOG "s.", fsm_.GetCurrentState().c_str());
163fa7767c5Sopenharmony_ci    if (curFsmState_ == StateId::READY) {
164fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::SUCCESS);
165fa7767c5Sopenharmony_ci    }
166fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNKNOWN);
167fa7767c5Sopenharmony_ci}
168fa7767c5Sopenharmony_ci
169fa7767c5Sopenharmony_ciPFilter HiPlayerImpl::CreateAudioDecoder(const std::string& desc)
170fa7767c5Sopenharmony_ci{
171fa7767c5Sopenharmony_ci    if (!audioDecoderMap_[desc]) {
172fa7767c5Sopenharmony_ci        audioDecoderMap_[desc] = FilterFactory::Instance().CreateFilterWithType<AudioDecoderFilter>(
173fa7767c5Sopenharmony_ci            "builtin.player.audiodecoder", "audiodecoder-" + desc);
174fa7767c5Sopenharmony_ci        // set parameters to decoder.
175fa7767c5Sopenharmony_ci    }
176fa7767c5Sopenharmony_ci    return audioDecoderMap_[desc];
177fa7767c5Sopenharmony_ci}
178fa7767c5Sopenharmony_ci
179fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Play()
180fa7767c5Sopenharmony_ci{
181fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
182fa7767c5Sopenharmony_ci    ErrorCode ret;
183fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Play entered.");
184fa7767c5Sopenharmony_ci    if (pipelineStates_ == PlayerStates::PLAYER_PAUSED) {
185fa7767c5Sopenharmony_ci        ret = fsm_.SendEvent(Intent::RESUME);
186fa7767c5Sopenharmony_ci    } else {
187fa7767c5Sopenharmony_ci        ret = fsm_.SendEvent(Intent::PLAY);
188fa7767c5Sopenharmony_ci    }
189fa7767c5Sopenharmony_ci    PROFILE_END("Play ret = " PUBLIC_LOG_D32, CppExt::to_underlying(ret));
190fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ret);
191fa7767c5Sopenharmony_ci}
192fa7767c5Sopenharmony_ci
193fa7767c5Sopenharmony_cibool HiPlayerImpl::IsPlaying()
194fa7767c5Sopenharmony_ci{
195fa7767c5Sopenharmony_ci    return pipelineStates_ == PlayerStates::PLAYER_STARTED;
196fa7767c5Sopenharmony_ci}
197fa7767c5Sopenharmony_ci
198fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Pause()
199fa7767c5Sopenharmony_ci{
200fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
201fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Pause entered.");
202fa7767c5Sopenharmony_ci    auto ret = CppExt::to_underlying(fsm_.SendEvent(Intent::PAUSE));
203fa7767c5Sopenharmony_ci    PROFILE_END("Pause ret = " PUBLIC_LOG_D32, ret);
204fa7767c5Sopenharmony_ci    return ret;
205fa7767c5Sopenharmony_ci}
206fa7767c5Sopenharmony_ci
207fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Stop()
208fa7767c5Sopenharmony_ci{
209fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
210fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Stop entered.");
211fa7767c5Sopenharmony_ci    auto ret = CppExt::to_underlying(fsm_.SendEvent(Intent::STOP));
212fa7767c5Sopenharmony_ci    PROFILE_END("Stop ret = " PUBLIC_LOG_D32, ret);
213fa7767c5Sopenharmony_ci    return ret;
214fa7767c5Sopenharmony_ci}
215fa7767c5Sopenharmony_ci
216fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::StopAsync()
217fa7767c5Sopenharmony_ci{
218fa7767c5Sopenharmony_ci    MEDIA_LOG_I("StopAsync entered.");
219fa7767c5Sopenharmony_ci    return fsm_.SendEventAsync(Intent::STOP);
220fa7767c5Sopenharmony_ci}
221fa7767c5Sopenharmony_ci
222fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Rewind(int64_t mSeconds, int32_t mode)
223fa7767c5Sopenharmony_ci{
224fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Rewind entered.");
225fa7767c5Sopenharmony_ci    int64_t hstTime = 0;
226fa7767c5Sopenharmony_ci    int64_t durationMs = 0;
227fa7767c5Sopenharmony_ci    NZERO_RETURN(GetDuration(durationMs));
228fa7767c5Sopenharmony_ci    MEDIA_LOG_D("Rewind durationMs : " PUBLIC_LOG_D64, durationMs);
229fa7767c5Sopenharmony_ci    if (mSeconds >= durationMs) { // if exceeds change to duration
230fa7767c5Sopenharmony_ci        mSeconds = durationMs;
231fa7767c5Sopenharmony_ci    }
232fa7767c5Sopenharmony_ci    if (audioSource_->GetSeekable() != Plugin::Seekable::SEEKABLE) {
233fa7767c5Sopenharmony_ci        MEDIA_LOG_E("Seek, invalid operation, audio source is unseekable or invalid");
234fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_INVALID_OPERATION);
235fa7767c5Sopenharmony_ci    }
236fa7767c5Sopenharmony_ci    if (!Plugin::Ms2HstTime(mSeconds, hstTime)) {
237fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_INVALID_PARAMETER_VALUE);
238fa7767c5Sopenharmony_ci    }
239fa7767c5Sopenharmony_ci    auto smode = Transform2SeekMode(static_cast<PlayerSeekMode>(mode));
240fa7767c5Sopenharmony_ci    return CppExt::to_underlying(fsm_.SendEvent(Intent::SEEK, SeekInfo{hstTime, smode}));
241fa7767c5Sopenharmony_ci}
242fa7767c5Sopenharmony_ci
243fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetVolume(float leftVolume, float rightVolume)
244fa7767c5Sopenharmony_ci{
245fa7767c5Sopenharmony_ci    if (leftVolume < 0 || leftVolume > MAX_MEDIA_VOLUME || rightVolume < 0 || rightVolume > MAX_MEDIA_VOLUME) {
246fa7767c5Sopenharmony_ci        MEDIA_LOG_E("volume not valid, should be in range [0,100]");
247fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_INVALID_PARAMETER_VALUE);
248fa7767c5Sopenharmony_ci    }
249fa7767c5Sopenharmony_ci    float volume = 0.0f;
250fa7767c5Sopenharmony_ci    if (leftVolume < 1e-6 && rightVolume >= 1e-6) { // 1e-6
251fa7767c5Sopenharmony_ci        volume = rightVolume;
252fa7767c5Sopenharmony_ci    } else if (rightVolume < 1e-6 && leftVolume >= 1e-6) { // 1e-6
253fa7767c5Sopenharmony_ci        volume = leftVolume;
254fa7767c5Sopenharmony_ci    } else {
255fa7767c5Sopenharmony_ci        volume = (leftVolume + rightVolume) / 2; // 2
256fa7767c5Sopenharmony_ci    }
257fa7767c5Sopenharmony_ci    volume /= MAX_MEDIA_VOLUME; // normalize to 0~1
258fa7767c5Sopenharmony_ci    if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
259fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_INVALID_OPERATION);
260fa7767c5Sopenharmony_ci    }
261fa7767c5Sopenharmony_ci    volume_ = volume;
262fa7767c5Sopenharmony_ci    if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_INITIALIZED ||
263fa7767c5Sopenharmony_ci        pipelineStates_ == PlayerStates::PLAYER_PREPARING || audioSink_ == nullptr) {
264fa7767c5Sopenharmony_ci        MEDIA_LOG_W("cannot set volume, will do this onReady");
265fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::SUCCESS);
266fa7767c5Sopenharmony_ci    }
267fa7767c5Sopenharmony_ci    return CppExt::to_underlying(SetVolumeToSink(volume_));
268fa7767c5Sopenharmony_ci}
269fa7767c5Sopenharmony_ci
270fa7767c5Sopenharmony_ci#ifndef SURFACE_DISABLED
271fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetSurface(Surface* surface)
272fa7767c5Sopenharmony_ci{
273fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
274fa7767c5Sopenharmony_ci}
275fa7767c5Sopenharmony_ci#endif
276fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::SetBufferSize(size_t size)
277fa7767c5Sopenharmony_ci{
278fa7767c5Sopenharmony_ci    return audioSource_->SetBufferSize(size);
279fa7767c5Sopenharmony_ci}
280fa7767c5Sopenharmony_ci
281fa7767c5Sopenharmony_civoid HiPlayerImpl::OnEvent(const Event& event)
282fa7767c5Sopenharmony_ci{
283fa7767c5Sopenharmony_ci    if (event.type != EventType::EVENT_AUDIO_PROGRESS) {
284fa7767c5Sopenharmony_ci        MEDIA_LOG_I("[HiStreamer] OnEvent (" PUBLIC_LOG_S ")", GetEventName(event.type));
285fa7767c5Sopenharmony_ci    }
286fa7767c5Sopenharmony_ci    switch (event.type) {
287fa7767c5Sopenharmony_ci        case EventType::EVENT_ERROR: {
288fa7767c5Sopenharmony_ci            fsm_.SendEventAsync(Intent::NOTIFY_ERROR, event.param);
289fa7767c5Sopenharmony_ci            break;
290fa7767c5Sopenharmony_ci        }
291fa7767c5Sopenharmony_ci        case EventType::EVENT_READY:
292fa7767c5Sopenharmony_ci            fsm_.SendEventAsync(Intent::NOTIFY_READY);
293fa7767c5Sopenharmony_ci            break;
294fa7767c5Sopenharmony_ci        case EventType::EVENT_COMPLETE:
295fa7767c5Sopenharmony_ci            mediaStats_.ReceiveEvent(event);
296fa7767c5Sopenharmony_ci            if (mediaStats_.IsEventCompleteAllReceived()) {
297fa7767c5Sopenharmony_ci                fsm_.SendEventAsync(Intent::NOTIFY_COMPLETE);
298fa7767c5Sopenharmony_ci            }
299fa7767c5Sopenharmony_ci            break;
300fa7767c5Sopenharmony_ci        case EventType::EVENT_PLUGIN_ERROR: {
301fa7767c5Sopenharmony_ci            HandlePluginErrorEvent(event);
302fa7767c5Sopenharmony_ci            break;
303fa7767c5Sopenharmony_ci        }
304fa7767c5Sopenharmony_ci        case EventType::EVENT_PLUGIN_EVENT: {
305fa7767c5Sopenharmony_ci            Plugin::PluginEvent pluginEvent = Plugin::AnyCast<Plugin::PluginEvent>(event.param);
306fa7767c5Sopenharmony_ci            if (pluginEvent.type == Plugin::PluginEventType::BELOW_LOW_WATERLINE ||
307fa7767c5Sopenharmony_ci                pluginEvent.type == Plugin::PluginEventType::ABOVE_LOW_WATERLINE) {
308fa7767c5Sopenharmony_ci                MEDIA_LOG_I("Receive PLUGIN_EVENT, type:  " PUBLIC_LOG_D32, CppExt::to_underlying(pluginEvent.type));
309fa7767c5Sopenharmony_ci            }
310fa7767c5Sopenharmony_ci            break;
311fa7767c5Sopenharmony_ci        }
312fa7767c5Sopenharmony_ci        default:
313fa7767c5Sopenharmony_ci            MEDIA_LOG_E("Unknown event(" PUBLIC_LOG_U32 ")", event.type);
314fa7767c5Sopenharmony_ci    }
315fa7767c5Sopenharmony_ci}
316fa7767c5Sopenharmony_ci
317fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoSetSource(const std::shared_ptr<MediaSource>& source)
318fa7767c5Sopenharmony_ci{
319fa7767c5Sopenharmony_ci    auto ret = audioSource_->SetSource(source);
320fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
321fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
322fa7767c5Sopenharmony_ci    }
323fa7767c5Sopenharmony_ci    return ret;
324fa7767c5Sopenharmony_ci}
325fa7767c5Sopenharmony_ci
326fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::PrepareFilters()
327fa7767c5Sopenharmony_ci{
328fa7767c5Sopenharmony_ci    auto ret = pipeline_->Prepare();
329fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
330fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
331fa7767c5Sopenharmony_ci    }
332fa7767c5Sopenharmony_ci    return ret;
333fa7767c5Sopenharmony_ci}
334fa7767c5Sopenharmony_ci
335fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoPlay()
336fa7767c5Sopenharmony_ci{
337fa7767c5Sopenharmony_ci    syncManager_->Resume();
338fa7767c5Sopenharmony_ci    auto ret = pipeline_->Start();
339fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
340fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
341fa7767c5Sopenharmony_ci    }
342fa7767c5Sopenharmony_ci    return ret;
343fa7767c5Sopenharmony_ci}
344fa7767c5Sopenharmony_ci
345fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoPause()
346fa7767c5Sopenharmony_ci{
347fa7767c5Sopenharmony_ci    auto ret = pipeline_->Pause();
348fa7767c5Sopenharmony_ci    syncManager_->Pause();
349fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
350fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
351fa7767c5Sopenharmony_ci    }
352fa7767c5Sopenharmony_ci    return ret;
353fa7767c5Sopenharmony_ci}
354fa7767c5Sopenharmony_ci
355fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoResume()
356fa7767c5Sopenharmony_ci{
357fa7767c5Sopenharmony_ci    syncManager_->Resume();
358fa7767c5Sopenharmony_ci    auto ret = pipeline_->Resume();
359fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
360fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
361fa7767c5Sopenharmony_ci    }
362fa7767c5Sopenharmony_ci    return ret;
363fa7767c5Sopenharmony_ci}
364fa7767c5Sopenharmony_ci
365fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoStop()
366fa7767c5Sopenharmony_ci{
367fa7767c5Sopenharmony_ci    MEDIA_LOG_I("HiPlayerImpl DoStop called, stop pipeline.");
368fa7767c5Sopenharmony_ci    mediaStats_.Reset();
369fa7767c5Sopenharmony_ci    // 先先关闭demuxer线程,防止元数据解析prepare过程中出现并发问题
370fa7767c5Sopenharmony_ci    if (demuxer_) {
371fa7767c5Sopenharmony_ci        demuxer_->StopTask(false);
372fa7767c5Sopenharmony_ci    }
373fa7767c5Sopenharmony_ci    auto ret = pipeline_->Stop();
374fa7767c5Sopenharmony_ci    syncManager_->Reset();
375fa7767c5Sopenharmony_ci    if (ret != ErrorCode::SUCCESS) {
376fa7767c5Sopenharmony_ci        UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
377fa7767c5Sopenharmony_ci    }
378fa7767c5Sopenharmony_ci    return ret;
379fa7767c5Sopenharmony_ci}
380fa7767c5Sopenharmony_ci
381fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoReset()
382fa7767c5Sopenharmony_ci{
383fa7767c5Sopenharmony_ci    return DoStop();
384fa7767c5Sopenharmony_ci}
385fa7767c5Sopenharmony_ci
386fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoSeek(int64_t hstTime, Plugin::SeekMode mode, bool appTriggered)
387fa7767c5Sopenharmony_ci{
388fa7767c5Sopenharmony_ci    if (appTriggered) {
389fa7767c5Sopenharmony_ci        fsm_.Notify(Intent::SEEK, ErrorCode::SUCCESS);
390fa7767c5Sopenharmony_ci    }
391fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
392fa7767c5Sopenharmony_ci    auto rtv = hstTime >= 0 ? ErrorCode::SUCCESS : ErrorCode::ERROR_INVALID_OPERATION;
393fa7767c5Sopenharmony_ci    if (rtv == ErrorCode::SUCCESS) {
394fa7767c5Sopenharmony_ci        pipeline_->FlushStart();
395fa7767c5Sopenharmony_ci        PROFILE_END("Flush start");
396fa7767c5Sopenharmony_ci        PROFILE_RESET();
397fa7767c5Sopenharmony_ci
398fa7767c5Sopenharmony_ci        int64_t realSeekTime = hstTime;
399fa7767c5Sopenharmony_ci        rtv = demuxer_->SeekTo(hstTime, mode, realSeekTime);
400fa7767c5Sopenharmony_ci        if (rtv == ErrorCode::SUCCESS) {
401fa7767c5Sopenharmony_ci            syncManager_->Seek(realSeekTime);
402fa7767c5Sopenharmony_ci        }
403fa7767c5Sopenharmony_ci        PROFILE_END("SeekTo");
404fa7767c5Sopenharmony_ci
405fa7767c5Sopenharmony_ci        pipeline_->FlushEnd();
406fa7767c5Sopenharmony_ci        PROFILE_END("Flush end");
407fa7767c5Sopenharmony_ci        PROFILE_RESET();
408fa7767c5Sopenharmony_ci    }
409fa7767c5Sopenharmony_ci    auto ptr = callback_.lock();
410fa7767c5Sopenharmony_ci    if (ptr != nullptr) {
411fa7767c5Sopenharmony_ci        if (rtv != ErrorCode::SUCCESS) {
412fa7767c5Sopenharmony_ci            ptr->OnError(CppExt::to_underlying(PlayerErrorTypeExt::SEEK_ERROR), CppExt::to_underlying(rtv));
413fa7767c5Sopenharmony_ci        } else {
414fa7767c5Sopenharmony_ci            ptr->OnRewindToComplete();
415fa7767c5Sopenharmony_ci        }
416fa7767c5Sopenharmony_ci    }
417fa7767c5Sopenharmony_ci    if (appTriggered) {
418fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_NO_NOTIFY;
419fa7767c5Sopenharmony_ci    }
420fa7767c5Sopenharmony_ci    return rtv;
421fa7767c5Sopenharmony_ci}
422fa7767c5Sopenharmony_ci
423fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoOnReady()
424fa7767c5Sopenharmony_ci{
425fa7767c5Sopenharmony_ci    SetVolumeToSink(volume_, false); // do not report
426fa7767c5Sopenharmony_ci    auto tmpMeta = demuxer_->GetGlobalMetaInfo();
427fa7767c5Sopenharmony_ci    sourceMeta_ = tmpMeta;
428fa7767c5Sopenharmony_ci    int64_t duration = 0;
429fa7767c5Sopenharmony_ci    bool found = false;
430fa7767c5Sopenharmony_ci    if (tmpMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(duration)) {
431fa7767c5Sopenharmony_ci        found = true;
432fa7767c5Sopenharmony_ci    } else {
433fa7767c5Sopenharmony_ci        MEDIA_LOG_W("Get media duration failed.");
434fa7767c5Sopenharmony_ci    }
435fa7767c5Sopenharmony_ci    streamMeta_.clear();
436fa7767c5Sopenharmony_ci    int64_t tmp = 0;
437fa7767c5Sopenharmony_ci    for (auto& streamMeta : demuxer_->GetStreamMetaInfo()) {
438fa7767c5Sopenharmony_ci        streamMeta_.push_back(streamMeta);
439fa7767c5Sopenharmony_ci        if (streamMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(tmp)) {
440fa7767c5Sopenharmony_ci            duration = std::max(duration, tmp);
441fa7767c5Sopenharmony_ci            found = true;
442fa7767c5Sopenharmony_ci        } else {
443fa7767c5Sopenharmony_ci            MEDIA_LOG_W("Get media duration failed.");
444fa7767c5Sopenharmony_ci        }
445fa7767c5Sopenharmony_ci    }
446fa7767c5Sopenharmony_ci    if (found) {
447fa7767c5Sopenharmony_ci        duration_ = duration;
448fa7767c5Sopenharmony_ci    }
449fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
450fa7767c5Sopenharmony_ci}
451fa7767c5Sopenharmony_ci
452fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoOnComplete()
453fa7767c5Sopenharmony_ci{
454fa7767c5Sopenharmony_ci    MEDIA_LOG_W("OnComplete looping: " PUBLIC_LOG_D32 ".", singleLoop_.load());
455fa7767c5Sopenharmony_ci    auto ptr = callback_.lock();
456fa7767c5Sopenharmony_ci    FALSE_RETURN_V_MSG(ptr != nullptr, ErrorCode::SUCCESS, "Player callback not exist.");
457fa7767c5Sopenharmony_ci    ptr->OnPlaybackComplete();
458fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
459fa7767c5Sopenharmony_ci}
460fa7767c5Sopenharmony_ci
461fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::DoOnError(ErrorCode errorCode)
462fa7767c5Sopenharmony_ci{
463fa7767c5Sopenharmony_ci    UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
464fa7767c5Sopenharmony_ci    auto ptr = callback_.lock();
465fa7767c5Sopenharmony_ci    FALSE_RETURN_V_MSG(ptr != nullptr, ErrorCode::SUCCESS, "Player callback not exist.");
466fa7767c5Sopenharmony_ci    ptr->OnError(PlayerCallback::PlayerCallback::PLAYER_ERROR_UNKNOWN, static_cast<int32_t>(errorCode));
467fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
468fa7767c5Sopenharmony_ci}
469fa7767c5Sopenharmony_ci
470fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::SetVolumeToSink(float volume, bool reportUpward)
471fa7767c5Sopenharmony_ci{
472fa7767c5Sopenharmony_ci    MEDIA_LOG_I("SetVolumeToSink entered.");
473fa7767c5Sopenharmony_ci    ErrorCode ret = ErrorCode::SUCCESS;
474fa7767c5Sopenharmony_ci    if (volume_ > 0) {
475fa7767c5Sopenharmony_ci        MEDIA_LOG_I("set volume " PUBLIC_LOG_F, volume);
476fa7767c5Sopenharmony_ci        ret = audioSink_->SetVolume(volume);
477fa7767c5Sopenharmony_ci    }
478fa7767c5Sopenharmony_ci    auto ptr = callback_.lock();
479fa7767c5Sopenharmony_ci    if (ptr != nullptr) {
480fa7767c5Sopenharmony_ci        if (ret != ErrorCode::SUCCESS) {
481fa7767c5Sopenharmony_ci            MEDIA_LOG_E("SetVolume failed with error " PUBLIC_LOG_D32, static_cast<int>(ret));
482fa7767c5Sopenharmony_ci            ptr->OnError(PlayerCallback::PlayerCallback::PLAYER_ERROR_UNKNOWN, CppExt::to_underlying(ret));
483fa7767c5Sopenharmony_ci        }
484fa7767c5Sopenharmony_ci    }
485fa7767c5Sopenharmony_ci    return ret;
486fa7767c5Sopenharmony_ci}
487fa7767c5Sopenharmony_ci
488fa7767c5Sopenharmony_cibool HiPlayerImpl::IsSingleLooping()
489fa7767c5Sopenharmony_ci{
490fa7767c5Sopenharmony_ci    return singleLoop_.load();
491fa7767c5Sopenharmony_ci}
492fa7767c5Sopenharmony_ci
493fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetLoop(bool loop)
494fa7767c5Sopenharmony_ci{
495fa7767c5Sopenharmony_ci    MEDIA_LOG_I("SetLoop entered, loop: " PUBLIC_LOG_D32, loop);
496fa7767c5Sopenharmony_ci    singleLoop_ = loop;
497fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::SUCCESS);
498fa7767c5Sopenharmony_ci}
499fa7767c5Sopenharmony_ci
500fa7767c5Sopenharmony_cibool HiPlayerImpl::IsSingleLoop()
501fa7767c5Sopenharmony_ci{
502fa7767c5Sopenharmony_ci    // note that we should also consider the live source, which cannot be singleLoop!
503fa7767c5Sopenharmony_ci    return singleLoop_;
504fa7767c5Sopenharmony_ci}
505fa7767c5Sopenharmony_ci
506fa7767c5Sopenharmony_civoid HiPlayerImpl::SetPlayerCallback(const std::shared_ptr<PlayerCallback>& cb)
507fa7767c5Sopenharmony_ci{
508fa7767c5Sopenharmony_ci    callback_ = cb;
509fa7767c5Sopenharmony_ci}
510fa7767c5Sopenharmony_ci
511fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Reset()
512fa7767c5Sopenharmony_ci{
513fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Reset entered.");
514fa7767c5Sopenharmony_ci    singleLoop_ = false;
515fa7767c5Sopenharmony_ci    mediaStats_.Reset();
516fa7767c5Sopenharmony_ci    return CppExt::to_underlying(fsm_.SendEvent(Intent::RESET));
517fa7767c5Sopenharmony_ci}
518fa7767c5Sopenharmony_ci
519fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::Release()
520fa7767c5Sopenharmony_ci{
521fa7767c5Sopenharmony_ci    PROFILE_BEGIN();
522fa7767c5Sopenharmony_ci    auto ret = Reset();
523fa7767c5Sopenharmony_ci    fsm_.Stop();
524fa7767c5Sopenharmony_ci    pipeline_.reset();
525fa7767c5Sopenharmony_ci    audioSource_.reset();
526fa7767c5Sopenharmony_ci    demuxer_.reset();
527fa7767c5Sopenharmony_ci    audioDecoderMap_.clear();
528fa7767c5Sopenharmony_ci    audioSink_.reset();
529fa7767c5Sopenharmony_ci    PROFILE_END("Release ret = " PUBLIC_LOG_D32, ret);
530fa7767c5Sopenharmony_ci    return ret;
531fa7767c5Sopenharmony_ci}
532fa7767c5Sopenharmony_ci
533fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::DeInit()
534fa7767c5Sopenharmony_ci{
535fa7767c5Sopenharmony_ci    return Reset();
536fa7767c5Sopenharmony_ci}
537fa7767c5Sopenharmony_ci
538fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetPlayerState(int32_t& state)
539fa7767c5Sopenharmony_ci{
540fa7767c5Sopenharmony_ci    state = static_cast<int32_t>(pipelineStates_.load());
541fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::SUCCESS);
542fa7767c5Sopenharmony_ci}
543fa7767c5Sopenharmony_ci
544fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetCurrentPosition(int64_t& currentPositionMs)
545fa7767c5Sopenharmony_ci{
546fa7767c5Sopenharmony_ci    currentPositionMs = Plugin::HstTime2Ms(syncManager_->GetMediaTimeNow());
547fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::SUCCESS);
548fa7767c5Sopenharmony_ci}
549fa7767c5Sopenharmony_ci
550fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetDuration(int64_t& outDurationMs)
551fa7767c5Sopenharmony_ci{
552fa7767c5Sopenharmony_ci    MEDIA_LOG_I("GetDuration entered.");
553fa7767c5Sopenharmony_ci    outDurationMs = 0;
554fa7767c5Sopenharmony_ci    if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_PREPARING
555fa7767c5Sopenharmony_ci        || audioSource_ == nullptr) {
556fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_INVALID_STATE);
557fa7767c5Sopenharmony_ci    }
558fa7767c5Sopenharmony_ci    if (duration_ < 0) {
559fa7767c5Sopenharmony_ci        outDurationMs = -1;
560fa7767c5Sopenharmony_ci        MEDIA_LOG_W("no valid duration");
561fa7767c5Sopenharmony_ci        return CppExt::to_underlying(ErrorCode::ERROR_UNKNOWN);
562fa7767c5Sopenharmony_ci    }
563fa7767c5Sopenharmony_ci    outDurationMs = Plugin::HstTime2Ms(duration_);
564fa7767c5Sopenharmony_ci    MEDIA_LOG_I("GetDuration returned " PUBLIC_LOG_D32, outDurationMs);
565fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::SUCCESS);
566fa7767c5Sopenharmony_ci}
567fa7767c5Sopenharmony_ci
568fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetVideoWidth(int32_t& videoWidth)
569fa7767c5Sopenharmony_ci{
570fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
571fa7767c5Sopenharmony_ci}
572fa7767c5Sopenharmony_ci
573fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetVideoHeight(int32_t& videoHeight)
574fa7767c5Sopenharmony_ci{
575fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
576fa7767c5Sopenharmony_ci}
577fa7767c5Sopenharmony_ci
578fa7767c5Sopenharmony_civoid HiPlayerImpl::HandlePluginErrorEvent(const Event& event)
579fa7767c5Sopenharmony_ci{
580fa7767c5Sopenharmony_ci    Plugin::PluginEvent pluginEvent = Plugin::AnyCast<Plugin::PluginEvent>(event.param);
581fa7767c5Sopenharmony_ci    MEDIA_LOG_I("Receive PLUGIN_ERROR, type:  " PUBLIC_LOG_D32, CppExt::to_underlying(pluginEvent.type));
582fa7767c5Sopenharmony_ci    if (pluginEvent.type == Plugin::PluginEventType::CLIENT_ERROR &&
583fa7767c5Sopenharmony_ci            Plugin::Any::IsSameTypeWith<Plugin::NetworkClientErrorCode>(pluginEvent.param)) {
584fa7767c5Sopenharmony_ci        auto netClientErrorCode = Plugin::AnyCast<Plugin::NetworkClientErrorCode>(pluginEvent.param);
585fa7767c5Sopenharmony_ci        auto errorCode {-1};
586fa7767c5Sopenharmony_ci        if (netClientErrorCode == Plugin::NetworkClientErrorCode::ERROR_TIME_OUT) {
587fa7767c5Sopenharmony_ci            errorCode = CppExt::to_underlying(Plugin::NetworkClientErrorCode::ERROR_TIME_OUT);
588fa7767c5Sopenharmony_ci        }
589fa7767c5Sopenharmony_ci        auto ptr = callback_.lock();
590fa7767c5Sopenharmony_ci        if (ptr != nullptr) {
591fa7767c5Sopenharmony_ci            ptr->OnError(PlayerCallback::PlayerErrorType::PLAYER_ERROR_UNKNOWN, errorCode);
592fa7767c5Sopenharmony_ci        }
593fa7767c5Sopenharmony_ci    }
594fa7767c5Sopenharmony_ci}
595fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetPlaybackSpeed(float speed)
596fa7767c5Sopenharmony_ci{
597fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
598fa7767c5Sopenharmony_ci}
599fa7767c5Sopenharmony_ci
600fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::GetPlaybackSpeed(float& speed)
601fa7767c5Sopenharmony_ci{
602fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
603fa7767c5Sopenharmony_ci}
604fa7767c5Sopenharmony_ci
605fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetAudioStreamType(int32_t type)
606fa7767c5Sopenharmony_ci{
607fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
608fa7767c5Sopenharmony_ci}
609fa7767c5Sopenharmony_ci
610fa7767c5Sopenharmony_civoid HiPlayerImpl::GetAudioStreamType(int32_t& type)
611fa7767c5Sopenharmony_ci{
612fa7767c5Sopenharmony_ci    type = -1;
613fa7767c5Sopenharmony_ci}
614fa7767c5Sopenharmony_ci
615fa7767c5Sopenharmony_ciint32_t HiPlayerImpl::SetParameter(const Format& params)
616fa7767c5Sopenharmony_ci{
617fa7767c5Sopenharmony_ci    return CppExt::to_underlying(ErrorCode::ERROR_UNIMPLEMENTED);
618fa7767c5Sopenharmony_ci}
619fa7767c5Sopenharmony_ci
620fa7767c5Sopenharmony_civoid HiPlayerImpl::OnStateChanged(StateId state)
621fa7767c5Sopenharmony_ci{
622fa7767c5Sopenharmony_ci    MEDIA_LOG_I("OnStateChanged from " PUBLIC_LOG_D32 " to " PUBLIC_LOG_D32, curFsmState_.load(), state);
623fa7767c5Sopenharmony_ci    UpdateStateNoLock(TransStateId2PlayerState(state));
624fa7767c5Sopenharmony_ci    {
625fa7767c5Sopenharmony_ci        OSAL::ScopedLock lock(stateMutex_);
626fa7767c5Sopenharmony_ci        curFsmState_ = state;
627fa7767c5Sopenharmony_ci        cond_.NotifyOne();
628fa7767c5Sopenharmony_ci    }
629fa7767c5Sopenharmony_ci}
630fa7767c5Sopenharmony_ci
631fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::OnCallback(const FilterCallbackType& type, Filter* filter, const Plugin::Any& parameter)
632fa7767c5Sopenharmony_ci{
633fa7767c5Sopenharmony_ci    ErrorCode ret = ErrorCode::SUCCESS;
634fa7767c5Sopenharmony_ci    switch (type) {
635fa7767c5Sopenharmony_ci        case FilterCallbackType::PORT_ADDED:
636fa7767c5Sopenharmony_ci            ret = NewAudioPortFound(filter, parameter);
637fa7767c5Sopenharmony_ci            if (ret != ErrorCode::SUCCESS) {
638fa7767c5Sopenharmony_ci                return ret;
639fa7767c5Sopenharmony_ci            }
640fa7767c5Sopenharmony_ci#ifdef VIDEO_SUPPORT
641fa7767c5Sopenharmony_ci            ret = NewVideoPortFound(filter, parameter);
642fa7767c5Sopenharmony_ci#endif
643fa7767c5Sopenharmony_ci            break;
644fa7767c5Sopenharmony_ci        case FilterCallbackType::PORT_REMOVE:
645fa7767c5Sopenharmony_ci            ret = RemoveFilterChains(filter, parameter);
646fa7767c5Sopenharmony_ci            break;
647fa7767c5Sopenharmony_ci        default:
648fa7767c5Sopenharmony_ci            break;
649fa7767c5Sopenharmony_ci    }
650fa7767c5Sopenharmony_ci    return ret;
651fa7767c5Sopenharmony_ci}
652fa7767c5Sopenharmony_ci
653fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::GetTrackCnt(size_t& cnt) const
654fa7767c5Sopenharmony_ci{
655fa7767c5Sopenharmony_ci    cnt = streamMeta_.size();
656fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
657fa7767c5Sopenharmony_ci}
658fa7767c5Sopenharmony_ci
659fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::GetSourceMeta(shared_ptr<const Plugin::Meta>& meta) const
660fa7767c5Sopenharmony_ci{
661fa7767c5Sopenharmony_ci    meta = sourceMeta_.lock();
662fa7767c5Sopenharmony_ci    return meta ? ErrorCode::SUCCESS : ErrorCode::ERROR_AGAIN;
663fa7767c5Sopenharmony_ci}
664fa7767c5Sopenharmony_ci
665fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::GetTrackMeta(size_t id, shared_ptr<const Plugin::Meta>& meta) const
666fa7767c5Sopenharmony_ci{
667fa7767c5Sopenharmony_ci    if (id > streamMeta_.size() || id < 0) {
668fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
669fa7767c5Sopenharmony_ci    }
670fa7767c5Sopenharmony_ci    meta = streamMeta_[id].lock();
671fa7767c5Sopenharmony_ci    if (meta == nullptr) {
672fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_AGAIN;
673fa7767c5Sopenharmony_ci    }
674fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
675fa7767c5Sopenharmony_ci}
676fa7767c5Sopenharmony_ci
677fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::NewAudioPortFound(Filter* filter, const Plugin::Any& parameter)
678fa7767c5Sopenharmony_ci{
679fa7767c5Sopenharmony_ci    if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
680fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
681fa7767c5Sopenharmony_ci    }
682fa7767c5Sopenharmony_ci    ErrorCode rtv = ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
683fa7767c5Sopenharmony_ci    auto param = Plugin::AnyCast<PortInfo>(parameter);
684fa7767c5Sopenharmony_ci    if (filter == demuxer_.get() && param.type == PortType::OUT) {
685fa7767c5Sopenharmony_ci        MEDIA_LOG_I("new port found on demuxer " PUBLIC_LOG_ZU, param.ports.size());
686fa7767c5Sopenharmony_ci        for (const auto& portDesc : param.ports) {
687fa7767c5Sopenharmony_ci            if (portDesc.name.compare(0, 5, "audio") != 0) { // 5 is length of "audio"
688fa7767c5Sopenharmony_ci                continue;
689fa7767c5Sopenharmony_ci            }
690fa7767c5Sopenharmony_ci            MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
691fa7767c5Sopenharmony_ci            auto fromPort = filter->GetOutPort(portDesc.name);
692fa7767c5Sopenharmony_ci            if (portDesc.isPcm) {
693fa7767c5Sopenharmony_ci                pipeline_->AddFilters({audioSink_.get()});
694fa7767c5Sopenharmony_ci                FAIL_LOG(pipeline_->LinkPorts(fromPort, audioSink_->GetInPort(PORT_NAME_DEFAULT)));
695fa7767c5Sopenharmony_ci                ActiveFilters({audioSink_.get()});
696fa7767c5Sopenharmony_ci            } else {
697fa7767c5Sopenharmony_ci                auto newAudioDecoder = CreateAudioDecoder(portDesc.name);
698fa7767c5Sopenharmony_ci                pipeline_->AddFilters({newAudioDecoder.get(), audioSink_.get()});
699fa7767c5Sopenharmony_ci                FAIL_LOG(pipeline_->LinkPorts(fromPort, newAudioDecoder->GetInPort(PORT_NAME_DEFAULT)));
700fa7767c5Sopenharmony_ci                FAIL_LOG(pipeline_->LinkPorts(newAudioDecoder->GetOutPort(PORT_NAME_DEFAULT),
701fa7767c5Sopenharmony_ci                                              audioSink_->GetInPort(PORT_NAME_DEFAULT)));
702fa7767c5Sopenharmony_ci                ActiveFilters({newAudioDecoder.get(), audioSink_.get()});
703fa7767c5Sopenharmony_ci            }
704fa7767c5Sopenharmony_ci            mediaStats_.Append(audioSink_->GetName());
705fa7767c5Sopenharmony_ci            rtv = ErrorCode::SUCCESS;
706fa7767c5Sopenharmony_ci            break;
707fa7767c5Sopenharmony_ci        }
708fa7767c5Sopenharmony_ci    }
709fa7767c5Sopenharmony_ci    return rtv;
710fa7767c5Sopenharmony_ci}
711fa7767c5Sopenharmony_ci
712fa7767c5Sopenharmony_ci#ifdef VIDEO_SUPPORT
713fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::NewVideoPortFound(Filter* filter, const Plugin::Any& parameter)
714fa7767c5Sopenharmony_ci{
715fa7767c5Sopenharmony_ci    if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
716fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
717fa7767c5Sopenharmony_ci    }
718fa7767c5Sopenharmony_ci    auto param = Plugin::AnyCast<PortInfo>(parameter);
719fa7767c5Sopenharmony_ci    if (filter != demuxer_.get() || param.type != PortType::OUT) {
720fa7767c5Sopenharmony_ci        return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
721fa7767c5Sopenharmony_ci    }
722fa7767c5Sopenharmony_ci    std::vector<Filter*> newFilters;
723fa7767c5Sopenharmony_ci    for (const auto& portDesc : param.ports) {
724fa7767c5Sopenharmony_ci        if (portDesc.name.compare(0, 5, "video") == 0) { // 5 is length of "video"
725fa7767c5Sopenharmony_ci            MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
726fa7767c5Sopenharmony_ci            videoDecoder = FilterFactory::Instance().CreateFilterWithType<VideoDecoderFilter>(
727fa7767c5Sopenharmony_ci                "builtin.player.videodecoder", "videodecoder-" + portDesc.name);
728fa7767c5Sopenharmony_ci            if (pipeline_->AddFilters({videoDecoder.get()}) == ErrorCode::SUCCESS) {
729fa7767c5Sopenharmony_ci                // link demuxer and video decoder
730fa7767c5Sopenharmony_ci                auto fromPort = filter->GetOutPort(portDesc.name);
731fa7767c5Sopenharmony_ci                auto toPort = videoDecoder->GetInPort(PORT_NAME_DEFAULT);
732fa7767c5Sopenharmony_ci                FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort)); // link ports
733fa7767c5Sopenharmony_ci                newFilters.emplace_back(videoDecoder.get());
734fa7767c5Sopenharmony_ci
735fa7767c5Sopenharmony_ci                // link video decoder and video sink
736fa7767c5Sopenharmony_ci                if (pipeline_->AddFilters({videoSink.get()}) == ErrorCode::SUCCESS) {
737fa7767c5Sopenharmony_ci                    fromPort = videoDecoder->GetOutPort(PORT_NAME_DEFAULT);
738fa7767c5Sopenharmony_ci                    toPort = videoSink->GetInPort(PORT_NAME_DEFAULT);
739fa7767c5Sopenharmony_ci                    FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort)); // link ports
740fa7767c5Sopenharmony_ci                    newFilters.push_back(videoSink.get());
741fa7767c5Sopenharmony_ci                    mediaStats_.Append(videoSink->GetName());
742fa7767c5Sopenharmony_ci                }
743fa7767c5Sopenharmony_ci            }
744fa7767c5Sopenharmony_ci            break;
745fa7767c5Sopenharmony_ci        }
746fa7767c5Sopenharmony_ci    }
747fa7767c5Sopenharmony_ci    if (!newFilters.empty()) {
748fa7767c5Sopenharmony_ci        ActiveFilters(newFilters);
749fa7767c5Sopenharmony_ci    }
750fa7767c5Sopenharmony_ci    return ErrorCode::SUCCESS;
751fa7767c5Sopenharmony_ci}
752fa7767c5Sopenharmony_ci#endif
753fa7767c5Sopenharmony_ci
754fa7767c5Sopenharmony_ciErrorCode HiPlayerImpl::RemoveFilterChains(Filter* filter, const Plugin::Any& parameter)
755fa7767c5Sopenharmony_ci{
756fa7767c5Sopenharmony_ci    ErrorCode ret = ErrorCode::SUCCESS;
757fa7767c5Sopenharmony_ci    auto param = Plugin::AnyCast<PortInfo>(parameter);
758fa7767c5Sopenharmony_ci    if (filter != demuxer_.get() || param.type != PortType::OUT) {
759fa7767c5Sopenharmony_ci        return ret;
760fa7767c5Sopenharmony_ci    }
761fa7767c5Sopenharmony_ci    for (const auto& portDesc : param.ports) {
762fa7767c5Sopenharmony_ci        MEDIA_LOG_I("remove filter chain for port: " PUBLIC_LOG_S, portDesc.name.c_str());
763fa7767c5Sopenharmony_ci        auto peerPort = filter->GetOutPort(portDesc.name)->GetPeerPort();
764fa7767c5Sopenharmony_ci        if (peerPort) {
765fa7767c5Sopenharmony_ci            auto nextFilter = const_cast<Filter*>(reinterpret_cast<const Filter*>(peerPort->GetOwnerFilter()));
766fa7767c5Sopenharmony_ci            if (nextFilter) {
767fa7767c5Sopenharmony_ci                pipeline_->RemoveFilterChain(nextFilter);
768fa7767c5Sopenharmony_ci            }
769fa7767c5Sopenharmony_ci        }
770fa7767c5Sopenharmony_ci    }
771fa7767c5Sopenharmony_ci    return ret;
772fa7767c5Sopenharmony_ci}
773fa7767c5Sopenharmony_ci
774fa7767c5Sopenharmony_civoid HiPlayerImpl::ActiveFilters(const std::vector<Filter*>& filters)
775fa7767c5Sopenharmony_ci{
776fa7767c5Sopenharmony_ci    for (auto it = filters.rbegin(); it != filters.rend(); ++it) {
777fa7767c5Sopenharmony_ci        (*it)->Prepare();
778fa7767c5Sopenharmony_ci    }
779fa7767c5Sopenharmony_ci}
780fa7767c5Sopenharmony_ci
781fa7767c5Sopenharmony_ciPlayerStates HiPlayerImpl::TransStateId2PlayerState(StateId state)
782fa7767c5Sopenharmony_ci{
783fa7767c5Sopenharmony_ci    PlayerStates playerState = PLAYER_STATE_ERROR;
784fa7767c5Sopenharmony_ci    switch (state) {
785fa7767c5Sopenharmony_ci        case StateId::IDLE:
786fa7767c5Sopenharmony_ci            playerState = PLAYER_IDLE;
787fa7767c5Sopenharmony_ci            break;
788fa7767c5Sopenharmony_ci        case StateId::INIT:
789fa7767c5Sopenharmony_ci            playerState = PLAYER_INITIALIZED;
790fa7767c5Sopenharmony_ci            break;
791fa7767c5Sopenharmony_ci        case StateId::PREPARING:
792fa7767c5Sopenharmony_ci            playerState = PLAYER_PREPARING;
793fa7767c5Sopenharmony_ci            break;
794fa7767c5Sopenharmony_ci        case StateId::READY:
795fa7767c5Sopenharmony_ci            playerState = PLAYER_PREPARED;
796fa7767c5Sopenharmony_ci            break;
797fa7767c5Sopenharmony_ci        case StateId::PAUSE:
798fa7767c5Sopenharmony_ci            playerState = PLAYER_PAUSED;
799fa7767c5Sopenharmony_ci            break;
800fa7767c5Sopenharmony_ci        case StateId::PLAYING:
801fa7767c5Sopenharmony_ci            playerState = PLAYER_STARTED;
802fa7767c5Sopenharmony_ci            break;
803fa7767c5Sopenharmony_ci        case StateId::STOPPED:
804fa7767c5Sopenharmony_ci            playerState = PLAYER_STOPPED;
805fa7767c5Sopenharmony_ci            break;
806fa7767c5Sopenharmony_ci        case StateId::EOS:
807fa7767c5Sopenharmony_ci            playerState = PLAYER_PLAYBACK_COMPLETE;
808fa7767c5Sopenharmony_ci            break;
809fa7767c5Sopenharmony_ci        default:
810fa7767c5Sopenharmony_ci            break;
811fa7767c5Sopenharmony_ci    }
812fa7767c5Sopenharmony_ci    return playerState;
813fa7767c5Sopenharmony_ci}
814fa7767c5Sopenharmony_ci
815fa7767c5Sopenharmony_ciPlugin::SeekMode HiPlayerImpl::Transform2SeekMode(PlayerSeekMode mode)
816fa7767c5Sopenharmony_ci{
817fa7767c5Sopenharmony_ci    switch (mode) {
818fa7767c5Sopenharmony_ci        case PlayerSeekMode::PLAYER_SEEK_NEXT_SYNC:
819fa7767c5Sopenharmony_ci            return Plugin::SeekMode::SEEK_NEXT_SYNC;
820fa7767c5Sopenharmony_ci        case PlayerSeekMode::PLAYER_SEEK_PREVIOUS_SYNC:
821fa7767c5Sopenharmony_ci            return Plugin::SeekMode::SEEK_PREVIOUS_SYNC;
822fa7767c5Sopenharmony_ci        case PlayerSeekMode::PLAYER_SEEK_CLOSEST_SYNC:
823fa7767c5Sopenharmony_ci            return Plugin::SeekMode::SEEK_CLOSEST_SYNC;
824fa7767c5Sopenharmony_ci        case PlayerSeekMode::PLAYER_SEEK_CLOSEST:
825fa7767c5Sopenharmony_ci            return Plugin::SeekMode::SEEK_CLOSEST;
826fa7767c5Sopenharmony_ci        default:
827fa7767c5Sopenharmony_ci            return Plugin::SeekMode::SEEK_CLOSEST;
828fa7767c5Sopenharmony_ci    }
829fa7767c5Sopenharmony_ci}
830fa7767c5Sopenharmony_ci
831fa7767c5Sopenharmony_ciconst std::string& HiPlayerImpl::StringnessPlayerState(PlayerStates state)
832fa7767c5Sopenharmony_ci{
833fa7767c5Sopenharmony_ci    using StateString = std::pair<PlayerStates, std::string>;
834fa7767c5Sopenharmony_ci    const static std::array<StateString, 9> maps = { // array size
835fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_STATE_ERROR, "state error"),
836fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_IDLE, "idle"),
837fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_INITIALIZED, "init"),
838fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_PREPARING, "preparing"),
839fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_PREPARED, "prepared"),
840fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_STARTED, "started"),
841fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_PAUSED, "paused"),
842fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_STOPPED, "stopped"),
843fa7767c5Sopenharmony_ci        std::make_pair(PlayerStates::PLAYER_PLAYBACK_COMPLETE, "completed"),
844fa7767c5Sopenharmony_ci    };
845fa7767c5Sopenharmony_ci    const static std::string UNKNOWN = "unknown";
846fa7767c5Sopenharmony_ci    auto ite = std::find_if(maps.begin(), maps.end(), [&] (const StateString& item) -> bool {
847fa7767c5Sopenharmony_ci        return item.first == state;
848fa7767c5Sopenharmony_ci    });
849fa7767c5Sopenharmony_ci    if (ite == maps.end()) {
850fa7767c5Sopenharmony_ci        return UNKNOWN;
851fa7767c5Sopenharmony_ci    }
852fa7767c5Sopenharmony_ci    return ite->second;
853fa7767c5Sopenharmony_ci}
854fa7767c5Sopenharmony_ci} // namespace Media
855fa7767c5Sopenharmony_ci} // namespace OHOS
856