From: zhishun.zhou Date: Fri, 8 Mar 2024 07:37:34 +0000 (+0800) Subject: [M120 Migration][HBBTV][MM] Support Preloading feature X-Git-Tag: accepted/tizen/unified/20240315.032948~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eb726a66d25f6dc35b43f22e22ab586769251c5e;p=platform%2Fframework%2Fweb%2Fchromium-efl.git [M120 Migration][HBBTV][MM] Support Preloading feature Add preload feature for Ligada ADINS tcs. Which need high performance during video switch. Patch from: https://review.tizen.org/gerrit/#/c/292683/ Change-Id: I7c64ff3b89be4b349f343a33f1fdf414f853e4d6 Signed-off-by: xiaofang Signed-off-by: zhishun.zhou --- diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h index 4085727..efd6250 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h @@ -26,6 +26,13 @@ typedef struct media_packet_s* media_packet_h; +enum PlayerState { + PLAYER_STATE_DELAYED_NULL, + PLAYER_STATE_DELAYED_PLAY, + PLAYER_STATE_DELAYED_PAUSE, + PLAYER_STATE_DELAYED_SEEK, +}; + namespace media { class MediaPlayerTizenClient; @@ -145,6 +152,14 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { scoped_refptr task_runner_; base::TimeDelta pending_seek_duration_{base::TimeDelta()}; + MediaTypeFlags media_type_{MediaType::Invalid}; + int width_{0}; + int height_{0}; + + base::TimeDelta duration_{base::TimeDelta()}; + bool is_preparing_{false}; + bool is_play_pending_{false}; + bool suspended_{false}; private: // |duration_update_timer_| related @@ -171,13 +186,8 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { bool is_file_url_{false}; bool is_paused_{false}; bool is_seeking_{false}; - bool is_play_pending_{false}; bool is_set_playback_rate_delayed_{false}; - bool suspended_{false}; - bool is_preparing_{false}; - int width_{0}; - int height_{0}; double playback_rate_{1.0}; double volume_{0.0}; @@ -185,12 +195,9 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { base::RepeatingTimer current_time_update_timer_; base::RepeatingTimer buffering_update_timer_; std::string user_agent_; - base::TimeDelta duration_{base::TimeDelta()}; base::TimeDelta playback_time_{base::TimeDelta()}; base::TimeDelta seek_duration_{base::TimeDelta()}; - MediaTypeFlags media_type_{MediaType::Invalid}; - #if defined(TIZEN_VIDEO_HOLE) bool is_video_hole_{false}; gfx::Rect delayed_viewport_rect_; diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc index 5f6a944..c9ece2c 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc @@ -12,6 +12,16 @@ namespace { const int kSeekableTimeUpdateInterval = 500; } +static void PlayerPreLoadingCb(void* data) { + if (!data) { + LOG(ERROR) << "input data is null"; + return; + } + media::MediaPlayerBridgeCapiTV* player = + static_cast(data); + player->OnPlayerPreloading(); +} + static void DrmErrorCb(int err_code, char* err_str, void* data) { DCHECK(data); media::MediaPlayerBridgeCapiTV* player = @@ -86,12 +96,15 @@ void MediaPlayerBridgeCapiTV::Prepare() { if (blink::IsHbbTV() && CheckHighBitRate() && stream_type_ == DASH_STREAM) AppendUrlHighBitRate(url_.spec()); + player_prepared_ = false; MediaPlayerBridgeCapi::Prepare(); if (GetMediaPlayerClient()) GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackReady, player_id_); } void MediaPlayerBridgeCapiTV::Release() { + is_preloaded_ = false; + player_prepared_ = false; StopSeekableTimeUpdateTimer(); MediaPlayerBridgeCapi::Release(); if (GetMediaPlayerClient()) @@ -99,6 +112,16 @@ void MediaPlayerBridgeCapiTV::Release() { } bool MediaPlayerBridgeCapiTV::Play() { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__ + << ",current_time:" << GetCurrentTime().InSecondsF(); + + // HBBTV run in preloading and preplay mode. If no prepread do prepare + // in PlayerPrePlay(), otherwise do normal Play. + if (blink::IsHbbTV() && !player_prepared_) { + if (!PlayerPrePlay()) + LOG(ERROR) << "HBBTV prePlay fail."; + return false; + } if (!MediaPlayerBridgeCapi::Play()) return false; if (GetMediaPlayerClient()) @@ -106,6 +129,16 @@ bool MediaPlayerBridgeCapiTV::Play() { return true; } +void MediaPlayerBridgeCapiTV::Pause(bool is_media_related_action) { + if (!player_prepared_) { + LOG(INFO) << "(" << static_cast(this) + << "), pause while player is not prepared, pause delay"; + delayed_player_state_ = PLAYER_STATE_DELAYED_PAUSE; + return; + } + MediaPlayerBridgeCapi::Pause(is_media_related_action); +} + void MediaPlayerBridgeCapiTV::PlaybackCompleteUpdate() { MediaPlayerBridgeCapi::PlaybackCompleteUpdate(); if (GetMediaPlayerClient()) @@ -113,10 +146,16 @@ void MediaPlayerBridgeCapiTV::PlaybackCompleteUpdate() { } // namespace media void MediaPlayerBridgeCapiTV::PlayerPrepared() { + player_prepared_ = true; MediaPlayerBridgeCapi::PlayerPrepared(); + int canSeek = 0; + int retVal = player_seek_available(player_, &canSeek); + if (retVal == PLAYER_ERROR_NONE && !canSeek) + is_player_seek_available_ = false; + GetAdaptiveStreamingInfo(); - if (/*!blink::IsHbbTV() && */is_live_stream_) { + if (!blink::IsHbbTV() && is_live_stream_) { UpdateSeekableTime(); StartSeekableTimeUpdateTimer(); } @@ -282,6 +321,153 @@ void MediaPlayerBridgeCapiTV::HandleDownloadableFontInfo( type); } +bool MediaPlayerBridgeCapiTV::PreloadIfNeeded(int& ret) { + LOG(INFO) << "PreloadIfNeeded, is_preloaded_ " << is_preloaded_; + if (blink::IsHbbTV() && !is_preloaded_) { + ret = player_preloading_async(player_, -1, PlayerPreLoadingCb, this); + return true; + } + + // fixup : kPlaybackReady status need checked by HBBTVResourceAcquired() patch + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackReady, player_id_); + else + LOG(ERROR) << "(" << static_cast(this) + << "), GetMediaPlayerClient return null"; + SetDisplayAtPausedState(); + return false; +} + +void MediaPlayerBridgeCapiTV::SetDisplayAtPausedState() { + int ret = PLAYER_ERROR_NONE; + if (!pending_seek_duration_.is_zero()) + ret = player_display_video_at_paused_state(player_, false); + else + ret = player_display_video_at_paused_state(player_, true); + + if (ret != PLAYER_ERROR_NONE) + LOG(ERROR) << "player_display_video_at_paused_state() failed"; +} + +void MediaPlayerBridgeCapiTV::UpdateDuration() { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + if (blink::IsHbbTV() && !is_preloaded_) { + LOG(INFO) << "HBBTV preload not finished, no need update duration. "; + return; + } + MediaPlayerBridgeCapi::UpdateDuration(); +} + +void MediaPlayerBridgeCapiTV::UpdateMediaType() { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + + if (blink::IsHbbTV() && !is_preloaded_) { + LOG(INFO) << "HBBTV preload not finished, no need update media type. "; + return; + } + MediaPlayerBridgeCapi::UpdateMediaType(); +} + +bool MediaPlayerBridgeCapiTV::CheckLiveStreaming() const { + int isLive = 0; + int retVal = player_get_adaptive_streaming_info(player_, &isLive, + PLAYER_ADAPTIVE_INFO_IS_LIVE); + if (retVal != PLAYER_ERROR_NONE) { + LOG(ERROR) << "player_get_adaptive_streaming_info failed, error: " + << retVal; + return false; + } + + if (!isLive) + return false; + + LOG(INFO) << "This is a live streaming."; + return true; +} + +void MediaPlayerBridgeCapiTV::OnPlayerPreloading() { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerBridgeCapiTV::PlayerPreloaded, + weak_factory_.GetWeakPtr())); +} + +bool MediaPlayerBridgeCapiTV::HBBTVResourceAcquired() { + bool media_resource_acquired = false; + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "MediaPlayerTizenClient is nullptr"; + return false; + } + + GetMediaPlayerClient()->NotifyPlaybackState( + kPlaybackReady, player_id_, url_.spec(), mime_type_, + &media_resource_acquired, NULL, NULL); + if (!media_resource_acquired) { + GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackStop, player_id_); + LOG(ERROR) << "HBBTV media resource acquired failed"; + } + return media_resource_acquired; +} + +void MediaPlayerBridgeCapiTV::PlayerPreloaded() { + LOG(INFO) << "PlayerPreloaded,this: " << this + << ",player_prepared_:" << player_prepared_; + + is_preloaded_ = true; + is_live_stream_ = CheckLiveStreaming(); + // if (stream_type_ == DASH_STREAM) + // ParseDashInfo(); + if (is_live_stream_ && stream_type_ != OTHER_STREAM) { + // UpdateSeekableTime(); + // StartSeekableTimeUpdateTimer(); + } + // UpdateAudioTrackInfo(); + // UpdateVideoTrackInfo(); + // UpdateTextTrackInfo(); + UpdateDuration(); + UpdateMediaType(); + if (GetMediaType() == MediaType::Invalid) { + LOG(ERROR) << "Media type is not valid!"; + return; + } + + OnReadyStateChange(player_id_, + blink::WebMediaPlayer::kReadyStateHaveFutureData); + OnNetworkStateChange(player_id_, blink::WebMediaPlayer::kNetworkStateLoading); + + if (!player_prepared_ && HBBTVResourceAcquired()) { + int ret = SetPlayerPrepareAsync(); + if (ret != PLAYER_ERROR_NONE) { + OnHandlePlayerError(ret, FROM_HERE); + } + } +} + +bool MediaPlayerBridgeCapiTV::PlayerPrePlay() { + LOG(INFO) << "PlayerPrePlay, this: " << this + << ",is_player_prepared : " << player_prepared_; + if (IsPlayerSuspended()) { + LOG(INFO) << "PlayerPrePlay while player is suspended"; + return false; + } + + if (!HBBTVResourceAcquired()) { + LOG(INFO) + << "PlayerPrePlay while it's not in case of HBBTV Resource Acquired"; + return false; + } + + delayed_player_state_ = PLAYER_STATE_DELAYED_PLAY; + LOG(INFO) << "begin to |player_prepare_async|"; + + SetDisplayAtPausedState(); + int ret = SetPlayerPrepareAsync(); + if (ret != PLAYER_ERROR_NONE) { + OnHandlePlayerError(ret, FROM_HERE); + return false; + } + + return true; +} void MediaPlayerBridgeCapiTV::Initialize(VideoRendererSink* sink) { player_set_drm_error_cb(player_, DrmErrorCb, this); MediaPlayerBridgeCapi::Initialize(sink); diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h index ecebe7d..5cbab59 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h @@ -29,14 +29,20 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { bool Play() override; void Prepare() override; void Release() override; + void Pause(bool is_media_related_action) override; void SetContentMimeType(const std::string& mime_type) override; void PlaybackCompleteUpdate() override; + bool PreloadIfNeeded(int& ret) override; + void UpdateMediaType() override; + void UpdateDuration() override; + void AppendUrlHighBitRate(const std::string& url); bool CheckHighBitRate(); void HandleDownloadableFontInfo(const std::string& scheme_id_uri, const std::string& value, const std::string& data, int type); + void OnPlayerPreloading(); void OnDrmError(int err_code, char* err_str); @@ -44,8 +50,15 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { void PlayerPrepared() override; private: + void PlayerPreloaded(); + bool PlayerPrePlay(); + void SetDisplayAtPausedState(); + bool CheckLiveStreaming() const; + bool HBBTVResourceAcquired(); bool SetDrmInfo(std::string& drm_info); bool SetMediaDRMInfo(const std::string&, const std::string&); + bool is_preloaded_{false}; + bool is_player_seek_available_{true}; void StartSeekableTimeUpdateTimer(); void StopSeekableTimeUpdateTimer(); void OnSeekableTimeUpdateTimerFired(); @@ -61,7 +74,6 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { base::TimeDelta min_seekable_time_{base::TimeDelta()}; base::TimeDelta max_seekable_time_{base::TimeDelta()}; base::RepeatingTimer seekable_time_update_timer_; - // NOTE: Weak pointers must be invalidated before all other member variables. base::WeakPtrFactory weak_factory_; };