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

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

Issue 2705213007: [Video] MediaSession API event handlers can resume background video. (Closed)
Patch Set: Fixed WMPA 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" 55 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
56 #include "third_party/WebKit/public/platform/WebMediaSource.h" 56 #include "third_party/WebKit/public/platform/WebMediaSource.h"
57 #include "third_party/WebKit/public/platform/WebRect.h" 57 #include "third_party/WebKit/public/platform/WebRect.h"
58 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" 58 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
59 #include "third_party/WebKit/public/platform/WebSize.h" 59 #include "third_party/WebKit/public/platform/WebSize.h"
60 #include "third_party/WebKit/public/platform/WebString.h" 60 #include "third_party/WebKit/public/platform/WebString.h"
61 #include "third_party/WebKit/public/platform/WebURL.h" 61 #include "third_party/WebKit/public/platform/WebURL.h"
62 #include "third_party/WebKit/public/web/WebDocument.h" 62 #include "third_party/WebKit/public/web/WebDocument.h"
63 #include "third_party/WebKit/public/web/WebFrame.h" 63 #include "third_party/WebKit/public/web/WebFrame.h"
64 #include "third_party/WebKit/public/web/WebLocalFrame.h" 64 #include "third_party/WebKit/public/web/WebLocalFrame.h"
65 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
65 #include "third_party/WebKit/public/web/WebView.h" 66 #include "third_party/WebKit/public/web/WebView.h"
66 67
67 #if defined(OS_ANDROID) 68 #if defined(OS_ANDROID)
68 #include "media/base/android/media_codec_util.h" 69 #include "media/base/android/media_codec_util.h"
69 #endif 70 #endif
70 71
71 using blink::WebCanvas; 72 using blink::WebCanvas;
72 using blink::WebMediaPlayer; 73 using blink::WebMediaPlayer;
73 using blink::WebRect; 74 using blink::WebRect;
74 using blink::WebSize; 75 using blink::WebSize;
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 413
413 #if defined(OS_ANDROID) // WMPI_CAST 414 #if defined(OS_ANDROID) // WMPI_CAST
414 cast_impl_.Initialize(url, frame_, delegate_id_); 415 cast_impl_.Initialize(url, frame_, delegate_id_);
415 #endif 416 #endif
416 } 417 }
417 418
418 void WebMediaPlayerImpl::play() { 419 void WebMediaPlayerImpl::play() {
419 DVLOG(1) << __func__; 420 DVLOG(1) << __func__;
420 DCHECK(main_task_runner_->BelongsToCurrentThread()); 421 DCHECK(main_task_runner_->BelongsToCurrentThread());
421 422
423 // User initiated play unlocks background video playback.
424 if (blink::WebUserGestureIndicator::isProcessingUserGesture())
425 video_locked_when_paused_when_hidden_ = false;
426
422 #if defined(OS_ANDROID) // WMPI_CAST 427 #if defined(OS_ANDROID) // WMPI_CAST
423 if (isRemote()) { 428 if (isRemote()) {
424 cast_impl_.play(); 429 cast_impl_.play();
425 return; 430 return;
426 } 431 }
427 #endif 432 #endif
428 // TODO(sandersd): Do we want to reset the idle timer here? 433 // TODO(sandersd): Do we want to reset the idle timer here?
429 if (delegate_) 434 if (delegate_)
430 delegate_->SetIdle(delegate_id_, false); 435 delegate_->SetIdle(delegate_id_, false);
431 paused_ = false; 436 paused_ = false;
(...skipping 17 matching lines...) Expand all
449 DCHECK(main_task_runner_->BelongsToCurrentThread()); 454 DCHECK(main_task_runner_->BelongsToCurrentThread());
450 455
451 // We update the paused state even when casting, since we expect pause() to be 456 // We update the paused state even when casting, since we expect pause() to be
452 // called when casting begins, and when we exit casting we should end up in a 457 // called when casting begins, and when we exit casting we should end up in a
453 // paused state. 458 // paused state.
454 paused_ = true; 459 paused_ = true;
455 460
456 // No longer paused because it was hidden. 461 // No longer paused because it was hidden.
457 paused_when_hidden_ = false; 462 paused_when_hidden_ = false;
458 463
464 // User initiated pause locks background videos.
465 if (blink::WebUserGestureIndicator::isProcessingUserGesture())
466 video_locked_when_paused_when_hidden_ = true;
467
459 #if defined(OS_ANDROID) // WMPI_CAST 468 #if defined(OS_ANDROID) // WMPI_CAST
460 if (isRemote()) { 469 if (isRemote()) {
461 cast_impl_.pause(); 470 cast_impl_.pause();
462 return; 471 return;
463 } 472 }
464 #endif 473 #endif
465 474
466 pipeline_.SetPlaybackRate(0.0); 475 pipeline_.SetPlaybackRate(0.0);
467 476
468 // pause() may be called after playback has ended and the HTMLMediaElement 477 // pause() may be called after playback has ended and the HTMLMediaElement
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 video_weblayer_->layer()->SetContentsOpaque(opaque_); 1404 video_weblayer_->layer()->SetContentsOpaque(opaque_);
1396 } 1405 }
1397 1406
1398 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() { 1407 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() {
1399 UpdateBackgroundVideoOptimizationState(); 1408 UpdateBackgroundVideoOptimizationState();
1400 } 1409 }
1401 1410
1402 void WebMediaPlayerImpl::OnFrameHidden() { 1411 void WebMediaPlayerImpl::OnFrameHidden() {
1403 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1412 DCHECK(main_task_runner_->BelongsToCurrentThread());
1404 1413
1414 // Backgrounding a video requires a user gesture to resume playback.
1415 if (IsHidden())
1416 video_locked_when_paused_when_hidden_ = true;
1417
1405 if (watch_time_reporter_) 1418 if (watch_time_reporter_)
1406 watch_time_reporter_->OnHidden(); 1419 watch_time_reporter_->OnHidden();
1407 1420
1408 // OnFrameHidden() can be called when frame is closed, then IsHidden() will 1421 UpdateBackgroundVideoOptimizationState();
1409 // return false, so check explicitly.
1410 if (IsHidden()) {
1411 if (ShouldPauseVideoWhenHidden()) {
1412 PauseVideoIfNeeded();
1413 return;
1414 } else {
1415 DisableVideoTrackIfNeeded();
1416 }
1417 }
1418
1419 UpdatePlayState(); 1422 UpdatePlayState();
1420 1423
1421 // Schedule suspended playing media to be paused if the user doesn't come back 1424 // Schedule suspended playing media to be paused if the user doesn't come back
1422 // to it within some timeout period to avoid any autoplay surprises. 1425 // to it within some timeout period to avoid any autoplay surprises.
1423 ScheduleIdlePauseTimer(); 1426 ScheduleIdlePauseTimer();
1424 } 1427 }
1425 1428
1426 void WebMediaPlayerImpl::OnFrameClosed() { 1429 void WebMediaPlayerImpl::OnFrameClosed() {
1427 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1430 DCHECK(main_task_runner_->BelongsToCurrentThread());
1428 UpdatePlayState(); 1431 UpdatePlayState();
1429 } 1432 }
1430 1433
1431 void WebMediaPlayerImpl::OnFrameShown() { 1434 void WebMediaPlayerImpl::OnFrameShown() {
1432 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1435 DCHECK(main_task_runner_->BelongsToCurrentThread());
1433 background_pause_timer_.Stop(); 1436 background_pause_timer_.Stop();
1434 1437
1438 // Foreground videos don't require user gesture to continue playback.
1439 video_locked_when_paused_when_hidden_ = false;
1440
1435 if (watch_time_reporter_) 1441 if (watch_time_reporter_)
1436 watch_time_reporter_->OnShown(); 1442 watch_time_reporter_->OnShown();
1437 1443
1438 // Only track the time to the first frame if playing or about to play because 1444 // Only track the time to the first frame if playing or about to play because
1439 // of being shown and only for videos we would optimize background playback 1445 // of being shown and only for videos we would optimize background playback
1440 // for. 1446 // for.
1441 if ((!paused_ && IsBackgroundOptimizationCandidate()) || 1447 if ((!paused_ && IsBackgroundOptimizationCandidate()) ||
1442 paused_when_hidden_) { 1448 paused_when_hidden_) {
1443 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb = 1449 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb =
1444 BIND_TO_RENDER_LOOP1( 1450 BIND_TO_RENDER_LOOP1(
1445 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame, 1451 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame,
1446 base::TimeTicks::Now()); 1452 base::TimeTicks::Now());
1447 compositor_task_runner_->PostTask( 1453 compositor_task_runner_->PostTask(
1448 FROM_HERE, 1454 FROM_HERE,
1449 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback, 1455 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback,
1450 base::Unretained(compositor_), new_processed_frame_cb)); 1456 base::Unretained(compositor_), new_processed_frame_cb));
1451 } 1457 }
1452 1458
1459 EnableVideoTrackIfNeeded();
1460
1453 if (paused_when_hidden_) { 1461 if (paused_when_hidden_) {
1454 paused_when_hidden_ = false; 1462 paused_when_hidden_ = false;
1455 OnPlay(); // Calls UpdatePlayState() so return afterwards. 1463 OnPlay(); // Calls UpdatePlayState() so return afterwards.
1456 return; 1464 return;
1457 } 1465 }
1458 1466
1459 EnableVideoTrackIfNeeded();
1460
1461 UpdatePlayState(); 1467 UpdatePlayState();
1462 } 1468 }
1463 1469
1464 void WebMediaPlayerImpl::OnIdleTimeout() { 1470 void WebMediaPlayerImpl::OnIdleTimeout() {
1465 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1471 DCHECK(main_task_runner_->BelongsToCurrentThread());
1466 1472
1467 // If we are attempting preroll, clear the stale flag. 1473 // If we are attempting preroll, clear the stale flag.
1468 if (IsPrerollAttemptNeeded()) { 1474 if (IsPrerollAttemptNeeded()) {
1469 if (delegate_) 1475 if (delegate_)
1470 delegate_->ClearStaleFlag(delegate_id_); 1476 delegate_->ClearStaleFlag(delegate_id_);
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 bool is_backgrounded) { 1924 bool is_backgrounded) {
1919 PlayState result; 1925 PlayState result;
1920 1926
1921 bool must_suspend = delegate_ && delegate_->IsFrameClosed(); 1927 bool must_suspend = delegate_ && delegate_->IsFrameClosed();
1922 bool is_stale = delegate_ && delegate_->IsStale(delegate_id_); 1928 bool is_stale = delegate_ && delegate_->IsStale(delegate_id_);
1923 1929
1924 // This includes both data source (before pipeline startup) and pipeline 1930 // This includes both data source (before pipeline startup) and pipeline
1925 // errors. 1931 // errors.
1926 bool has_error = IsNetworkStateError(network_state_); 1932 bool has_error = IsNetworkStateError(network_state_);
1927 1933
1928 // After HaveMetadata, we know which tracks are present and the duration.
1929 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata;
1930
1931 // After HaveFutureData, Blink will call play() if the state is not paused; 1934 // After HaveFutureData, Blink will call play() if the state is not paused;
1932 // prior to this point |paused_| is not accurate. 1935 // prior to this point |paused_| is not accurate.
1933 bool have_future_data = 1936 bool have_future_data =
1934 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; 1937 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData;
1935 1938
1936 // Background suspend is not enabled for audio-only players unless paused, 1939 // Background suspend is only enabled for paused players.
1937 // though in the case of audio-only the session should be kept. 1940 // In the case of players with audio the session should be kept.
1938 // Videos are not suspended if the user resumed the playback via the remote 1941 bool background_suspended =
1939 // controls earlier and it's still playing.
1940 bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo();
1941 bool can_play_backgrounded = is_backgrounded_video && !is_remote &&
1942 hasAudio() && IsResumeBackgroundVideosEnabled();
1943 bool is_background_playing =
1944 delegate_ && delegate_->IsBackgroundVideoPlaybackUnlocked();
1945 bool background_suspended = !is_streaming && is_backgrounded_video &&
1946 !(can_play_backgrounded && is_background_playing);
1947 bool background_pause_suspended =
1948 !is_streaming && is_backgrounded && paused_ && have_future_data; 1942 !is_streaming && is_backgrounded && paused_ && have_future_data;
1949 1943
1950 // Idle suspension is allowed prior to have future data since there exist 1944 // Idle suspension is allowed prior to have future data since there exist
1951 // mechanisms to exit the idle state when the player is capable of reaching 1945 // mechanisms to exit the idle state when the player is capable of reaching
1952 // the have future data state; see didLoadingProgress(). 1946 // the have future data state; see didLoadingProgress().
1953 // 1947 //
1954 // TODO(sandersd): Make the delegate suspend idle players immediately when 1948 // TODO(sandersd): Make the delegate suspend idle players immediately when
1955 // hidden. 1949 // hidden.
1956 bool idle_suspended = 1950 bool idle_suspended =
1957 !is_streaming && is_stale && paused_ && !seeking_ && !overlay_enabled_; 1951 !is_streaming && is_stale && paused_ && !seeking_ && !overlay_enabled_;
1958 1952
1959 // If we're already suspended, see if we can wait for user interaction. Prior 1953 // If we're already suspended, see if we can wait for user interaction. Prior
1960 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale| 1954 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale|
1961 // will be cleared when we receive data which may take us to HaveFutureData. 1955 // will be cleared when we receive data which may take us to HaveFutureData.
1962 bool can_stay_suspended = 1956 bool can_stay_suspended =
1963 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_; 1957 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_;
1964 1958
1965 // Combined suspend state. 1959 // Combined suspend state.
1966 result.is_suspended = is_remote || must_suspend || idle_suspended || 1960 result.is_suspended = is_remote || must_suspend || idle_suspended ||
1967 background_suspended || background_pause_suspended || 1961 background_suspended || can_stay_suspended;
1968 can_stay_suspended;
1969 1962
1970 // We do not treat |playback_rate_| == 0 as paused. For the media session, 1963 // We do not treat |playback_rate_| == 0 as paused. For the media session,
1971 // being paused implies displaying a play button, which is incorrect in this 1964 // being paused implies displaying a play button, which is incorrect in this
1972 // case. For memory usage reporting, we just use the same definition (but we 1965 // case. For memory usage reporting, we just use the same definition (but we
1973 // don't have to). 1966 // don't have to).
1974 // 1967 //
1975 // Similarly, we don't consider |ended_| to be paused. Blink will immediately 1968 // Similarly, we don't consider |ended_| to be paused. Blink will immediately
1976 // call pause() or seek(), so |ended_| should not affect the computation. 1969 // call pause() or seek(), so |ended_| should not affect the computation.
1977 // Despite that, |ended_| does result in a separate paused state, to simplfy 1970 // Despite that, |ended_| does result in a separate paused state, to simplfy
1978 // the contract for SetDelegateState(). 1971 // the contract for SetDelegateState().
1979 // 1972 //
1980 // |has_session| is used to decide when to create a media session. Idle 1973 // |has_remote_controls| indicates if the player can be controlled outside the
1974 // page (e.g. via the notification controls or by audio focus events). Idle
1981 // suspension does not destroy the media session, because we expect that the 1975 // suspension does not destroy the media session, because we expect that the
1982 // notification controls (and audio focus) remain. We also require: 1976 // notification controls (and audio focus) remain. The following must be true
1983 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). 1977 // for the player to have remote controls:
1984 // - |have_future_data|, since we need to know whether we are paused to 1978 // - |have_future_data|, since we need to know whether we are paused to
1985 // correctly configure the session. 1979 // correctly configure the session and also because the tracks and
1980 // duration are passed to DidPlay()
1981 // - |is_remote| is false as remote players have their own controls
1982 // - |has_error| is false player should have no errors
1983 // - hasAudio() (requires |have_future_data|)
1986 // 1984 //
1987 // TODO(sandersd): If Blink told us the paused state sooner, we could create 1985 // TODO(sandersd): If Blink told us the paused state sooner, we could detect
1988 // the media session sooner. 1986 // if the remote controls are available sooner.
1987
1988 // Background videos with audio don't have remote controls if background
1989 // suspend is enabled and resuming background videos is not (original Android
1990 // behavior).
1991 bool backgrounded_video_has_no_remote_controls =
1992 IsBackgroundedSuspendEnabled() && !IsResumeBackgroundVideosEnabled() &&
1993 is_backgrounded && hasVideo();
1989 bool can_play = !has_error && !is_remote && have_future_data; 1994 bool can_play = !has_error && !is_remote && have_future_data;
1990 bool has_session_playing = can_play && !must_suspend && !background_suspended; 1995 bool has_remote_controls = can_play && !must_suspend && hasAudio() &&
1996 !backgrounded_video_has_no_remote_controls;
1991 1997
1992 // |has_session_suspended| means the player is suspended from the media 1998 if (!has_remote_controls) {
1993 // element point of view but paused and can be resumed from the delegate point
1994 // of view. Therefore it behaves like |paused_| for the delegate.
1995 bool has_session_suspended = can_play && !must_suspend &&
1996 background_suspended && can_play_backgrounded;
1997
1998 bool has_session = has_session_playing || has_session_suspended;
1999
2000 if (!has_session) {
2001 result.delegate_state = DelegateState::GONE; 1999 result.delegate_state = DelegateState::GONE;
2002 result.is_idle = delegate_ && delegate_->IsIdle(delegate_id_); 2000 result.is_idle = delegate_ && delegate_->IsIdle(delegate_id_);
2003 } else if (paused_ || has_session_suspended) { 2001 } else if (paused_) {
2004 // TODO(sandersd): Is it possible to have a suspended session, be ended, 2002 // TODO(sandersd): Is it possible to have a suspended session, be ended,
2005 // and not be paused? If so we should be in a PLAYING state. 2003 // and not be paused? If so we should be in a PLAYING state.
2006 result.delegate_state = 2004 result.delegate_state =
2007 ended_ ? DelegateState::GONE : DelegateState::PAUSED; 2005 ended_ ? DelegateState::GONE : DelegateState::PAUSED;
2008 result.is_idle = !seeking_; 2006 result.is_idle = !seeking_;
2009 } else { 2007 } else {
2010 result.delegate_state = DelegateState::PLAYING; 2008 result.delegate_state = DelegateState::PLAYING;
2011 result.is_idle = false; 2009 result.is_idle = false;
2012 } 2010 }
2013 2011
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource", 2069 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource",
2072 data_source_memory_usage / 1024); 2070 data_source_memory_usage / 1024);
2073 } 2071 }
2074 if (demuxer_) { 2072 if (demuxer_) {
2075 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer", 2073 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer",
2076 demuxer_memory_usage / 1024); 2074 demuxer_memory_usage / 1024);
2077 } 2075 }
2078 } 2076 }
2079 2077
2080 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { 2078 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() {
2081 // Only schedule the pause timer if we're playing and are suspended. 2079 // Only schedule the pause timer if we're not paused or paused but going to
2082 if (paused_ || !pipeline_controller_.IsSuspended()) 2080 // resume when foregrounded, and are suspended.
2081 if ((paused_ && !paused_when_hidden_) || !pipeline_controller_.IsSuspended())
2083 return; 2082 return;
2084 2083
2085 #if defined(OS_ANDROID) 2084 #if defined(OS_ANDROID)
2086 // Remote players will be suspended and locally paused. 2085 // Remote players will be suspended and locally paused.
2087 if (isRemote()) 2086 if (isRemote())
2088 return; 2087 return;
2089 #endif 2088 #endif
2090 2089
2091 // Idle timeout chosen arbitrarily. 2090 // Idle timeout chosen arbitrarily.
2092 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), 2091 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5),
(...skipping 27 matching lines...) Expand all
2120 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; 2119 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0;
2121 } 2120 }
2122 2121
2123 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { 2122 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) {
2124 DCHECK(main_task_runner_->BelongsToCurrentThread()); 2123 DCHECK(main_task_runner_->BelongsToCurrentThread());
2125 2124
2126 client_->activateViewportIntersectionMonitoring(activate); 2125 client_->activateViewportIntersectionMonitoring(activate);
2127 } 2126 }
2128 2127
2129 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { 2128 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const {
2130 #if !defined(OS_ANDROID) 2129 // If suspending background video, pause any video that's not remoted or
2131 // On desktop, this behavior is behind the feature flag. 2130 // not unlocked to play in the background.
2132 if (!IsBackgroundVideoTrackOptimizationEnabled()) 2131 if (IsBackgroundedSuspendEnabled()) {
2133 return false; 2132 if (!hasVideo())
2133 return false;
2134
2135 #if defined(OS_ANDROID)
2136 if (isRemote())
2137 return false;
2134 #endif 2138 #endif
2135 2139
2136 // Pause video-only players that match the criteria for being optimized. 2140 return !hasAudio() || (IsResumeBackgroundVideosEnabled() &&
2137 return !hasAudio() && IsBackgroundOptimizationCandidate(); 2141 video_locked_when_paused_when_hidden_);
2142 }
2143
2144 // Otherwise only pause if the optimization is on and it's a video-only
2145 // optimization candidate.
2146 return IsBackgroundVideoTrackOptimizationEnabled() && !hasAudio() &&
2147 IsBackgroundOptimizationCandidate();
2138 } 2148 }
2139 2149
2140 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { 2150 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const {
2141 // This optimization is behind the flag on all platforms. 2151 // This optimization is behind the flag on all platforms.
2142 if (!IsBackgroundVideoTrackOptimizationEnabled()) 2152 if (!IsBackgroundVideoTrackOptimizationEnabled())
2143 return false; 2153 return false;
2144 2154
2145 // Disable video track only for players with audio that match the criteria for 2155 // Disable video track only for players with audio that match the criteria for
2146 // being optimized. 2156 // being optimized.
2147 return hasAudio() && IsBackgroundOptimizationCandidate(); 2157 return hasAudio() && IsBackgroundOptimizationCandidate();
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2258 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time; 2268 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time;
2259 if (hasAudio()) { 2269 if (hasAudio()) {
2260 UMA_HISTOGRAM_TIMES( 2270 UMA_HISTOGRAM_TIMES(
2261 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", 2271 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack",
2262 time_to_first_frame); 2272 time_to_first_frame);
2263 } else { 2273 } else {
2264 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", 2274 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused",
2265 time_to_first_frame); 2275 time_to_first_frame);
2266 } 2276 }
2267 } 2277 }
2268
2269 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) { 2278 void WebMediaPlayerImpl::RecordUnderflowDuration(base::TimeDelta duration) {
2270 DCHECK(data_source_ || chunk_demuxer_); 2279 DCHECK(data_source_ || chunk_demuxer_);
2271 if (data_source_) 2280 if (data_source_)
2272 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", duration); 2281 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", duration);
2273 else 2282 else
2274 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration.MSE", duration); 2283 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration.MSE", duration);
2275 } 2284 }
2276 2285
2277 } // namespace media 2286 } // 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