Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Unified Diff: media/blink/webmediaplayer_impl.cc

Issue 2289543005: Allow suspension prior to reaching kHaveFutureData. (Closed)
Patch Set: Fix pause timer. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/blink/webmediaplayer_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/blink/webmediaplayer_impl.cc
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 1f3c5ee6e0ce8cf9e3fcf0c394bc33268d3ac46d..f8136f5e7c5c4853f762dd5ae8283231d9c6e1fd 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -754,9 +754,23 @@ blink::WebTimeRanges WebMediaPlayerImpl::seekable() const {
bool WebMediaPlayerImpl::didLoadingProgress() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- bool pipeline_progress = pipeline_.DidLoadingProgress();
- bool data_progress = buffered_data_source_host_.DidLoadingProgress();
- return pipeline_progress || data_progress;
+
+ // Note: Separate variables used to ensure both methods are called every time.
+ const bool pipeline_progress = pipeline_.DidLoadingProgress();
+ const bool data_progress = buffered_data_source_host_.DidLoadingProgress();
+ const bool did_loading_progress = pipeline_progress || data_progress;
+
+ // If we've idle suspended before reaching kHaveFutureData and loading has
+ // progressed we need to spin up the renderer and figure out if we have enough
+ // data yet; |client_| may be waiting on this signal to trigger playback. The
+ // idle timeout is long enough that this is a low-cost operation.
+ if (highest_ready_state_ < ReadyState::ReadyStateHaveFutureData &&
+ pipeline_controller_.IsSuspended() && did_loading_progress && is_idle_) {
+ is_idle_ = false;
+ UpdatePlayState();
+ }
+
+ return did_loading_progress;
}
void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas,
@@ -1240,14 +1254,10 @@ void WebMediaPlayerImpl::OnShown() {
void WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
- if (must_suspend) {
+ if (must_suspend)
must_suspend_ = true;
- } else {
- // TODO(sandersd): Remove this when idleness is separate from play state.
- if (delegate_state_ == DelegateState::PAUSED_BUT_NOT_IDLE)
- return;
+ else
is_idle_ = true;
- }
UpdatePlayState();
}
@@ -1567,7 +1577,13 @@ void WebMediaPlayerImpl::UpdatePlayState() {
}
void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state) {
- if (!delegate_ || delegate_state_ == new_state)
+ if (!delegate_)
+ return;
+
+ // Dedupe state changes in the general case, but make an exception for gone
+ // since the delegate will use that information to decide when the idle timer
+ // should be fired.
+ if (delegate_state_ == new_state && new_state != DelegateState::GONE)
return;
delegate_state_ = new_state;
@@ -1584,14 +1600,6 @@ void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state) {
case DelegateState::PAUSED:
delegate_->DidPause(delegate_id_, false);
break;
- case DelegateState::PAUSED_BUT_NOT_IDLE:
- // It doesn't really matter what happens when we enter this state, only
- // that we reset the idle timer when leaving it.
- //
- // TODO(sandersd): Ideally the delegate would consider idleness and play
- // state as orthogonal properties so that we could avoid this.
- delegate_->DidPause(delegate_id_, false);
- break;
case DelegateState::ENDED:
delegate_->DidPause(delegate_id_, true);
break;
@@ -1678,29 +1686,22 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote,
delegate_ && delegate_->IsPlayingBackgroundVideo();
bool background_suspended = is_backgrounded_video &&
!(can_play_backgrounded && is_background_playing);
+ bool background_pause_suspended = is_backgrounded && paused_;
- // The |paused_| state is not reliable until we |have_future_data|.
- bool background_pause_suspended =
- is_backgrounded && have_future_data && paused_;
-
- // Idle suspend is enabled once there is future data. We don't want to idle
- // suspend before that because play() may never be triggered to leave the idle
- // state. There could be other theoretical problems if the page is waiting for
- // other events before actually calling play(), but at least we don't break
- // Blink.
- //
// TODO(sandersd): Make the delegate suspend idle players immediately when
// hidden.
- // TODO(sandersd): If Blink told us the paused state sooner, we could
- // idle suspend sooner.
- bool idle_suspended = is_idle_ && have_future_data;
+ bool idle_suspended = is_idle_ && paused_ && !seeking_ && !overlay_enabled_;
+
+ // If we're already suspended, see if we can wait for user interaction. Prior
+ // to HaveFutureData, we require |is_idle_| to remain suspended. |is_idle_|
+ // will be cleared when we receive data which may take us to HaveFutureData.
+ bool can_stay_suspended =
+ (is_idle_ || have_future_data) && is_suspended && paused_ && !seeking_;
// Combined suspend state.
- result.is_suspended =
- is_remote || must_suspend_ || idle_suspended || background_suspended ||
- background_pause_suspended ||
- // If we're already suspended, see if we can wait for user interaction.
- (is_suspended && have_future_data && paused_ && !seeking_);
+ result.is_suspended = is_remote || must_suspend_ || idle_suspended ||
+ background_suspended || background_pause_suspended ||
+ can_stay_suspended;
// We do not treat |playback_rate_| == 0 as paused. For the media session,
// being paused implies displaying a play button, which is incorrect in this
@@ -1736,13 +1737,8 @@ WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote,
if (!has_session) {
result.delegate_state = DelegateState::GONE;
} else if (paused_ || has_session_suspended) {
- if (seeking() || overlay_enabled_) {
- result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE;
- } else if (ended_) {
- result.delegate_state = DelegateState::ENDED;
- } else {
- result.delegate_state = DelegateState::PAUSED;
- }
+ result.delegate_state =
+ ended_ ? DelegateState::ENDED : DelegateState::PAUSED;
} else {
result.delegate_state = DelegateState::PLAYING;
}
@@ -1796,10 +1792,8 @@ void WebMediaPlayerImpl::FinishMemoryUsageReport(int64_t demuxer_memory_usage) {
}
void WebMediaPlayerImpl::ScheduleIdlePauseTimer() {
- // Only schedule the pause timer if we're playing and are suspended. We use
- // delegate state as a proxy for suspended here since the suspension may be in
- // flight at the time of this call.
- if (paused_ || delegate_state_ != DelegateState::GONE)
+ // Only schedule the pause timer if we're playing and are suspended.
+ if (paused_ || !pipeline_controller_.IsSuspended())
return;
#if defined(OS_ANDROID)
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/blink/webmediaplayer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698