1 /*
2  * Copyright (c) 2021-2021 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 
16 #define HST_LOG_TAG "HiPlayerImpl"
17 
18 #include "hiplayer_impl.h"
19 #include <audio_info.h>
20 #include <av_common.h>
21 #include <media_errors.h>
22 #include "foundation/cpp_ext/type_traits_ext.h"
23 #include "foundation/log.h"
24 #include "foundation/utils/dump_buffer.h"
25 #include "foundation/utils/hitrace_utils.h"
26 #include "foundation/utils/steady_clock.h"
27 #include "media_utils.h"
28 #include "pipeline/factory/filter_factory.h"
29 #include "plugin/common/media_source.h"
30 #include "plugin/common/plugin_time.h"
31 
32 namespace {
33 const float MAX_MEDIA_VOLUME = 1.0f; // standard interface volume is between 0 to 1.
34 }
35 
36 namespace OHOS {
37 namespace Media {
38 using namespace Pipeline;
39 constexpr double EPSINON = 0.0001;
40 constexpr double SPEED_0_75_X = 0.75;
41 constexpr double SPEED_1_00_X = 1.00;
42 constexpr double SPEED_1_25_X = 1.25;
43 constexpr double SPEED_1_75_X = 1.75;
44 constexpr double SPEED_2_00_X = 2.00;
45 
HiPlayerImpl(int32_t appUid,int32_t appPid)46 HiPlayerImpl::HiPlayerImpl(int32_t appUid, int32_t appPid)
47     : appUid_(appUid),
48       appPid_(appPid),
49       volume_(-1.0f), // default negative, if app not set, will not set it.
50       mediaStats_()
51 {
52     SYNC_TRACER();
53     MEDIA_LOG_I("hiPlayerImpl ctor");
54     FilterFactory::Instance().Init();
55     syncManager_ = std::make_shared<MediaSyncManager>();
56 
57     audioSource_ =
58         FilterFactory::Instance().CreateFilterWithType<MediaSourceFilter>("builtin.player.mediasource", "mediaSource");
59 #ifdef UNIT_TEST
60     demuxer_ = FilterFactory::Instance().CreateFilterWithType<DemuxerFilter>("builtin.player.demuxer", "demuxer");
61     audioDecoder_ = FilterFactory::Instance().CreateFilterWithType<AudioDecoderFilter>("builtin.player.audiodecoder",
62                                                                                        "audiodecoder");
63     audioSink_ =
64         FilterFactory::Instance().CreateFilterWithType<AudioSinkFilter>("builtin.player.audiosink", "audiosink");
65 #else
66     demuxer_ = FilterFactory::Instance().CreateFilterWithType<DemuxerFilter>("builtin.player.demuxer", "demuxer");
67     audioSink_ =
68         FilterFactory::Instance().CreateFilterWithType<AudioSinkFilter>("builtin.player.audiosink", "audioSink");
69     audioSink_->SetParameter(static_cast<int32_t>(Plugin::Tag::APP_PID), appPid_);
70     audioSink_->SetParameter(static_cast<int32_t>(Plugin::Tag::APP_UID), appUid_);
71 #ifdef VIDEO_SUPPORT
72     videoSink_ =
73         FilterFactory::Instance().CreateFilterWithType<VideoSinkFilter>("builtin.player.videosink", "videoSink");
74     FALSE_RETURN(videoSink_ != nullptr);
75     videoSink_->SetSyncCenter(syncManager_);
76 #endif
77 #endif
78     FALSE_RETURN(audioSource_ != nullptr);
79     FALSE_RETURN(demuxer_ != nullptr);
80     FALSE_RETURN(audioSink_ != nullptr);
81     audioSink_->SetSyncCenter(syncManager_);
82     pipeline_ = std::make_shared<PipelineCore>();
83     callbackLooper_.SetPlayEngine(this);
84 }
85 
~HiPlayerImpl()86 HiPlayerImpl::~HiPlayerImpl()
87 {
88     MEDIA_LOG_I("dtor called.");
89     if (pipelineStates_ != PLAYER_STOPPED) {
90         DoStop();
91         HiPlayerImpl::OnStateChanged(StateId::STOPPED);
92     }
93     callbackLooper_.Stop();
94     audioSink_.reset();
95 #ifdef VIDEO_SUPPORT
96     videoSink_.reset();
97 #endif
98     syncManager_.reset();
99 }
UpdateStateNoLock(PlayerStates newState,bool notifyUpward)100 void HiPlayerImpl::UpdateStateNoLock(PlayerStates newState, bool notifyUpward)
101 {
102     if (pipelineStates_ == newState) {
103         return;
104     }
105     pipelineStates_ = newState;
106     if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_PREPARING) {
107         MEDIA_LOG_W("do not report idle and preparing since av player doesn't need report idle and preparing");
108         return;
109     }
110     if (notifyUpward) {
111         if (callbackLooper_.IsStarted()) {
112             Format format;
113             while (!pendingStates_.empty()) {
114                 auto pendingState = pendingStates_.front();
115                 pendingStates_.pop();
116                 MEDIA_LOG_I("sending pending state change: " PUBLIC_LOG_S, StringnessPlayerState(pendingState).c_str());
117                 callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE, pendingState, format);
118             }
119             MEDIA_LOG_I("sending newest state change: " PUBLIC_LOG_S,
120                         StringnessPlayerState(pipelineStates_.load()).c_str());
121             callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE, pipelineStates_, format);
122         } else {
123             pendingStates_.push(newState);
124         }
125     }
126 }
127 
Init()128 ErrorCode HiPlayerImpl::Init()
129 {
130     MEDIA_LOG_I("Init entered.");
131     mediaStats_.Reset();
132     if (initialized_.load()) {
133         return ErrorCode::SUCCESS;
134     }
135     pipeline_->Init(this, this);
136     ErrorCode ret = pipeline_->AddFilters({audioSource_.get(), demuxer_.get()});
137     if (ret == ErrorCode::SUCCESS) {
138         ret = pipeline_->LinkFilters({audioSource_.get(), demuxer_.get()});
139     }
140     if (ret == ErrorCode::SUCCESS) {
141         initialized_ = true;
142     } else {
143         pipeline_->RemoveFilterChain(audioSource_.get());
144         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
145     }
146     return ret;
147 }
148 
SetSource(const std::string & uri)149 int32_t HiPlayerImpl::SetSource(const std::string& uri)
150 {
151     SYNC_TRACER();
152     MEDIA_LOG_I("SetSource entered source uri: " PUBLIC_LOG_S, uri.c_str());
153     PROFILE_BEGIN("SetSource begin");
154     auto ret = Init();
155     if (ret == ErrorCode::SUCCESS) {
156         ret = DoSetSource(std::make_shared<MediaSource>(uri));
157         url_ = uri;
158     }
159     if (ret != ErrorCode::SUCCESS) {
160         MEDIA_LOG_E("SetSource error: " PUBLIC_LOG_S, GetErrorName(ret));
161     } else {
162         OnStateChanged(StateId::INIT);
163     }
164     PROFILE_END("SetSource end.");
165     return TransErrorCode(ret);
166 }
167 
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)168 int32_t HiPlayerImpl::SetSource(const std::shared_ptr<IMediaDataSource>& dataSrc)
169 {
170     MEDIA_LOG_I("SetSource entered source stream");
171     PROFILE_BEGIN("SetSource begin");
172     auto ret = Init();
173     if (ret == ErrorCode::SUCCESS) {
174         ret = DoSetSource(std::make_shared<MediaSource>(dataSrc));
175     }
176     if (ret != ErrorCode::SUCCESS) {
177         MEDIA_LOG_E("SetSource error: " PUBLIC_LOG_S, GetErrorName(ret));
178     } else {
179         OnStateChanged(StateId::INIT);
180     }
181     PROFILE_END("SetSource end.");
182     return TransErrorCode(ret);
183 }
184 
Prepare()185 int32_t HiPlayerImpl::Prepare()
186 {
187     DUMP_BUFFER2FILE_PREPARE();
188     if (!(pipelineStates_ == PlayerStates::PLAYER_INITIALIZED || pipelineStates_ == PlayerStates::PLAYER_STOPPED)) {
189         return MSERR_INVALID_OPERATION;
190     }
191     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
192         SetSource(url_);
193     }
194     SYNC_TRACER();
195     NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_START, 0);
196     MEDIA_LOG_I("Prepare entered, current pipeline state: " PUBLIC_LOG_S ".",
197         StringnessPlayerState(pipelineStates_).c_str());
198     PROFILE_BEGIN();
199     auto ret = PrepareFilters();
200     if (ret != ErrorCode::SUCCESS) {
201         PROFILE_END("Prepare failed,");
202         MEDIA_LOG_E("Prepare failed with error " PUBLIC_LOG_D32, ret);
203         return TransErrorCode(ret);
204     }
205     OnStateChanged(StateId::PREPARING);
206     OSAL::ScopedLock lock(stateMutex_);
207     if (pipelineStates_ == PlayerStates::PLAYER_PREPARING) { // Wait state change to ready
208         cond_.Wait(lock, [this] { return pipelineStates_ != PlayerStates::PLAYER_PREPARING; });
209     }
210     MEDIA_LOG_D("Prepare finished, current pipeline state: " PUBLIC_LOG "s.",
211         StringnessPlayerState(pipelineStates_).c_str());
212     PROFILE_END("Prepare finished, current pipeline state: " PUBLIC_LOG "s.",
213         StringnessPlayerState(pipelineStates_).c_str());
214     if (pipelineStates_ == PlayerStates::PLAYER_PREPARED) {
215         NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_END, 0);
216         Format format;
217         callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, 0, format);
218         return TransErrorCode(ErrorCode::SUCCESS);
219     }
220 
221     return TransErrorCode(ErrorCode::ERROR_UNKNOWN);
222 }
223 
PrepareAsync()224 int HiPlayerImpl::PrepareAsync()
225 {
226     DUMP_BUFFER2FILE_PREPARE();
227     if (!(pipelineStates_ == PlayerStates::PLAYER_INITIALIZED || pipelineStates_ == PlayerStates::PLAYER_STOPPED)) {
228         return MSERR_INVALID_OPERATION;
229     }
230     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
231         SetSource(url_);
232     }
233     ASYNC_TRACER();
234     NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_START, 0);
235     MEDIA_LOG_I("Prepare async entered, current pipeline state: " PUBLIC_LOG_S,
236         StringnessPlayerState(pipelineStates_).c_str());
237     PROFILE_BEGIN();
238     auto ret = PrepareFilters();
239     if (ret != ErrorCode::SUCCESS) {
240         PROFILE_END("Prepare async failed,");
241         MEDIA_LOG_E("Prepare async failed with error " PUBLIC_LOG_D32, ret);
242     } else {
243         PROFILE_END("Prepare async successfully,");
244     }
245     OnStateChanged(StateId::PREPARING);
246     NotifyBufferingUpdate(PlayerKeys::PLAYER_BUFFERING_END, 0);
247     return TransErrorCode(ret);
248 }
249 
Play()250 int32_t HiPlayerImpl::Play()
251 {
252     SYNC_TRACER();
253     MEDIA_LOG_I("Play entered.");
254     PROFILE_BEGIN();
255     auto ret {ErrorCode::SUCCESS};
256     callbackLooper_.StartReportMediaProgress(100); // 100 MS
257     if (pipelineStates_ == PlayerStates::PLAYER_PLAYBACK_COMPLETE) {
258         ret = DoSeek(0, Plugin::SeekMode::SEEK_PREVIOUS_SYNC);
259     } else if (pipelineStates_ == PlayerStates::PLAYER_PAUSED) {
260         ret = DoResume();
261     } else {
262         ret = DoPlay();
263     }
264     if (ret == ErrorCode::SUCCESS) {
265         OnStateChanged(StateId::PLAYING);
266     }
267     PROFILE_END("Play ret = " PUBLIC_LOG_D32, TransErrorCode(ret));
268     return TransErrorCode(ret);
269 }
270 
Pause()271 int32_t HiPlayerImpl::Pause()
272 {
273     SYNC_TRACER();
274     MEDIA_LOG_I("Pause entered.");
275     PROFILE_BEGIN();
276     auto ret = TransErrorCode(DoPause());
277     callbackLooper_.StopReportMediaProgress();
278     callbackLooper_.ManualReportMediaProgressOnce();
279     OnStateChanged(StateId::PAUSE);
280     PROFILE_END("Pause ret = " PUBLIC_LOG_D32, ret);
281     return ret;
282 }
283 
Stop()284 int32_t HiPlayerImpl::Stop()
285 {
286     SYNC_TRACER();
287     MEDIA_LOG_I("Stop entered.");
288     PROFILE_BEGIN();
289     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
290         return TransErrorCode(ErrorCode::SUCCESS);
291     }
292     auto ret = TransErrorCode(DoStop());
293     OnStateChanged(StateId::STOPPED);
294     callbackLooper_.StopReportMediaProgress();
295     callbackLooper_.ManualReportMediaProgressOnce();
296     PROFILE_END("Stop ret = " PUBLIC_LOG_D32, ret);
297     return ret;
298 }
299 
StopAsync()300 ErrorCode HiPlayerImpl::StopAsync()
301 {
302     MEDIA_LOG_I("StopAsync entered.");
303     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
304         return ErrorCode::SUCCESS;
305     }
306     ErrorCode ret = DoStop();
307     OnStateChanged(StateId::STOPPED);
308     return ret;
309 }
310 
Seek(int32_t mSeconds,PlayerSeekMode mode)311 int32_t HiPlayerImpl::Seek(int32_t mSeconds, PlayerSeekMode mode)
312 {
313     SYNC_TRACER();
314     MEDIA_LOG_I("Seek entered. mSeconds : " PUBLIC_LOG_D32 ", seekMode : " PUBLIC_LOG_D32,
315                 mSeconds, static_cast<int32_t>(mode));
316     int64_t hstTime = 0;
317     int32_t durationMs = 0;
318     NZERO_RETURN(GetDuration(durationMs));
319     MEDIA_LOG_D("Seek durationMs : " PUBLIC_LOG_D32, durationMs);
320     if (mSeconds >= durationMs) { // if exceeds change to duration
321         mSeconds = durationMs;
322     }
323     mSeconds = mSeconds < 0 ? 0 : mSeconds;
324     if (audioSource_->GetSeekable() != Plugin::Seekable::SEEKABLE) {
325         MEDIA_LOG_E("Seek, invalid operation, audio source is unseekable or invalid");
326         return MSERR_INVALID_OPERATION;
327     }
328     if (!Plugin::Ms2HstTime(mSeconds, hstTime)) {
329         return TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE);
330     }
331     auto smode = Transform2SeekMode(mode);
332     auto ret = DoSeek(hstTime, smode);
333     return TransErrorCode(ret);
334 }
335 
SetVolume(float leftVolume,float rightVolume)336 int32_t HiPlayerImpl::SetVolume(float leftVolume, float rightVolume)
337 {
338     MEDIA_LOG_I("SetVolume entered.");
339     if (leftVolume < 0 || leftVolume > MAX_MEDIA_VOLUME || rightVolume < 0 || rightVolume > MAX_MEDIA_VOLUME) {
340         MEDIA_LOG_E("volume not valid, should be in range [0,100]");
341         return TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE);
342     }
343     float volume = 0.0f;
344     if (leftVolume < 1e-6 && rightVolume >= 1e-6) {  // 1e-6
345         volume = rightVolume;
346     } else if (rightVolume < 1e-6 && leftVolume >= 1e-6) {  // 1e-6
347         volume = leftVolume;
348     } else {
349         volume = (leftVolume + rightVolume) / 2;  // 2
350     }
351     volume /= MAX_MEDIA_VOLUME;  // normalize to 0~1
352     volume_ = volume;
353     if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_INITIALIZED ||
354         pipelineStates_ == PlayerStates::PLAYER_PREPARING || pipelineStates_ == PlayerStates::PLAYER_STOPPED ||
355         audioSink_ == nullptr) {
356         MEDIA_LOG_W("cannot set volume, will do this onReady");
357         return TransErrorCode(ErrorCode::SUCCESS);
358     }
359     return TransErrorCode(SetVolumeToSink(volume));
360 }
361 
SetVideoSurface(sptr<Surface> surface)362 int32_t HiPlayerImpl::SetVideoSurface(sptr<Surface> surface)
363 {
364     MEDIA_LOG_D("SetVideoSurface entered.");
365 #ifdef VIDEO_SUPPORT
366     FALSE_RETURN_V_MSG_E(surface != nullptr, TransErrorCode(ErrorCode::ERROR_INVALID_PARAMETER_VALUE),
367                          "Set video surface failed, surface == nullptr");
368     return TransErrorCode(videoSink_->SetVideoSurface(surface));
369 #else
370     return TransErrorCode(ErrorCode::SUCCESS);
371 #endif
372 }
373 
GetVideoTrackInfo(std::vector<Format> & videoTrack)374 int32_t HiPlayerImpl::GetVideoTrackInfo(std::vector<Format>& videoTrack)
375 {
376     MEDIA_LOG_I("GetVideoTrackInfo entered.");
377     std::string mime;
378     std::vector<std::shared_ptr<Plugin::Meta>> metaInfo = demuxer_->GetStreamMetaInfo();
379     for (const auto& trackInfo : metaInfo) {
380         if (trackInfo->Get<Plugin::Tag::MIME>(mime)) {
381             if (IsVideoMime(mime)) {
382                 int64_t bitRate;
383                 uint32_t frameRate;
384                 uint32_t height;
385                 uint32_t width;
386                 uint32_t trackIndex;
387                 Format videoTrackInfo {};
388                 (void)videoTrackInfo.PutStringValue("codec_mime", mime);
389                 (void)videoTrackInfo.PutIntValue("track_type", MediaType::MEDIA_TYPE_VID);
390                 if (trackInfo->Get<Plugin::Tag::TRACK_ID>(trackIndex)) {
391                     (void)videoTrackInfo.PutIntValue("track_index", static_cast<int32_t>(trackIndex));
392                 } else {
393                     MEDIA_LOG_W("Get TRACK_ID failed.");
394                 }
395                 if (trackInfo->Get<Plugin::Tag::MEDIA_BITRATE>(bitRate)) {
396                     (void)videoTrackInfo.PutIntValue("bitrate", static_cast<int32_t>(bitRate));
397                 } else {
398                     MEDIA_LOG_W("Get MEDIA_BITRATE fail");
399                 }
400                 if (trackInfo->Get<Plugin::Tag::VIDEO_FRAME_RATE>(frameRate)) {
401                     (void)videoTrackInfo.PutIntValue("frame_rate", static_cast<int32_t>(frameRate));
402                 } else {
403                     MEDIA_LOG_W("Get VIDEO_FRAME_RATE fail");
404                 }
405                 if (trackInfo->Get<Plugin::Tag::VIDEO_HEIGHT>(height)) {
406                     (void)videoTrackInfo.PutIntValue("height", static_cast<int32_t>(height));
407                 } else {
408                     MEDIA_LOG_W("Get VIDEO_HEIGHT fail");
409                 }
410                 if (trackInfo->Get<Plugin::Tag::VIDEO_WIDTH>(width)) {
411                     (void)videoTrackInfo.PutIntValue("width", static_cast<int32_t>(width));
412                 } else {
413                     MEDIA_LOG_W("Get VIDEO_WIDTH failed.");
414                 }
415                 videoTrack.push_back(videoTrackInfo);
416             }
417         } else {
418             MEDIA_LOG_W("Get MIME fail");
419         }
420     }
421     return TransErrorCode(ErrorCode::SUCCESS);
422 }
423 
GetAudioTrackInfo(std::vector<Format> & audioTrack)424 int32_t HiPlayerImpl::GetAudioTrackInfo(std::vector<Format>& audioTrack)
425 {
426     MEDIA_LOG_I("GetAudioTrackInfo entered.");
427     std::string mime;
428     std::vector<std::shared_ptr<Plugin::Meta>> metaInfo = demuxer_->GetStreamMetaInfo();
429     for (const auto& trackInfo : metaInfo) {
430         if (trackInfo->Get<Plugin::Tag::MIME>(mime)) {
431             if (IsAudioMime(mime)) {
432                 int64_t bitRate;
433                 uint32_t audioChannels;
434                 uint32_t audioSampleRate;
435                 uint32_t trackIndex;
436                 Format audioTrackInfo {};
437                 (void)audioTrackInfo.PutStringValue("codec_mime", mime);
438                 (void)audioTrackInfo.PutIntValue("track_type", MediaType::MEDIA_TYPE_AUD);
439                 if (trackInfo->Get<Plugin::Tag::TRACK_ID>(trackIndex)) {
440                     (void)audioTrackInfo.PutIntValue("track_index", static_cast<int32_t>(trackIndex));
441                 } else {
442                     MEDIA_LOG_I("Get TRACK_ID failed.");
443                 }
444                 if (trackInfo->Get<Plugin::Tag::MEDIA_BITRATE>(bitRate)) {
445                     (void)audioTrackInfo.PutIntValue("bitrate", static_cast<int32_t>(bitRate));
446                 } else {
447                     MEDIA_LOG_I("Get MEDIA_BITRATE fail");
448                 }
449                 if (trackInfo->Get<Plugin::Tag::AUDIO_CHANNELS>(audioChannels)) {
450                     (void)audioTrackInfo.PutIntValue("channel_count", static_cast<int32_t>(audioChannels));
451                 } else {
452                     MEDIA_LOG_I("Get AUDIO_CHANNELS fail");
453                 }
454                 if (trackInfo->Get<Plugin::Tag::AUDIO_SAMPLE_RATE>(audioSampleRate)) {
455                     (void)audioTrackInfo.PutIntValue("sample_rate", static_cast<int32_t>(audioSampleRate));
456                 } else {
457                     MEDIA_LOG_I("Get AUDIO_SAMPLE_RATE fail");
458                 }
459                 audioTrack.push_back(audioTrackInfo);
460             }
461         } else {
462             MEDIA_LOG_W("Get MIME fail");
463         }
464     }
465     return TransErrorCode(ErrorCode::SUCCESS);
466 }
467 
GetVideoWidth()468 int32_t HiPlayerImpl::GetVideoWidth()
469 {
470     MEDIA_LOG_I("GetVideoWidth entered. video width: " PUBLIC_LOG_D32, videoWidth_);
471     return videoWidth_;
472 }
473 
GetVideoHeight()474 int32_t HiPlayerImpl::GetVideoHeight()
475 {
476     MEDIA_LOG_I("GetVideoHeight entered. video height: " PUBLIC_LOG_D32, videoHeight_);
477     return videoHeight_;
478 }
479 
HandleErrorEvent(const Event & event)480 void HiPlayerImpl::HandleErrorEvent(const Event& event)
481 {
482     ErrorCode errorCode = ErrorCode::ERROR_UNKNOWN;
483     if (Plugin::Any::IsSameTypeWith<ErrorCode>(event.param)) {
484         errorCode = Plugin::AnyCast<ErrorCode>(event.param);
485     }
486     DoOnError(errorCode);
487 }
488 
HandleReadyEvent()489 void HiPlayerImpl::HandleReadyEvent()
490 {
491     ErrorCode errorCode = DoOnReady();
492     if (errorCode == ErrorCode::SUCCESS) {
493         OnStateChanged(StateId::READY);
494         Format format;
495         callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, 0, format);
496     } else {
497         OnStateChanged(StateId::INIT);
498     }
499 }
500 
HandleCompleteEvent(const Event & event)501 void HiPlayerImpl::HandleCompleteEvent(const Event& event)
502 {
503     mediaStats_.ReceiveEvent(event);
504     if (mediaStats_.IsEventCompleteAllReceived()) {
505         DoOnComplete();
506     }
507 }
508 
HandlePluginErrorEvent(const Event & event)509 void HiPlayerImpl::HandlePluginErrorEvent(const Event& event)
510 {
511     Plugin::PluginEvent pluginEvent = Plugin::AnyCast<Plugin::PluginEvent>(event.param);
512     MEDIA_LOG_I("Receive PLUGIN_ERROR, type:  " PUBLIC_LOG_D32, CppExt::to_underlying(pluginEvent.type));
513     if (pluginEvent.type == Plugin::PluginEventType::CLIENT_ERROR &&
514             Plugin::Any::IsSameTypeWith<Plugin::NetworkClientErrorCode>(pluginEvent.param)) {
515         auto netClientErrorCode = Plugin::AnyCast<Plugin::NetworkClientErrorCode>(pluginEvent.param);
516         auto errorType {PlayerErrorType::PLAYER_ERROR_UNKNOWN};
517         auto serviceErrCode { MSERR_UNKNOWN };
518         if (netClientErrorCode == Plugin::NetworkClientErrorCode::ERROR_TIME_OUT) {
519             errorType = PlayerErrorType::PLAYER_ERROR;
520             serviceErrCode = MSERR_NETWORK_TIMEOUT;
521         }
522         callbackLooper_.OnError(errorType, serviceErrCode);
523     }
524 }
525 
OnEvent(const Event & event)526 void HiPlayerImpl::OnEvent(const Event& event)
527 {
528     if (event.type != EventType::EVENT_AUDIO_PROGRESS) {
529         MEDIA_LOG_I("[HiStreamer] OnEvent (" PUBLIC_LOG_S ")", GetEventName(event.type));
530     }
531     switch (event.type) {
532         case EventType::EVENT_ERROR: {
533             HandleErrorEvent(event);
534             break;
535         }
536         case EventType::EVENT_READY: {
537             HandleReadyEvent();
538             break;
539         }
540         case EventType::EVENT_COMPLETE: {
541             HandleCompleteEvent(event);
542             break;
543         }
544         case EventType::EVENT_PLUGIN_ERROR: {
545             HandlePluginErrorEvent(event);
546             break;
547         }
548         case EventType::EVENT_RESOLUTION_CHANGE: {
549             HandleResolutionChangeEvent(event);
550             break;
551         }
552         case EventType::EVENT_PLUGIN_EVENT: {
553             HandlePluginEvent(event);
554             break;
555         }
556         case EventType::EVENT_VIDEO_RENDERING_START: {
557             Format format;
558             callbackLooper_.OnInfo(INFO_TYPE_MESSAGE, PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START, format);
559             break;
560         }
561         case EventType::EVENT_IS_LIVE_STREAM: {
562             Format format;
563             callbackLooper_.OnInfo(INFO_TYPE_IS_LIVE_STREAM, 0, format);
564             break;
565         }
566         default:
567             MEDIA_LOG_E("Unknown event(" PUBLIC_LOG_U32 ")", event.type);
568     }
569 }
570 
DoSetSource(const std::shared_ptr<MediaSource> & source)571 ErrorCode HiPlayerImpl::DoSetSource(const std::shared_ptr<MediaSource>& source)
572 {
573     auto ret = audioSource_->SetSource(source);
574     if (ret != ErrorCode::SUCCESS) {
575         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
576     }
577     return ret;
578 }
579 
PrepareFilters()580 ErrorCode HiPlayerImpl::PrepareFilters()
581 {
582     auto ret = pipeline_->Prepare();
583     if (ret != ErrorCode::SUCCESS) {
584         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
585     }
586     return ret;
587 }
588 
DoPlay()589 ErrorCode HiPlayerImpl::DoPlay()
590 {
591     syncManager_->Resume();
592     auto ret = pipeline_->Start();
593     if (ret != ErrorCode::SUCCESS) {
594         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
595     }
596     return ret;
597 }
598 
DoPause()599 ErrorCode HiPlayerImpl::DoPause()
600 {
601     auto ret = pipeline_->Pause();
602     syncManager_->Pause();
603     if (ret != ErrorCode::SUCCESS) {
604         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
605     }
606     return ret;
607 }
608 
DoResume()609 ErrorCode HiPlayerImpl::DoResume()
610 {
611     syncManager_->Resume();
612     auto ret = pipeline_->Resume();
613     if (ret != ErrorCode::SUCCESS) {
614         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
615     }
616     return ret;
617 }
618 
DoStop()619 ErrorCode HiPlayerImpl::DoStop()
620 {
621     DUMP_BUFFER2FILE_END();
622     mediaStats_.Reset();
623     // 先关闭demuxer线程,防止元数据解析prepare过程中出现并发问题
624     if (demuxer_) {
625         demuxer_->StopTask(false);
626     }
627     auto ret = pipeline_->Stop();
628     syncManager_->Reset();
629     if (ret != ErrorCode::SUCCESS) {
630         UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
631     }
632     return ret;
633 }
634 
DoReset()635 ErrorCode HiPlayerImpl::DoReset()
636 {
637     return DoStop();
638 }
639 
DoSeek(int64_t hstTime,Plugin::SeekMode mode)640 ErrorCode HiPlayerImpl::DoSeek(int64_t hstTime, Plugin::SeekMode mode)
641 {
642     SYNC_TRACER();
643     PROFILE_BEGIN();
644     int64_t seekPos = hstTime;
645     Plugin::SeekMode seekMode = mode;
646     auto rtv = seekPos >= 0 ? ErrorCode::SUCCESS : ErrorCode::ERROR_INVALID_OPERATION;
647     if (rtv == ErrorCode::SUCCESS) {
648         pipeline_->FlushStart();
649         PROFILE_END("Flush start");
650         PROFILE_RESET();
651 
652         MEDIA_LOG_I("Do seek ...");
653         int64_t realSeekTime = seekPos;
654         rtv = demuxer_->SeekTo(seekPos, seekMode, realSeekTime);
655         if (rtv == ErrorCode::SUCCESS) {
656             syncManager_->Seek(realSeekTime);
657         }
658         PROFILE_END("SeekTo");
659 
660         pipeline_->FlushEnd();
661         PROFILE_END("Flush end");
662         PROFILE_RESET();
663     }
664     if (rtv != ErrorCode::SUCCESS) {
665         callbackLooper_.OnError(PLAYER_ERROR, MSERR_SEEK_FAILED);
666         MEDIA_LOG_E("Seek done, seek error.");
667     } else {
668         Format format;
669         int64_t currentPos = Plugin::HstTime2Ms(seekPos);
670         MEDIA_LOG_I("Seek done, currentPos : " PUBLIC_LOG_D64, currentPos);
671         callbackLooper_.OnInfo(INFO_TYPE_SEEKDONE, static_cast<int32_t>(currentPos), format);
672         callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, static_cast<int32_t>(currentPos), format);
673     }
674 
675     return rtv;
676 }
677 
DoOnReady()678 ErrorCode HiPlayerImpl::DoOnReady()
679 {
680     SetVolumeToSink(volume_, false); // do not report
681     auto tmpMeta = demuxer_->GetGlobalMetaInfo();
682     sourceMeta_ = tmpMeta;
683     int64_t duration = 0;
684     bool found = false;
685     if (tmpMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(duration)) {
686         found = true;
687     } else {
688         MEDIA_LOG_W("Get media duration failed.");
689     }
690     streamMeta_.clear();
691     int64_t tmp = 0;
692     for (auto& streamMeta : demuxer_->GetStreamMetaInfo()) {
693         streamMeta_.push_back(streamMeta);
694         if (streamMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(tmp)) {
695             duration = std::max(duration, tmp);
696             found = true;
697         } else {
698             MEDIA_LOG_W("Get media duration failed.");
699         }
700     }
701     if (found) {
702         duration_ = duration;
703         Format format;
704         callbackLooper_.OnInfo(INFO_TYPE_DURATION_UPDATE, Plugin::HstTime2Ms(duration_), format);
705     } else {
706         MEDIA_LOG_E("INFO_TYPE_DURATION_UPDATE failed");
707     }
708     return ErrorCode::SUCCESS;
709 }
710 
DoOnComplete()711 ErrorCode HiPlayerImpl::DoOnComplete()
712 {
713     MEDIA_LOG_I("OnComplete looping: " PUBLIC_LOG_D32 ".", singleLoop_.load());
714     Format format;
715     if (singleLoop_.load()) {
716         callbackLooper_.OnInfo(INFO_TYPE_EOS, static_cast<int32_t>(singleLoop_.load()), format);
717     } else {
718         OnStateChanged(StateId::EOS);
719         callbackLooper_.StopReportMediaProgress();
720         callbackLooper_.ManualReportMediaProgressOnce();
721     }
722     mediaStats_.ResetEventCompleteAllReceived();
723     return ErrorCode::SUCCESS;
724 }
725 
DoOnError(ErrorCode errorCode)726 ErrorCode HiPlayerImpl::DoOnError(ErrorCode errorCode)
727 {
728     UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
729     callbackLooper_.OnError(PLAYER_ERROR, TransErrorCode(errorCode));
730     return ErrorCode::SUCCESS;
731 }
732 
SetVolumeToSink(float volume,bool reportUpward)733 ErrorCode HiPlayerImpl::SetVolumeToSink(float volume, bool reportUpward)
734 {
735     MEDIA_LOG_I("SetVolumeToSink entered.");
736     ErrorCode ret = ErrorCode::SUCCESS;
737     if (volume_ >= 0) {
738         MEDIA_LOG_I("set volume " PUBLIC_LOG_F, volume);
739         ret = audioSink_->SetVolume(volume);
740     }
741 
742     if (ret != ErrorCode::SUCCESS) {
743         MEDIA_LOG_E("SetVolume failed with error " PUBLIC_LOG_D32, static_cast<int>(ret));
744         callbackLooper_.OnError(PLAYER_ERROR, TransErrorCode(ret));
745     } else if (reportUpward) {
746         Format format;
747         callbackLooper_.OnInfo(INFO_TYPE_VOLUME_CHANGE, volume, format);
748     }
749     return ret;
750 }
751 
CreateAudioDecoder(const std::string & desc)752 PFilter HiPlayerImpl::CreateAudioDecoder(const std::string& desc)
753 {
754     if (!audioDecoderMap_[desc]) {
755         audioDecoderMap_[desc] = FilterFactory::Instance().CreateFilterWithType<AudioDecoderFilter>(
756             "builtin.player.audiodecoder", "audiodecoder-" + desc);
757         // set parameters to decoder.
758     }
759     return audioDecoderMap_[desc];
760 }
761 
SetLooping(bool loop)762 int32_t HiPlayerImpl::SetLooping(bool loop)
763 {
764     MEDIA_LOG_I("SetLooping entered, loop: " PUBLIC_LOG_D32, loop);
765     singleLoop_ = loop;
766     return TransErrorCode(ErrorCode::SUCCESS);
767 }
768 
SetParameter(const Format & params)769 int32_t HiPlayerImpl::SetParameter(const Format& params)
770 {
771     MEDIA_LOG_I("SetParameter entered.");
772     if (params.ContainKey(PlayerKeys::VIDEO_SCALE_TYPE)) {
773         int32_t videoScaleType = 0;
774         params.GetIntValue(PlayerKeys::VIDEO_SCALE_TYPE, videoScaleType);
775         return SetVideoScaleType(VideoScaleType(videoScaleType));
776     }
777     if (params.ContainKey(PlayerKeys::CONTENT_TYPE) && params.ContainKey(PlayerKeys::STREAM_USAGE)) {
778         int32_t contentType;
779         int32_t streamUsage;
780         int32_t rendererFlag;
781         params.GetIntValue(PlayerKeys::CONTENT_TYPE, contentType);
782         params.GetIntValue(PlayerKeys::STREAM_USAGE, streamUsage);
783         params.GetIntValue(PlayerKeys::RENDERER_FLAG, rendererFlag);
784         return SetAudioRendererInfo(contentType, streamUsage, rendererFlag);
785     }
786     if (params.ContainKey(PlayerKeys::AUDIO_INTERRUPT_MODE)) {
787         int32_t interruptMode = 0;
788         params.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
789         return SetAudioInterruptMode(interruptMode);
790     }
791     return TransErrorCode(ErrorCode::ERROR_UNIMPLEMENTED);
792 }
793 
SetObs(const std::weak_ptr<IPlayerEngineObs> & obs)794 int32_t HiPlayerImpl::SetObs(const std::weak_ptr<IPlayerEngineObs>& obs)
795 {
796     MEDIA_LOG_I("SetObs entered.");
797     callbackLooper_.StartWithPlayerEngineObs(obs);
798     return TransErrorCode(ErrorCode::SUCCESS);
799 }
800 
Reset()801 int32_t HiPlayerImpl::Reset()
802 {
803     MEDIA_LOG_I("Reset entered.");
804     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
805         return TransErrorCode(ErrorCode::SUCCESS);
806     }
807     singleLoop_ = false;
808     mediaStats_.Reset();
809     auto ret = DoReset();
810     OnStateChanged(StateId::STOPPED);
811     return TransErrorCode(ret);
812 }
813 
GetCurrentTime(int32_t & currentPositionMs)814 int32_t HiPlayerImpl::GetCurrentTime(int32_t& currentPositionMs)
815 {
816     currentPositionMs = Plugin::HstTime2Ms(syncManager_->GetMediaTimeNow());
817     return TransErrorCode(ErrorCode::SUCCESS);
818 }
819 
GetDuration(int32_t & durationMs)820 int32_t HiPlayerImpl::GetDuration(int32_t& durationMs)
821 {
822     durationMs = 0;
823     if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_PREPARING ||
824         audioSource_ == nullptr) {
825         MEDIA_LOG_E("GetDuration, invalid state or audioSource_ is null. state: " PUBLIC_LOG_S,
826                     StringnessPlayerState(pipelineStates_).c_str());
827         return MSERR_INVALID_STATE;
828     }
829     if (duration_ < 0) {
830         durationMs = -1;
831         MEDIA_LOG_W("no valid duration");
832         return MSERR_UNKNOWN;
833     }
834     durationMs = Plugin::HstTime2Ms(duration_);
835     MEDIA_LOG_DD("GetDuration returned " PUBLIC_LOG_D32, durationMs);
836     return MSERR_OK;
837 }
838 
SetPlaybackSpeed(PlaybackRateMode mode)839 int32_t HiPlayerImpl::SetPlaybackSpeed(PlaybackRateMode mode)
840 {
841     MEDIA_LOG_I("SetPlaybackSpeed entered.");
842     double playbackSpeed = ChangeModeToSpeed(mode);
843     demuxer_->SetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_PLAYBACK_SPEED), playbackSpeed);
844     Format format;
845     callbackLooper_.OnInfo(INFO_TYPE_SPEEDDONE, 0, format);
846 
847     int32_t currentPosMs = 0;
848     int32_t durationMs = 0;
849     NZERO_RETURN(GetDuration(durationMs));
850     NZERO_RETURN(GetCurrentTime(currentPosMs));
851     currentPosMs = std::min(currentPosMs, durationMs);
852     currentPosMs = currentPosMs < 0 ? 0 : currentPosMs;
853     callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, currentPosMs, format);
854     MEDIA_LOG_D("SetPlaybackSpeed entered end.");
855     return MSERR_OK;
856 }
GetPlaybackSpeed(PlaybackRateMode & mode)857 int32_t HiPlayerImpl::GetPlaybackSpeed(PlaybackRateMode& mode)
858 {
859     MEDIA_LOG_I("GetPlaybackSpeed entered.");
860     Plugin::Any any;
861     demuxer_->GetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_PLAYBACK_SPEED), any);
862     auto playbackSpeed = Plugin::AnyCast<double>(any);
863     mode = ChangeSpeedToMode(playbackSpeed);
864     return MSERR_OK;
865 }
866 
OnStateChanged(StateId state)867 void HiPlayerImpl::OnStateChanged(StateId state)
868 {
869     MEDIA_LOG_I("OnStateChanged from " PUBLIC_LOG_D32 " to " PUBLIC_LOG_D32, pipelineStates_.load(),
870         TransStateId2PlayerState(state));
871     UpdateStateNoLock(TransStateId2PlayerState(state));
872     {
873         OSAL::ScopedLock lock(stateMutex_);
874         cond_.NotifyOne();
875     }
876 }
877 
OnCallback(const FilterCallbackType & type,Filter * filter,const Plugin::Any & parameter)878 ErrorCode HiPlayerImpl::OnCallback(const FilterCallbackType& type, Filter* filter, const Plugin::Any& parameter)
879 {
880     ErrorCode ret = ErrorCode::SUCCESS;
881     switch (type) {
882         case FilterCallbackType::PORT_ADDED:
883             ret = NewAudioPortFound(filter, parameter);
884             if (ret != ErrorCode::SUCCESS) {
885                 return ret;
886             }
887 #ifdef VIDEO_SUPPORT
888             ret = NewVideoPortFound(filter, parameter);
889 #endif
890             break;
891         case FilterCallbackType::PORT_REMOVE:
892             ret = RemoveFilterChains(filter, parameter);
893             break;
894         default:
895             break;
896     }
897     return ret;
898 }
899 
NewAudioPortFound(Filter * filter,const Plugin::Any & parameter)900 ErrorCode HiPlayerImpl::NewAudioPortFound(Filter* filter, const Plugin::Any& parameter)
901 {
902     if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
903         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
904     }
905     ErrorCode rtv = ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
906     auto param = Plugin::AnyCast<PortInfo>(parameter);
907     if (filter == demuxer_.get() && param.type == PortType::OUT) {
908         MEDIA_LOG_I("new port found on demuxer " PUBLIC_LOG_ZU, param.ports.size());
909         for (const auto& portDesc : param.ports) {
910             if (portDesc.name.compare(0, 5, "audio") != 0) { // 5 is length of "audio"
911                 continue;
912             }
913             MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
914             auto fromPort = filter->GetOutPort(portDesc.name);
915             if (portDesc.isPcm) {
916                 pipeline_->AddFilters({audioSink_.get()});
917                 FAIL_LOG(pipeline_->LinkPorts(fromPort, audioSink_->GetInPort(PORT_NAME_DEFAULT)));
918                 ActiveFilters({audioSink_.get()});
919             } else {
920                 auto newAudioDecoder = CreateAudioDecoder(portDesc.name);
921                 pipeline_->AddFilters({newAudioDecoder.get(), audioSink_.get()});
922                 FAIL_LOG(pipeline_->LinkPorts(fromPort, newAudioDecoder->GetInPort(PORT_NAME_DEFAULT)));
923                 FAIL_LOG(pipeline_->LinkPorts(newAudioDecoder->GetOutPort(PORT_NAME_DEFAULT),
924                                               audioSink_->GetInPort(PORT_NAME_DEFAULT)));
925                 ActiveFilters({newAudioDecoder.get(), audioSink_.get()});
926             }
927             mediaStats_.Append(audioSink_->GetName());
928             rtv = ErrorCode::SUCCESS;
929             break;
930         }
931     }
932     return rtv;
933 }
934 
935 #ifdef VIDEO_SUPPORT
NewVideoPortFound(Filter * filter,const Plugin::Any & parameter)936 ErrorCode HiPlayerImpl::NewVideoPortFound(Filter* filter, const Plugin::Any& parameter)
937 {
938     if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
939         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
940     }
941     auto param = Plugin::AnyCast<PortInfo>(parameter);
942     if (filter != demuxer_.get() || param.type != PortType::OUT) {
943         return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
944     }
945     std::vector<Filter*> newFilters;
946     for (const auto& portDesc : param.ports) {
947         if (portDesc.name.compare(0, 5, "video") == 0) { // 5 is length of "video"
948             MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
949             videoDecoder_ = FilterFactory::Instance().CreateFilterWithType<VideoDecoderFilter>(
950                 "builtin.player.videodecoder", "videodecoder-" + portDesc.name);
951             if (pipeline_->AddFilters({videoDecoder_.get()}) == ErrorCode::SUCCESS) {
952                 // link demuxer and video decoder
953                 auto fromPort = filter->GetOutPort(portDesc.name);
954                 auto toPort = videoDecoder_->GetInPort(PORT_NAME_DEFAULT);
955                 FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort));  // link ports
956                 newFilters.emplace_back(videoDecoder_.get());
957 
958                 // link video decoder and video sink
959                 if (pipeline_->AddFilters({videoSink_.get()}) == ErrorCode::SUCCESS) {
960                     fromPort = videoDecoder_->GetOutPort(PORT_NAME_DEFAULT);
961                     toPort = videoSink_->GetInPort(PORT_NAME_DEFAULT);
962                     FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort));  // link ports
963                     newFilters.push_back(videoSink_.get());
964                     mediaStats_.Append(videoSink_->GetName());
965                 }
966             }
967             break;
968         }
969     }
970     if (!newFilters.empty()) {
971         ActiveFilters(newFilters);
972     }
973     return ErrorCode::SUCCESS;
974 }
975 #endif
976 
RemoveFilterChains(Filter * filter,const Plugin::Any & parameter)977 ErrorCode HiPlayerImpl::RemoveFilterChains(Filter* filter, const Plugin::Any& parameter)
978 {
979     ErrorCode ret = ErrorCode::SUCCESS;
980     auto param = Plugin::AnyCast<PortInfo>(parameter);
981     if (filter != demuxer_.get() || param.type != PortType::OUT) {
982         return ret;
983     }
984     for (const auto& portDesc : param.ports) {
985         MEDIA_LOG_I("remove filter chain for port: " PUBLIC_LOG_S, portDesc.name.c_str());
986         auto peerPort = filter->GetOutPort(portDesc.name)->GetPeerPort();
987         if (peerPort) {
988             auto nextFilter = const_cast<Filter*>(reinterpret_cast<const Filter*>(peerPort->GetOwnerFilter()));
989             if (nextFilter) {
990                 pipeline_->RemoveFilterChain(nextFilter);
991             }
992         }
993     }
994     return ret;
995 }
996 
ActiveFilters(const std::vector<Filter * > & filters)997 void HiPlayerImpl::ActiveFilters(const std::vector<Filter*>& filters)
998 {
999     for (auto it = filters.rbegin(); it != filters.rend(); ++it) {
1000         (*it)->Prepare();
1001     }
1002 }
1003 
ChangeModeToSpeed(const PlaybackRateMode & mode) const1004 double HiPlayerImpl::ChangeModeToSpeed(const PlaybackRateMode& mode) const
1005 {
1006     switch (mode) {
1007         case SPEED_FORWARD_0_75_X:
1008             return SPEED_0_75_X;
1009         case SPEED_FORWARD_1_00_X:
1010             return SPEED_1_00_X;
1011         case SPEED_FORWARD_1_25_X:
1012             return SPEED_1_25_X;
1013         case SPEED_FORWARD_1_75_X:
1014             return SPEED_1_75_X;
1015         case SPEED_FORWARD_2_00_X:
1016             return SPEED_2_00_X;
1017         default:
1018             MEDIA_LOG_I("unknown mode:" PUBLIC_LOG_D32 ", return default speed(SPEED_1_00_X)", mode);
1019     }
1020     return SPEED_1_00_X;
1021 }
1022 
ChangeSpeedToMode(double rate) const1023 PlaybackRateMode HiPlayerImpl::ChangeSpeedToMode(double rate) const
1024 {
1025     if (abs(rate - SPEED_0_75_X) < EPSINON) {
1026         return SPEED_FORWARD_0_75_X;
1027     }
1028     if (abs(rate - SPEED_1_00_X) < EPSINON) {
1029         return SPEED_FORWARD_1_00_X;
1030     }
1031     if (abs(rate - SPEED_1_25_X) < EPSINON) {
1032         return SPEED_FORWARD_1_25_X;
1033     }
1034     if (abs(rate - SPEED_1_75_X) < EPSINON) {
1035         return SPEED_FORWARD_1_75_X;
1036     }
1037     if (abs(rate - SPEED_2_00_X) < EPSINON) {
1038         return SPEED_FORWARD_2_00_X;
1039     }
1040     MEDIA_LOG_I("unknown rate:" PUBLIC_LOG_F ", return default speed(SPEED_FORWARD_1_00_X)", rate);
1041     return SPEED_FORWARD_1_00_X;
1042 }
1043 
SetVideoScaleType(VideoScaleType videoScaleType)1044 int32_t HiPlayerImpl::SetVideoScaleType(VideoScaleType videoScaleType)
1045 {
1046     MEDIA_LOG_I("SetVideoScaleType entered.");
1047 #ifdef VIDEO_SUPPORT
1048     auto ret = videoSink_->SetParameter(static_cast<int32_t>(Tag::VIDEO_SCALE_TYPE),
1049         static_cast<Plugin::VideoScaleType>(static_cast<uint32_t>(videoScaleType)));
1050     return TransErrorCode(ret);
1051 #else
1052     return TransErrorCode(ErrorCode::SUCCESS);
1053 #endif
1054 }
1055 
SetAudioRendererInfo(const int32_t contentType,const int32_t streamUsage,const int32_t rendererFlag)1056 int32_t HiPlayerImpl::SetAudioRendererInfo(const int32_t contentType, const int32_t streamUsage,
1057                                            const int32_t rendererFlag)
1058 {
1059     MEDIA_LOG_I("SetAudioRendererInfo entered.");
1060     Plugin::AudioRenderInfo audioRenderInfo {contentType, streamUsage, rendererFlag};
1061     auto ret = audioSink_->SetParameter(static_cast<int32_t>(Tag::AUDIO_RENDER_INFO), audioRenderInfo);
1062     return TransErrorCode(ret);
1063 }
1064 
SetAudioInterruptMode(const int32_t interruptMode)1065 int32_t HiPlayerImpl::SetAudioInterruptMode(const int32_t interruptMode)
1066 {
1067     MEDIA_LOG_I("SetAudioInterruptMode entered.");
1068     auto ret = audioSink_->SetParameter(static_cast<int32_t>(Tag::AUDIO_INTERRUPT_MODE), interruptMode);
1069     return TransErrorCode(ret);
1070 }
1071 
NotifyBufferingUpdate(const std::string_view & type,int32_t param)1072 void HiPlayerImpl::NotifyBufferingUpdate(const std::string_view& type, int32_t param)
1073 {
1074     Format format;
1075     format.PutIntValue(std::string(type), param);
1076     callbackLooper_.OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
1077 }
1078 
HandleResolutionChangeEvent(const Event & event)1079 void HiPlayerImpl::HandleResolutionChangeEvent(const Event& event)
1080 {
1081     auto resolution = Plugin::AnyCast<std::pair<int32_t, int32_t>>(event.param);
1082     Format format;
1083     (void)format.PutIntValue(PlayerKeys::PLAYER_WIDTH, resolution.first);
1084     (void)format.PutIntValue(PlayerKeys::PLAYER_HEIGHT, resolution.second);
1085     callbackLooper_.OnInfo(INFO_TYPE_RESOLUTION_CHANGE, 0, format);
1086     MEDIA_LOG_I("Receive plugin RESOLUTION_CHANGE, video_width: " PUBLIC_LOG_U32
1087                 ", video_height: " PUBLIC_LOG_U32, resolution.first, resolution.second);
1088     videoWidth_ = resolution.first;
1089     videoHeight_ = resolution.second;
1090 }
1091 
HandlePluginEvent(const Event & event)1092 void HiPlayerImpl::HandlePluginEvent(const Event& event)
1093 {
1094     auto pluginEvent = Plugin::AnyCast<Plugin::PluginEvent>(event.param);
1095     switch (pluginEvent.type) {
1096         case Plugin::PluginEventType::AUDIO_INTERRUPT: {
1097             auto interruptEvent = Plugin::AnyCast<AudioStandard::InterruptEvent>(pluginEvent.param);
1098             MEDIA_LOG_I("Receive Audio AUDIO_INTERRUPT EVENT, eventType: " PUBLIC_LOG_U32
1099                 ", forceType: " PUBLIC_LOG_U32 ", hintType: " PUBLIC_LOG_U32,
1100                 interruptEvent.eventType, interruptEvent.forceType, interruptEvent.hintType);
1101             Format format;
1102             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, interruptEvent.eventType);
1103             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, interruptEvent.forceType);
1104             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, interruptEvent.hintType);
1105             callbackLooper_.OnInfo(INFO_TYPE_INTERRUPT_EVENT, 0, format);
1106             break;
1107         }
1108         case Plugin::PluginEventType::AUDIO_STATE_CHANGE: {
1109             auto renderState = Plugin::AnyCast<AudioStandard::RendererState>(pluginEvent.param);
1110             MEDIA_LOG_I("Receive Audio STATE_CHANGE EVENT, renderState: " PUBLIC_LOG_U32,
1111                 static_cast<uint32_t>(renderState));
1112             if (renderState == AudioStandard::RendererState::RENDERER_PAUSED) {
1113                 Format format;
1114                 callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE_BY_AUDIO, PlayerStates::PLAYER_PAUSED, format);
1115             }
1116             break;
1117         }
1118         case Plugin::PluginEventType::BELOW_LOW_WATERLINE:
1119         case Plugin::PluginEventType::ABOVE_LOW_WATERLINE:
1120         default:
1121             MEDIA_LOG_I("Receive PLUGIN_EVENT, type:  " PUBLIC_LOG_D32,
1122                         CppExt::to_underlying(pluginEvent.type));
1123             break;
1124     }
1125 }
1126 }  // namespace Media
1127 }  // namespace OHOS
1128