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 seekTime = hstTime;
645     Plugin::SeekMode seekMode = mode;
646     auto rtv = seekTime >= 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 = seekTime;
654         rtv = audioSource_->SeekToTime(seekTime);
655         if (rtv != ErrorCode::SUCCESS) {
656             MEDIA_LOG_I("SeekToTime failed\n");
657             rtv = demuxer_->SeekTo(seekTime, seekMode, realSeekTime);
658         }
659         if (rtv == ErrorCode::SUCCESS) {
660             syncManager_->Seek(realSeekTime);
661         }
662         PROFILE_END("SeekTo");
663 
664         pipeline_->FlushEnd();
665         PROFILE_END("Flush end");
666         PROFILE_RESET();
667     }
668     if (rtv != ErrorCode::SUCCESS) {
669         callbackLooper_.OnError(PLAYER_ERROR, MSERR_SEEK_FAILED);
670         MEDIA_LOG_E("Seek done, seek error.");
671     } else {
672         Format format;
673         int64_t currentPos = Plugin::HstTime2Ms(seekTime);
674         MEDIA_LOG_I("Seek done, currentPos : " PUBLIC_LOG_D64, currentPos);
675         callbackLooper_.OnInfo(INFO_TYPE_SEEKDONE, static_cast<int32_t>(currentPos), format);
676         callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, static_cast<int32_t>(currentPos), format);
677     }
678 
679     return rtv;
680 }
681 
DoOnReady()682 ErrorCode HiPlayerImpl::DoOnReady()
683 {
684     SetVolumeToSink(volume_, false); // do not report
685     auto tmpMeta = demuxer_->GetGlobalMetaInfo();
686     sourceMeta_ = tmpMeta;
687     int64_t duration = 0;
688     bool found = false;
689     if (tmpMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(duration)) {
690         found = true;
691     } else {
692         MEDIA_LOG_W("Get media duration failed.");
693     }
694     streamMeta_.clear();
695     int64_t tmp = 0;
696     for (auto& streamMeta : demuxer_->GetStreamMetaInfo()) {
697         streamMeta_.push_back(streamMeta);
698         if (streamMeta->Get<Media::Plugin::Tag::MEDIA_DURATION>(tmp)) {
699             duration = std::max(duration, tmp);
700             found = true;
701         } else {
702             MEDIA_LOG_W("Get media duration failed.");
703         }
704     }
705     if (found) {
706         duration_ = duration;
707         Format format;
708         callbackLooper_.OnInfo(INFO_TYPE_DURATION_UPDATE, Plugin::HstTime2Ms(duration_), format);
709     } else {
710         MEDIA_LOG_E("INFO_TYPE_DURATION_UPDATE failed");
711     }
712     std::vector<uint32_t> vBitRates;
713     auto ret = audioSource_->GetBitRates(vBitRates);
714     if ((ret == ErrorCode::SUCCESS) && (vBitRates.size() > 0)) {
715         int msize = vBitRates.size();
716         const int size_ = msize;
717         uint32_t* bitrates = vBitRates.data();
718         Format bitRateFormat;
719         (void)bitRateFormat.PutBuffer(std::string(PlayerKeys::PLAYER_BITRATE),
720         static_cast<uint8_t *>(static_cast<void *>(bitrates)), size_ * sizeof(uint32_t));
721         callbackLooper_.OnInfo(INFO_TYPE_BITRATE_COLLECT, 0, bitRateFormat);
722     }
723     return ErrorCode::SUCCESS;
724 }
725 
DoOnComplete()726 ErrorCode HiPlayerImpl::DoOnComplete()
727 {
728     MEDIA_LOG_I("OnComplete looping: " PUBLIC_LOG_D32 ".", singleLoop_.load());
729     Format format;
730     if (singleLoop_.load()) {
731         callbackLooper_.OnInfo(INFO_TYPE_EOS, static_cast<int32_t>(singleLoop_.load()), format);
732     } else {
733         OnStateChanged(StateId::EOS);
734         callbackLooper_.StopReportMediaProgress();
735         callbackLooper_.ManualReportMediaProgressOnce();
736     }
737     mediaStats_.ResetEventCompleteAllReceived();
738     return ErrorCode::SUCCESS;
739 }
740 
DoOnError(ErrorCode errorCode)741 ErrorCode HiPlayerImpl::DoOnError(ErrorCode errorCode)
742 {
743     UpdateStateNoLock(PlayerStates::PLAYER_STATE_ERROR);
744     callbackLooper_.OnError(PLAYER_ERROR, TransErrorCode(errorCode));
745     return ErrorCode::SUCCESS;
746 }
747 
SetVolumeToSink(float volume, bool reportUpward)748 ErrorCode HiPlayerImpl::SetVolumeToSink(float volume, bool reportUpward)
749 {
750     MEDIA_LOG_I("SetVolumeToSink entered.");
751     ErrorCode ret = ErrorCode::SUCCESS;
752     if (volume_ >= 0) {
753         MEDIA_LOG_I("set volume " PUBLIC_LOG_F, volume);
754         ret = audioSink_->SetVolume(volume);
755     }
756 
757     if (ret != ErrorCode::SUCCESS) {
758         MEDIA_LOG_E("SetVolume failed with error " PUBLIC_LOG_D32, static_cast<int>(ret));
759         callbackLooper_.OnError(PLAYER_ERROR, TransErrorCode(ret));
760     } else if (reportUpward) {
761         Format format;
762         callbackLooper_.OnInfo(INFO_TYPE_VOLUME_CHANGE, volume, format);
763     }
764     return ret;
765 }
766 
CreateAudioDecoder(const std::string& desc)767 PFilter HiPlayerImpl::CreateAudioDecoder(const std::string& desc)
768 {
769     if (!audioDecoderMap_[desc]) {
770         audioDecoderMap_[desc] = FilterFactory::Instance().CreateFilterWithType<AudioDecoderFilter>(
771             "builtin.player.audiodecoder", "audiodecoder-" + desc);
772         // set parameters to decoder.
773     }
774     return audioDecoderMap_[desc];
775 }
776 
SetLooping(bool loop)777 int32_t HiPlayerImpl::SetLooping(bool loop)
778 {
779     MEDIA_LOG_I("SetLooping entered, loop: " PUBLIC_LOG_D32, loop);
780     singleLoop_ = loop;
781     return TransErrorCode(ErrorCode::SUCCESS);
782 }
783 
SetParameter(const Format& params)784 int32_t HiPlayerImpl::SetParameter(const Format& params)
785 {
786     MEDIA_LOG_I("SetParameter entered.");
787     if (params.ContainKey(PlayerKeys::VIDEO_SCALE_TYPE)) {
788         int32_t videoScaleType = 0;
789         params.GetIntValue(PlayerKeys::VIDEO_SCALE_TYPE, videoScaleType);
790         return SetVideoScaleType(VideoScaleType(videoScaleType));
791     }
792     if (params.ContainKey(PlayerKeys::CONTENT_TYPE) && params.ContainKey(PlayerKeys::STREAM_USAGE)) {
793         int32_t contentType;
794         int32_t streamUsage;
795         int32_t rendererFlag;
796         params.GetIntValue(PlayerKeys::CONTENT_TYPE, contentType);
797         params.GetIntValue(PlayerKeys::STREAM_USAGE, streamUsage);
798         params.GetIntValue(PlayerKeys::RENDERER_FLAG, rendererFlag);
799         return SetAudioRendererInfo(contentType, streamUsage, rendererFlag);
800     }
801     if (params.ContainKey(PlayerKeys::AUDIO_INTERRUPT_MODE)) {
802         int32_t interruptMode = 0;
803         params.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
804         return SetAudioInterruptMode(interruptMode);
805     }
806     return TransErrorCode(ErrorCode::ERROR_UNIMPLEMENTED);
807 }
808 
SetObs(const std::weak_ptr<IPlayerEngineObs>& obs)809 int32_t HiPlayerImpl::SetObs(const std::weak_ptr<IPlayerEngineObs>& obs)
810 {
811     MEDIA_LOG_I("SetObs entered.");
812     callbackLooper_.StartWithPlayerEngineObs(obs);
813     return TransErrorCode(ErrorCode::SUCCESS);
814 }
815 
Reset()816 int32_t HiPlayerImpl::Reset()
817 {
818     MEDIA_LOG_I("Reset entered.");
819     if (pipelineStates_ == PlayerStates::PLAYER_STOPPED) {
820         return TransErrorCode(ErrorCode::SUCCESS);
821     }
822     singleLoop_ = false;
823     mediaStats_.Reset();
824     auto ret = DoReset();
825     OnStateChanged(StateId::STOPPED);
826     return TransErrorCode(ret);
827 }
828 
GetCurrentTime(int32_t& currentPositionMs)829 int32_t HiPlayerImpl::GetCurrentTime(int32_t& currentPositionMs)
830 {
831     currentPositionMs = Plugin::HstTime2Ms(syncManager_->GetMediaTimeNow());
832     return TransErrorCode(ErrorCode::SUCCESS);
833 }
834 
GetDuration(int32_t& durationMs)835 int32_t HiPlayerImpl::GetDuration(int32_t& durationMs)
836 {
837     durationMs = 0;
838     if (pipelineStates_ == PlayerStates::PLAYER_IDLE || pipelineStates_ == PlayerStates::PLAYER_PREPARING ||
839         audioSource_ == nullptr) {
840         MEDIA_LOG_E("GetDuration, invalid state or audioSource_ is null. state: " PUBLIC_LOG_S,
841                     StringnessPlayerState(pipelineStates_).c_str());
842         return MSERR_INVALID_STATE;
843     }
844     if (duration_ < 0) {
845         durationMs = -1;
846         MEDIA_LOG_W("no valid duration");
847         return MSERR_UNKNOWN;
848     }
849     durationMs = Plugin::HstTime2Ms(duration_);
850     MEDIA_LOG_DD("GetDuration returned " PUBLIC_LOG_D32, durationMs);
851     return MSERR_OK;
852 }
853 
SetPlaybackSpeed(PlaybackRateMode mode)854 int32_t HiPlayerImpl::SetPlaybackSpeed(PlaybackRateMode mode)
855 {
856     MEDIA_LOG_I("SetPlaybackSpeed entered.");
857     double playbackSpeed = ChangeModeToSpeed(mode);
858     demuxer_->SetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_PLAYBACK_SPEED), playbackSpeed);
859     Format format;
860     callbackLooper_.OnInfo(INFO_TYPE_SPEEDDONE, 0, format);
861 
862     int32_t currentPosMs = 0;
863     int32_t durationMs = 0;
864     NZERO_RETURN(GetDuration(durationMs));
865     NZERO_RETURN(GetCurrentTime(currentPosMs));
866     currentPosMs = std::min(currentPosMs, durationMs);
867     currentPosMs = currentPosMs < 0 ? 0 : currentPosMs;
868     callbackLooper_.OnInfo(INFO_TYPE_POSITION_UPDATE, currentPosMs, format);
869     MEDIA_LOG_D("SetPlaybackSpeed entered end.");
870     return MSERR_OK;
871 }
872 int32_t HiPlayerImpl::GetPlaybackSpeed(PlaybackRateMode& mode)
873 {
874     MEDIA_LOG_I("GetPlaybackSpeed entered.");
875     Plugin::Any any;
876     demuxer_->GetParameter(static_cast<int32_t>(Plugin::Tag::MEDIA_PLAYBACK_SPEED), any);
877     auto playbackSpeed = Plugin::AnyCast<double>(any);
878     mode = ChangeSpeedToMode(playbackSpeed);
879     return MSERR_OK;
880 }
881 
OnStateChanged(StateId state)882 void HiPlayerImpl::OnStateChanged(StateId state)
883 {
884     MEDIA_LOG_I("OnStateChanged from " PUBLIC_LOG_D32 " to " PUBLIC_LOG_D32, pipelineStates_.load(),
885         TransStateId2PlayerState(state));
886     UpdateStateNoLock(TransStateId2PlayerState(state));
887     {
888         OSAL::ScopedLock lock(stateMutex_);
889         cond_.NotifyOne();
890     }
891 }
892 
OnCallback(const FilterCallbackType& type, Filter* filter, const Plugin::Any& parameter)893 ErrorCode HiPlayerImpl::OnCallback(const FilterCallbackType& type, Filter* filter, const Plugin::Any& parameter)
894 {
895     ErrorCode ret = ErrorCode::SUCCESS;
896     switch (type) {
897         case FilterCallbackType::PORT_ADDED:
898             ret = NewAudioPortFound(filter, parameter);
899             if (ret != ErrorCode::SUCCESS) {
900                 return ret;
901             }
902 #ifdef VIDEO_SUPPORT
903             ret = NewVideoPortFound(filter, parameter);
904 #endif
905             break;
906         case FilterCallbackType::PORT_REMOVE:
907             ret = RemoveFilterChains(filter, parameter);
908             break;
909         default:
910             break;
911     }
912     return ret;
913 }
914 
NewAudioPortFound(Filter* filter, const Plugin::Any& parameter)915 ErrorCode HiPlayerImpl::NewAudioPortFound(Filter* filter, const Plugin::Any& parameter)
916 {
917     if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
918         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
919     }
920     ErrorCode rtv = ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
921     auto param = Plugin::AnyCast<PortInfo>(parameter);
922     if (filter == demuxer_.get() && param.type == PortType::OUT) {
923         MEDIA_LOG_I("new port found on demuxer " PUBLIC_LOG_ZU, param.ports.size());
924         for (const auto& portDesc : param.ports) {
925             if (portDesc.name.compare(0, 5, "audio") != 0) { // 5 is length of "audio"
926                 continue;
927             }
928             MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
929             auto fromPort = filter->GetOutPort(portDesc.name);
930             if (portDesc.isPcm) {
931                 pipeline_->AddFilters({audioSink_.get()});
932                 FAIL_LOG(pipeline_->LinkPorts(fromPort, audioSink_->GetInPort(PORT_NAME_DEFAULT)));
933                 ActiveFilters({audioSink_.get()});
934             } else {
935                 auto newAudioDecoder = CreateAudioDecoder(portDesc.name);
936                 pipeline_->AddFilters({newAudioDecoder.get(), audioSink_.get()});
937                 FAIL_LOG(pipeline_->LinkPorts(fromPort, newAudioDecoder->GetInPort(PORT_NAME_DEFAULT)));
938                 FAIL_LOG(pipeline_->LinkPorts(newAudioDecoder->GetOutPort(PORT_NAME_DEFAULT),
939                                               audioSink_->GetInPort(PORT_NAME_DEFAULT)));
940                 ActiveFilters({newAudioDecoder.get(), audioSink_.get()});
941             }
942             mediaStats_.Append(audioSink_->GetName());
943             rtv = ErrorCode::SUCCESS;
944             break;
945         }
946     }
947     return rtv;
948 }
949 
950 #ifdef VIDEO_SUPPORT
NewVideoPortFound(Filter* filter, const Plugin::Any& parameter)951 ErrorCode HiPlayerImpl::NewVideoPortFound(Filter* filter, const Plugin::Any& parameter)
952 {
953     if (!Plugin::Any::IsSameTypeWith<PortInfo>(parameter)) {
954         return ErrorCode::ERROR_INVALID_PARAMETER_TYPE;
955     }
956     auto param = Plugin::AnyCast<PortInfo>(parameter);
957     if (filter != demuxer_.get() || param.type != PortType::OUT) {
958         return ErrorCode::ERROR_INVALID_PARAMETER_VALUE;
959     }
960     std::vector<Filter*> newFilters;
961     for (const auto& portDesc : param.ports) {
962         if (portDesc.name.compare(0, 5, "video") == 0) { // 5 is length of "video"
963             MEDIA_LOG_I("port name " PUBLIC_LOG_S, portDesc.name.c_str());
964             videoDecoder_ = FilterFactory::Instance().CreateFilterWithType<VideoDecoderFilter>(
965                 "builtin.player.videodecoder", "videodecoder-" + portDesc.name);
966             if (pipeline_->AddFilters({videoDecoder_.get()}) == ErrorCode::SUCCESS) {
967                 // link demuxer and video decoder
968                 auto fromPort = filter->GetOutPort(portDesc.name);
969                 auto toPort = videoDecoder_->GetInPort(PORT_NAME_DEFAULT);
970                 FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort));  // link ports
971                 newFilters.emplace_back(videoDecoder_.get());
972 
973                 // link video decoder and video sink
974                 if (pipeline_->AddFilters({videoSink_.get()}) == ErrorCode::SUCCESS) {
975                     fromPort = videoDecoder_->GetOutPort(PORT_NAME_DEFAULT);
976                     toPort = videoSink_->GetInPort(PORT_NAME_DEFAULT);
977                     FAIL_LOG(pipeline_->LinkPorts(fromPort, toPort));  // link ports
978                     newFilters.push_back(videoSink_.get());
979                     mediaStats_.Append(videoSink_->GetName());
980                 }
981             }
982             break;
983         }
984     }
985     if (!newFilters.empty()) {
986         ActiveFilters(newFilters);
987     }
988     return ErrorCode::SUCCESS;
989 }
990 #endif
991 
RemoveFilterChains(Filter* filter, const Plugin::Any& parameter)992 ErrorCode HiPlayerImpl::RemoveFilterChains(Filter* filter, const Plugin::Any& parameter)
993 {
994     ErrorCode ret = ErrorCode::SUCCESS;
995     auto param = Plugin::AnyCast<PortInfo>(parameter);
996     if (filter != demuxer_.get() || param.type != PortType::OUT) {
997         return ret;
998     }
999     for (const auto& portDesc : param.ports) {
1000         MEDIA_LOG_I("remove filter chain for port: " PUBLIC_LOG_S, portDesc.name.c_str());
1001         auto peerPort = filter->GetOutPort(portDesc.name)->GetPeerPort();
1002         if (peerPort) {
1003             auto nextFilter = const_cast<Filter*>(reinterpret_cast<const Filter*>(peerPort->GetOwnerFilter()));
1004             if (nextFilter) {
1005                 pipeline_->RemoveFilterChain(nextFilter);
1006             }
1007         }
1008     }
1009     return ret;
1010 }
1011 
ActiveFilters(const std::vector<Filter*>& filters)1012 void HiPlayerImpl::ActiveFilters(const std::vector<Filter*>& filters)
1013 {
1014     for (auto it = filters.rbegin(); it != filters.rend(); ++it) {
1015         (*it)->Prepare();
1016     }
1017 }
1018 
ChangeModeToSpeed(const PlaybackRateMode& mode) const1019 double HiPlayerImpl::ChangeModeToSpeed(const PlaybackRateMode& mode) const
1020 {
1021     switch (mode) {
1022         case SPEED_FORWARD_0_75_X:
1023             return SPEED_0_75_X;
1024         case SPEED_FORWARD_1_00_X:
1025             return SPEED_1_00_X;
1026         case SPEED_FORWARD_1_25_X:
1027             return SPEED_1_25_X;
1028         case SPEED_FORWARD_1_75_X:
1029             return SPEED_1_75_X;
1030         case SPEED_FORWARD_2_00_X:
1031             return SPEED_2_00_X;
1032         default:
1033             MEDIA_LOG_I("unknown mode:" PUBLIC_LOG_D32 ", return default speed(SPEED_1_00_X)", mode);
1034     }
1035     return SPEED_1_00_X;
1036 }
1037 
ChangeSpeedToMode(double rate) const1038 PlaybackRateMode HiPlayerImpl::ChangeSpeedToMode(double rate) const
1039 {
1040     if (abs(rate - SPEED_0_75_X) < EPSINON) {
1041         return SPEED_FORWARD_0_75_X;
1042     }
1043     if (abs(rate - SPEED_1_00_X) < EPSINON) {
1044         return SPEED_FORWARD_1_00_X;
1045     }
1046     if (abs(rate - SPEED_1_25_X) < EPSINON) {
1047         return SPEED_FORWARD_1_25_X;
1048     }
1049     if (abs(rate - SPEED_1_75_X) < EPSINON) {
1050         return SPEED_FORWARD_1_75_X;
1051     }
1052     if (abs(rate - SPEED_2_00_X) < EPSINON) {
1053         return SPEED_FORWARD_2_00_X;
1054     }
1055     MEDIA_LOG_I("unknown rate:" PUBLIC_LOG_F ", return default speed(SPEED_FORWARD_1_00_X)", rate);
1056     return SPEED_FORWARD_1_00_X;
1057 }
1058 
SetVideoScaleType(VideoScaleType videoScaleType)1059 int32_t HiPlayerImpl::SetVideoScaleType(VideoScaleType videoScaleType)
1060 {
1061     MEDIA_LOG_I("SetVideoScaleType entered.");
1062 #ifdef VIDEO_SUPPORT
1063     auto ret = videoSink_->SetParameter(static_cast<int32_t>(Tag::VIDEO_SCALE_TYPE),
1064         static_cast<Plugin::VideoScaleType>(static_cast<uint32_t>(videoScaleType)));
1065     return TransErrorCode(ret);
1066 #else
1067     return TransErrorCode(ErrorCode::SUCCESS);
1068 #endif
1069 }
1070 
SetAudioRendererInfo(const int32_t contentType, const int32_t streamUsage, const int32_t rendererFlag)1071 int32_t HiPlayerImpl::SetAudioRendererInfo(const int32_t contentType, const int32_t streamUsage,
1072                                            const int32_t rendererFlag)
1073 {
1074     MEDIA_LOG_I("SetAudioRendererInfo entered.");
1075     Plugin::AudioRenderInfo audioRenderInfo {contentType, streamUsage, rendererFlag};
1076     auto ret = audioSink_->SetParameter(static_cast<int32_t>(Tag::AUDIO_RENDER_INFO), audioRenderInfo);
1077     return TransErrorCode(ret);
1078 }
1079 
SetAudioInterruptMode(const int32_t interruptMode)1080 int32_t HiPlayerImpl::SetAudioInterruptMode(const int32_t interruptMode)
1081 {
1082     MEDIA_LOG_I("SetAudioInterruptMode entered.");
1083     auto ret = audioSink_->SetParameter(static_cast<int32_t>(Tag::AUDIO_INTERRUPT_MODE), interruptMode);
1084     return TransErrorCode(ret);
1085 }
1086 
SelectBitRate(uint32_t bitRate)1087 int32_t HiPlayerImpl::SelectBitRate(uint32_t bitRate)
1088 {
1089     int64_t mBitRate = static_cast<int64_t>(bitRate);
1090     pipeline_->FlushStart();
1091     auto ret = audioSource_->SelectBitRate(mBitRate);
1092     pipeline_->FlushEnd();
1093     return TransErrorCode(ret);
1094 }
1095 
NotifyBufferingUpdate(const std::string_view& type, int32_t param)1096 void HiPlayerImpl::NotifyBufferingUpdate(const std::string_view& type, int32_t param)
1097 {
1098     Format format;
1099     format.PutIntValue(std::string(type), param);
1100     callbackLooper_.OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
1101 }
1102 
HandleResolutionChangeEvent(const Event& event)1103 void HiPlayerImpl::HandleResolutionChangeEvent(const Event& event)
1104 {
1105     auto resolution = Plugin::AnyCast<std::pair<int32_t, int32_t>>(event.param);
1106     Format format;
1107     (void)format.PutIntValue(PlayerKeys::PLAYER_WIDTH, resolution.first);
1108     (void)format.PutIntValue(PlayerKeys::PLAYER_HEIGHT, resolution.second);
1109     callbackLooper_.OnInfo(INFO_TYPE_RESOLUTION_CHANGE, 0, format);
1110     MEDIA_LOG_I("Receive plugin RESOLUTION_CHANGE, video_width: " PUBLIC_LOG_U32
1111                 ", video_height: " PUBLIC_LOG_U32, resolution.first, resolution.second);
1112     videoWidth_ = resolution.first;
1113     videoHeight_ = resolution.second;
1114 }
1115 
HandlePluginEvent(const Event& event)1116 void HiPlayerImpl::HandlePluginEvent(const Event& event)
1117 {
1118     auto pluginEvent = Plugin::AnyCast<Plugin::PluginEvent>(event.param);
1119     switch (pluginEvent.type) {
1120         case Plugin::PluginEventType::AUDIO_INTERRUPT: {
1121             auto interruptEvent = Plugin::AnyCast<AudioStandard::InterruptEvent>(pluginEvent.param);
1122             MEDIA_LOG_I("Receive Audio AUDIO_INTERRUPT EVENT, eventType: " PUBLIC_LOG_U32
1123                 ", forceType: " PUBLIC_LOG_U32 ", hintType: " PUBLIC_LOG_U32,
1124                 interruptEvent.eventType, interruptEvent.forceType, interruptEvent.hintType);
1125             Format format;
1126             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, interruptEvent.eventType);
1127             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, interruptEvent.forceType);
1128             (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, interruptEvent.hintType);
1129             callbackLooper_.OnInfo(INFO_TYPE_INTERRUPT_EVENT, 0, format);
1130             break;
1131         }
1132         case Plugin::PluginEventType::AUDIO_STATE_CHANGE: {
1133             auto renderState = Plugin::AnyCast<AudioStandard::RendererState>(pluginEvent.param);
1134             MEDIA_LOG_I("Receive Audio STATE_CHANGE EVENT, renderState: " PUBLIC_LOG_U32,
1135                 static_cast<uint32_t>(renderState));
1136             if (renderState == AudioStandard::RendererState::RENDERER_PAUSED) {
1137                 Format format;
1138                 callbackLooper_.OnInfo(INFO_TYPE_STATE_CHANGE_BY_AUDIO, PlayerStates::PLAYER_PAUSED, format);
1139             }
1140             break;
1141         }
1142         case Plugin::PluginEventType::BELOW_LOW_WATERLINE:
1143         case Plugin::PluginEventType::ABOVE_LOW_WATERLINE:
1144         default:
1145             MEDIA_LOG_I("Receive PLUGIN_EVENT, type:  " PUBLIC_LOG_D32,
1146                         CppExt::to_underlying(pluginEvent.type));
1147             break;
1148     }
1149 }
1150 }  // namespace Media
1151 }  // namespace OHOS
1152