Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Media is not resuming playback on window's focus/visibilitychange event #50

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion media/filters/pipeline_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ void PipelineController::Suspend() {
void PipelineController::Resume() {
DCHECK(thread_checker_.CalledOnValidThread());
pending_suspend_ = false;

if (state_ == State::SWITCHING_TRACKS) {
defer_playback_resume_ = true;
return;
}

if (state_ == State::SUSPENDING || state_ == State::SUSPENDED) {
pending_resume_ = true;
Dispatch();
Expand Down Expand Up @@ -437,7 +443,13 @@ void PipelineController::FireOnTrackChangeCompleteForTesting(State set_to) {
void PipelineController::OnTrackChangeComplete(State previous_state) {
DCHECK(thread_checker_.CalledOnValidThread());

if (state_ == State::SWITCHING_TRACKS)
if (defer_playback_resume_) {
state_ = State::SUSPENDED;
defer_playback_resume_ = false;
Resume();
return;
}
else if (state_ == State::SWITCHING_TRACKS)
state_ = previous_state;

// Other track changed or seek/suspend/resume, etc may be waiting.
Expand Down
9 changes: 9 additions & 0 deletions media/filters/pipeline_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ class MEDIA_EXPORT PipelineController {
std::vector<MediaTrack::Id> pending_audio_track_change_ids_;
base::Optional<MediaTrack::Id> pending_video_track_change_id_;

// Defer playback resume basing on this flag.
// In some corner case when pausing a video on blur/visibilitychange
// event and then resuming a video on a tab focus/visibilitychange
// event there may be a race condition between
// changing video tracks (state: 5) and resuming playback (state: 8).
// Because of that the new "RESUMING" state is not assigned and a video
// is not starting when a tab with the video is again in focus.
bool defer_playback_resume_ = false;

// Set to true during Start(). Indicates that |seeked_cb_| must be fired once
// we've completed startup.
bool pending_startup_ = false;
Expand Down
13 changes: 13 additions & 0 deletions media/filters/pipeline_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -535,4 +535,17 @@ TEST_F(PipelineControllerTest, SuspendDuringAudioTrackChange) {
EXPECT_FALSE(was_resumed_);
}

TEST_F(PipelineControllerTest, ResumePlaybackDuringSwitchingTracksState) {
Complete(StartPipeline());
Complete(SuspendPipeline());
EXPECT_CALL(*pipeline_, OnSelectedVideoTrackChanged(_, _)).Times(1);
EXPECT_CALL(*pipeline_, GetMediaTime()).Times(1);
EXPECT_CALL(*pipeline_, OnResume(_, _)).Times(1);

pipeline_controller_.OnSelectedVideoTrackChanged({});
pipeline_controller_.Resume();
pipeline_controller_.FireOnTrackChangeCompleteForTesting(
PipelineController::State::PLAYING);
}

} // namespace media