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

Side by Side Diff: media/blink/webmediaplayer_impl.cc

Issue 2681863005: [Video] MediaSession API event handlers can resume background video. (Closed)
Patch Set: Updated the comment in ComputePlayState Created 3 years, 10 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/blink/webmediaplayer_impl.h" 5 #include "media/blink/webmediaplayer_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <string> 10 #include <string>
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" 56 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
57 #include "third_party/WebKit/public/platform/WebMediaSource.h" 57 #include "third_party/WebKit/public/platform/WebMediaSource.h"
58 #include "third_party/WebKit/public/platform/WebRect.h" 58 #include "third_party/WebKit/public/platform/WebRect.h"
59 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" 59 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
60 #include "third_party/WebKit/public/platform/WebSize.h" 60 #include "third_party/WebKit/public/platform/WebSize.h"
61 #include "third_party/WebKit/public/platform/WebString.h" 61 #include "third_party/WebKit/public/platform/WebString.h"
62 #include "third_party/WebKit/public/platform/WebURL.h" 62 #include "third_party/WebKit/public/platform/WebURL.h"
63 #include "third_party/WebKit/public/web/WebDocument.h" 63 #include "third_party/WebKit/public/web/WebDocument.h"
64 #include "third_party/WebKit/public/web/WebFrame.h" 64 #include "third_party/WebKit/public/web/WebFrame.h"
65 #include "third_party/WebKit/public/web/WebLocalFrame.h" 65 #include "third_party/WebKit/public/web/WebLocalFrame.h"
66 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
66 #include "third_party/WebKit/public/web/WebView.h" 67 #include "third_party/WebKit/public/web/WebView.h"
67 68
68 #if defined(OS_ANDROID) 69 #if defined(OS_ANDROID)
69 #include "media/base/android/media_codec_util.h" 70 #include "media/base/android/media_codec_util.h"
70 #endif 71 #endif
71 72
72 using blink::WebCanvas; 73 using blink::WebCanvas;
73 using blink::WebMediaPlayer; 74 using blink::WebMediaPlayer;
74 using blink::WebRect; 75 using blink::WebRect;
75 using blink::WebSize; 76 using blink::WebSize;
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 411
411 #if defined(OS_ANDROID) // WMPI_CAST 412 #if defined(OS_ANDROID) // WMPI_CAST
412 cast_impl_.Initialize(url, frame_, delegate_id_); 413 cast_impl_.Initialize(url, frame_, delegate_id_);
413 #endif 414 #endif
414 } 415 }
415 416
416 void WebMediaPlayerImpl::play() { 417 void WebMediaPlayerImpl::play() {
417 DVLOG(1) << __func__; 418 DVLOG(1) << __func__;
418 DCHECK(main_task_runner_->BelongsToCurrentThread()); 419 DCHECK(main_task_runner_->BelongsToCurrentThread());
419 420
421 // User initiated play unlocks background video playback.
422 if (blink::WebUserGestureIndicator::isProcessingUserGesture())
423 video_locked_when_paused_when_hidden_ = false;
424
420 #if defined(OS_ANDROID) // WMPI_CAST 425 #if defined(OS_ANDROID) // WMPI_CAST
421 if (isRemote()) { 426 if (isRemote()) {
422 cast_impl_.play(); 427 cast_impl_.play();
423 return; 428 return;
424 } 429 }
425 #endif 430 #endif
426 // TODO(sandersd): Do we want to reset the idle timer here? 431 // TODO(sandersd): Do we want to reset the idle timer here?
427 delegate_->SetIdle(delegate_id_, false); 432 delegate_->SetIdle(delegate_id_, false);
428 paused_ = false; 433 paused_ = false;
429 pipeline_.SetPlaybackRate(playback_rate_); 434 pipeline_.SetPlaybackRate(playback_rate_);
(...skipping 16 matching lines...) Expand all
446 DCHECK(main_task_runner_->BelongsToCurrentThread()); 451 DCHECK(main_task_runner_->BelongsToCurrentThread());
447 452
448 // We update the paused state even when casting, since we expect pause() to be 453 // We update the paused state even when casting, since we expect pause() to be
449 // called when casting begins, and when we exit casting we should end up in a 454 // called when casting begins, and when we exit casting we should end up in a
450 // paused state. 455 // paused state.
451 paused_ = true; 456 paused_ = true;
452 457
453 // No longer paused because it was hidden. 458 // No longer paused because it was hidden.
454 paused_when_hidden_ = false; 459 paused_when_hidden_ = false;
455 460
461 // User initiated pause locks background videos.
462 if (blink::WebUserGestureIndicator::isProcessingUserGesture())
463 video_locked_when_paused_when_hidden_ = true;
464
456 #if defined(OS_ANDROID) // WMPI_CAST 465 #if defined(OS_ANDROID) // WMPI_CAST
457 if (isRemote()) { 466 if (isRemote()) {
458 cast_impl_.pause(); 467 cast_impl_.pause();
459 return; 468 return;
460 } 469 }
461 #endif 470 #endif
462 471
463 pipeline_.SetPlaybackRate(0.0); 472 pipeline_.SetPlaybackRate(0.0);
464 473
465 // pause() may be called after playback has ended and the HTMLMediaElement 474 // pause() may be called after playback has ended and the HTMLMediaElement
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
1420 video_weblayer_->layer()->SetContentsOpaque(opaque_); 1429 video_weblayer_->layer()->SetContentsOpaque(opaque_);
1421 } 1430 }
1422 1431
1423 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() { 1432 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() {
1424 UpdateBackgroundVideoOptimizationState(); 1433 UpdateBackgroundVideoOptimizationState();
1425 } 1434 }
1426 1435
1427 void WebMediaPlayerImpl::OnFrameHidden() { 1436 void WebMediaPlayerImpl::OnFrameHidden() {
1428 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1437 DCHECK(main_task_runner_->BelongsToCurrentThread());
1429 1438
1439 // Backgrounding a video requires a user gesture to resume playback.
1440 if (IsHidden())
1441 video_locked_when_paused_when_hidden_ = true;
1442
1430 if (watch_time_reporter_) 1443 if (watch_time_reporter_)
1431 watch_time_reporter_->OnHidden(); 1444 watch_time_reporter_->OnHidden();
1432 1445
1433 // OnFrameHidden() can be called when frame is closed, then IsHidden() will 1446 UpdateBackgroundVideoOptimizationState();
1434 // return false, so check explicitly.
1435 if (IsHidden()) {
1436 if (ShouldPauseVideoWhenHidden()) {
1437 PauseVideoIfNeeded();
1438 return;
1439 } else {
1440 DisableVideoTrackIfNeeded();
1441 }
1442 }
1443
1444 UpdatePlayState(); 1447 UpdatePlayState();
1445 1448
1446 // Schedule suspended playing media to be paused if the user doesn't come back 1449 // Schedule suspended playing media to be paused if the user doesn't come back
1447 // to it within some timeout period to avoid any autoplay surprises. 1450 // to it within some timeout period to avoid any autoplay surprises.
1448 ScheduleIdlePauseTimer(); 1451 ScheduleIdlePauseTimer();
1449 } 1452 }
1450 1453
1451 void WebMediaPlayerImpl::OnFrameClosed() { 1454 void WebMediaPlayerImpl::OnFrameClosed() {
1452 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1455 DCHECK(main_task_runner_->BelongsToCurrentThread());
1453 UpdatePlayState(); 1456 UpdatePlayState();
1454 } 1457 }
1455 1458
1456 void WebMediaPlayerImpl::OnFrameShown() { 1459 void WebMediaPlayerImpl::OnFrameShown() {
1457 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1460 DCHECK(main_task_runner_->BelongsToCurrentThread());
1458 background_pause_timer_.Stop(); 1461 background_pause_timer_.Stop();
1459 1462
1463 // Foreground videos don't require user gesture to continue playback.
1464 video_locked_when_paused_when_hidden_ = false;
1465
1460 if (watch_time_reporter_) 1466 if (watch_time_reporter_)
1461 watch_time_reporter_->OnShown(); 1467 watch_time_reporter_->OnShown();
1462 1468
1463 // Only track the time to the first frame if playing or about to play because 1469 // Only track the time to the first frame if playing or about to play because
1464 // of being shown and only for videos we would optimize background playback 1470 // of being shown and only for videos we would optimize background playback
1465 // for. 1471 // for.
1466 if ((!paused_ && IsBackgroundOptimizationCandidate()) || 1472 if ((!paused_ && IsBackgroundOptimizationCandidate()) ||
1467 paused_when_hidden_) { 1473 paused_when_hidden_) {
1468 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb = 1474 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb =
1469 BindToCurrentLoop(base::Bind( 1475 BindToCurrentLoop(base::Bind(
1470 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame, 1476 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame,
1471 AsWeakPtr(), base::TimeTicks::Now())); 1477 AsWeakPtr(), base::TimeTicks::Now()));
1472 compositor_task_runner_->PostTask( 1478 compositor_task_runner_->PostTask(
1473 FROM_HERE, 1479 FROM_HERE,
1474 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback, 1480 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback,
1475 base::Unretained(compositor_), new_processed_frame_cb)); 1481 base::Unretained(compositor_), new_processed_frame_cb));
1476 } 1482 }
1477 1483
1484 EnableVideoTrackIfNeeded();
1485
1478 if (paused_when_hidden_) { 1486 if (paused_when_hidden_) {
1479 paused_when_hidden_ = false; 1487 paused_when_hidden_ = false;
1480 OnPlay(); // Calls UpdatePlayState() so return afterwards. 1488 OnPlay(); // Calls UpdatePlayState() so return afterwards.
1481 return; 1489 return;
1482 } 1490 }
1483 1491
1484 EnableVideoTrackIfNeeded();
1485
1486 UpdatePlayState(); 1492 UpdatePlayState();
1487 } 1493 }
1488 1494
1489 void WebMediaPlayerImpl::OnIdleTimeout() { 1495 void WebMediaPlayerImpl::OnIdleTimeout() {
1490 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1496 DCHECK(main_task_runner_->BelongsToCurrentThread());
1491 1497
1492 // If we are attempting preroll, clear the stale flag. 1498 // If we are attempting preroll, clear the stale flag.
1493 if (IsPrerollAttemptNeeded()) { 1499 if (IsPrerollAttemptNeeded()) {
1494 delegate_->ClearStaleFlag(delegate_id_); 1500 delegate_->ClearStaleFlag(delegate_id_);
1495 return; 1501 return;
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 bool is_backgrounded) { 1946 bool is_backgrounded) {
1941 PlayState result; 1947 PlayState result;
1942 1948
1943 bool must_suspend = delegate_->IsFrameClosed(); 1949 bool must_suspend = delegate_->IsFrameClosed();
1944 bool is_stale = delegate_->IsStale(delegate_id_); 1950 bool is_stale = delegate_->IsStale(delegate_id_);
1945 1951
1946 // This includes both data source (before pipeline startup) and pipeline 1952 // This includes both data source (before pipeline startup) and pipeline
1947 // errors. 1953 // errors.
1948 bool has_error = IsNetworkStateError(network_state_); 1954 bool has_error = IsNetworkStateError(network_state_);
1949 1955
1950 // After HaveMetadata, we know which tracks are present and the duration.
1951 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata;
1952
1953 // After HaveFutureData, Blink will call play() if the state is not paused; 1956 // After HaveFutureData, Blink will call play() if the state is not paused;
1954 // prior to this point |paused_| is not accurate. 1957 // prior to this point |paused_| is not accurate.
1955 bool have_future_data = 1958 bool have_future_data =
1956 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; 1959 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData;
1957 1960
1958 // Background suspend is not enabled for audio-only players unless paused, 1961 // Background suspend is only enabled for paused players.
1959 // though in the case of audio-only the session should be kept. 1962 // In the case of players with audio the session should be kept.
1960 // Videos are not suspended if the user resumed the playback via the remote 1963 bool background_suspended =
1961 // controls earlier and it's still playing.
1962 bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo();
1963 bool can_play_backgrounded = is_backgrounded_video && !is_remote &&
1964 hasAudio() && IsResumeBackgroundVideosEnabled();
1965 bool is_background_playing = delegate_->IsBackgroundVideoPlaybackUnlocked();
1966 bool background_suspended = can_auto_suspend && is_backgrounded_video &&
1967 !(can_play_backgrounded && is_background_playing);
1968 bool background_pause_suspended =
1969 can_auto_suspend && is_backgrounded && paused_ && have_future_data; 1964 can_auto_suspend && is_backgrounded && paused_ && have_future_data;
1970 1965
1971 // Idle suspension is allowed prior to have future data since there exist 1966 // Idle suspension is allowed prior to have future data since there exist
1972 // mechanisms to exit the idle state when the player is capable of reaching 1967 // mechanisms to exit the idle state when the player is capable of reaching
1973 // the have future data state; see didLoadingProgress(). 1968 // the have future data state; see didLoadingProgress().
1974 // 1969 //
1975 // TODO(sandersd): Make the delegate suspend idle players immediately when 1970 // TODO(sandersd): Make the delegate suspend idle players immediately when
1976 // hidden. 1971 // hidden.
1977 bool idle_suspended = 1972 bool idle_suspended =
1978 can_auto_suspend && is_stale && paused_ && !seeking_ && !overlay_enabled_; 1973 can_auto_suspend && is_stale && paused_ && !seeking_ && !overlay_enabled_;
1979 1974
1980 // If we're already suspended, see if we can wait for user interaction. Prior 1975 // If we're already suspended, see if we can wait for user interaction. Prior
1981 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale| 1976 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale|
1982 // will be cleared when we receive data which may take us to HaveFutureData. 1977 // will be cleared when we receive data which may take us to HaveFutureData.
1983 bool can_stay_suspended = 1978 bool can_stay_suspended =
1984 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_; 1979 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_;
1985 1980
1986 // Combined suspend state. 1981 // Combined suspend state.
1987 result.is_suspended = is_remote || must_suspend || idle_suspended || 1982 result.is_suspended = is_remote || must_suspend || idle_suspended ||
1988 background_suspended || background_pause_suspended || 1983 background_suspended || can_stay_suspended;
1989 can_stay_suspended;
1990 1984
1991 // We do not treat |playback_rate_| == 0 as paused. For the media session, 1985 // We do not treat |playback_rate_| == 0 as paused. For the media session,
1992 // being paused implies displaying a play button, which is incorrect in this 1986 // being paused implies displaying a play button, which is incorrect in this
1993 // case. For memory usage reporting, we just use the same definition (but we 1987 // case. For memory usage reporting, we just use the same definition (but we
1994 // don't have to). 1988 // don't have to).
1995 // 1989 //
1996 // Similarly, we don't consider |ended_| to be paused. Blink will immediately 1990 // Similarly, we don't consider |ended_| to be paused. Blink will immediately
1997 // call pause() or seek(), so |ended_| should not affect the computation. 1991 // call pause() or seek(), so |ended_| should not affect the computation.
1998 // Despite that, |ended_| does result in a separate paused state, to simplfy 1992 // Despite that, |ended_| does result in a separate paused state, to simplfy
1999 // the contract for SetDelegateState(). 1993 // the contract for SetDelegateState().
2000 // 1994 //
2001 // |has_session| is used to decide when to create a media session. Idle 1995 // |has_remote_controls| indicates if the player can be controlled outside the
1996 // page (e.g. via the notification controls or by audio focus events). Idle
2002 // suspension does not destroy the media session, because we expect that the 1997 // suspension does not destroy the media session, because we expect that the
2003 // notification controls (and audio focus) remain. We also require: 1998 // notification controls (and audio focus) remain. The following must be true
2004 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). 1999 // for the player to have remote controls:
2005 // - |have_future_data|, since we need to know whether we are paused to 2000 // - |have_future_data|, since we need to know whether we are paused to
2006 // correctly configure the session. 2001 // correctly configure the session and also because the tracks and
2002 // duration are passed to DidPlay()
2003 // - |is_remote| is false as remote players have their own controls
2004 // - |has_error| is false player should have no errors
2005 // - hasAudio() (requires |have_future_data|)
2007 // 2006 //
2008 // TODO(sandersd): If Blink told us the paused state sooner, we could create 2007 // TODO(sandersd): If Blink told us the paused state sooner, we could detect
2009 // the media session sooner. 2008 // if the remote controls are available sooner.
2009
2010 // Background videos with audio don't have remote controls if background
2011 // suspend is enabled and resuming background videos is not (original Android
2012 // behavior).
2013 bool backgrounded_video_has_no_remote_controls =
2014 IsBackgroundedSuspendEnabled() && !IsResumeBackgroundVideosEnabled() &&
2015 is_backgrounded && hasVideo();
2010 bool can_play = !has_error && !is_remote && have_future_data; 2016 bool can_play = !has_error && !is_remote && have_future_data;
2011 bool has_session_playing = can_play && !must_suspend && !background_suspended; 2017 bool has_remote_controls = can_play && !must_suspend && hasAudio() &&
2018 !backgrounded_video_has_no_remote_controls;
2012 2019
2013 // |has_session_suspended| means the player is suspended from the media 2020 if (!has_remote_controls) {
2014 // element point of view but paused and can be resumed from the delegate point
2015 // of view. Therefore it behaves like |paused_| for the delegate.
2016 bool has_session_suspended = can_play && !must_suspend &&
2017 background_suspended && can_play_backgrounded;
2018
2019 bool has_session = has_session_playing || has_session_suspended;
2020
2021 if (!has_session) {
2022 result.delegate_state = DelegateState::GONE; 2021 result.delegate_state = DelegateState::GONE;
2023 result.is_idle = delegate_->IsIdle(delegate_id_); 2022 result.is_idle = delegate_->IsIdle(delegate_id_);
2024 } else if (paused_ || has_session_suspended) { 2023 } else if (paused_) {
2025 // TODO(sandersd): Is it possible to have a suspended session, be ended, 2024 // TODO(sandersd): Is it possible to have a suspended session, be ended,
2026 // and not be paused? If so we should be in a PLAYING state. 2025 // and not be paused? If so we should be in a PLAYING state.
2027 result.delegate_state = 2026 result.delegate_state =
2028 ended_ ? DelegateState::GONE : DelegateState::PAUSED; 2027 ended_ ? DelegateState::GONE : DelegateState::PAUSED;
2029 result.is_idle = !seeking_; 2028 result.is_idle = !seeking_;
2030 } else { 2029 } else {
2031 result.delegate_state = DelegateState::PLAYING; 2030 result.delegate_state = DelegateState::PLAYING;
2032 result.is_idle = false; 2031 result.is_idle = false;
2033 } 2032 }
2034 2033
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource", 2091 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource",
2093 data_source_memory_usage / 1024); 2092 data_source_memory_usage / 1024);
2094 } 2093 }
2095 if (demuxer_) { 2094 if (demuxer_) {
2096 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer", 2095 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer",
2097 demuxer_memory_usage / 1024); 2096 demuxer_memory_usage / 1024);
2098 } 2097 }
2099 } 2098 }
2100 2099
2101 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { 2100 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() {
2102 // Only schedule the pause timer if we're playing and are suspended. 2101 // Only schedule the pause timer if we're not paused or paused but going to
2103 if (paused_ || !pipeline_controller_.IsSuspended()) 2102 // resume when foregrounded, and are suspended.
2103 if ((paused_ && !paused_when_hidden_) || !pipeline_controller_.IsSuspended())
2104 return; 2104 return;
2105 2105
2106 #if defined(OS_ANDROID) 2106 #if defined(OS_ANDROID)
2107 // Remote players will be suspended and locally paused. 2107 // Remote players will be suspended and locally paused.
2108 if (isRemote()) 2108 if (isRemote())
2109 return; 2109 return;
2110 #endif 2110 #endif
2111 2111
2112 // Idle timeout chosen arbitrarily. 2112 // Idle timeout chosen arbitrarily.
2113 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), 2113 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5),
(...skipping 27 matching lines...) Expand all
2141 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; 2141 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0;
2142 } 2142 }
2143 2143
2144 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { 2144 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) {
2145 DCHECK(main_task_runner_->BelongsToCurrentThread()); 2145 DCHECK(main_task_runner_->BelongsToCurrentThread());
2146 2146
2147 client_->activateViewportIntersectionMonitoring(activate); 2147 client_->activateViewportIntersectionMonitoring(activate);
2148 } 2148 }
2149 2149
2150 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { 2150 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const {
2151 #if !defined(OS_ANDROID) 2151 // If suspending background video, pause any video that's not remoted or
2152 // On desktop, this behavior is behind the feature flag. 2152 // not unlocked to play in the background.
2153 if (!IsBackgroundVideoTrackOptimizationEnabled()) 2153 if (IsBackgroundedSuspendEnabled()) {
2154 return false; 2154 if (!hasVideo())
2155 return false;
2156
2157 #if defined(OS_ANDROID)
2158 if (isRemote())
2159 return false;
2155 #endif 2160 #endif
2156 2161
2157 // Pause video-only players that match the criteria for being optimized. 2162 return !hasAudio() ||
2158 return !hasAudio() && IsBackgroundOptimizationCandidate(); 2163 (IsResumeBackgroundVideosEnabled() &&
2164 video_locked_when_paused_when_hidden_);
2165 }
2166
2167 // Otherwise only pause if the optimization is on and it's a video-only
2168 // optimization candidate.
2169 return IsBackgroundVideoTrackOptimizationEnabled() && !hasAudio() &&
2170 IsBackgroundOptimizationCandidate();
2159 } 2171 }
2160 2172
2161 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { 2173 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const {
2162 // This optimization is behind the flag on all platforms. 2174 // This optimization is behind the flag on all platforms.
2163 if (!IsBackgroundVideoTrackOptimizationEnabled()) 2175 if (!IsBackgroundVideoTrackOptimizationEnabled())
2164 return false; 2176 return false;
2165 2177
2166 // Disable video track only for players with audio that match the criteria for 2178 // Disable video track only for players with audio that match the criteria for
2167 // being optimized. 2179 // being optimized.
2168 return hasAudio() && IsBackgroundOptimizationCandidate(); 2180 return hasAudio() && IsBackgroundOptimizationCandidate();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2279 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time; 2291 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time;
2280 if (hasAudio()) { 2292 if (hasAudio()) {
2281 UMA_HISTOGRAM_TIMES( 2293 UMA_HISTOGRAM_TIMES(
2282 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", 2294 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack",
2283 time_to_first_frame); 2295 time_to_first_frame);
2284 } else { 2296 } else {
2285 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", 2297 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused",
2286 time_to_first_frame); 2298 time_to_first_frame);
2287 } 2299 }
2288 } 2300 }
2289
2290 void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) { 2301 void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) {
2291 DCHECK(main_task_runner_->BelongsToCurrentThread()); 2302 DCHECK(main_task_runner_->BelongsToCurrentThread());
2292 disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend; 2303 disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend;
2293 ScheduleRestart(); 2304 ScheduleRestart();
2294 } 2305 }
2295 2306
2296 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) { 2307 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) {
2297 DCHECK(data_source_ || chunk_demuxer_); 2308 DCHECK(data_source_ || chunk_demuxer_);
2298 if (data_source_) 2309 if (data_source_)
2299 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", duration); 2310 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", duration);
2300 else 2311 else
2301 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration.MSE", duration); 2312 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration.MSE", duration);
2302 } 2313 }
2303 2314
2304 } // namespace media 2315 } // namespace media
OLDNEW
« 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