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