OLD | NEW |
---|---|
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 Loading... | |
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 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 | 412 |
412 #if defined(OS_ANDROID) // WMPI_CAST | 413 #if defined(OS_ANDROID) // WMPI_CAST |
413 cast_impl_.Initialize(url, frame_, delegate_id_); | 414 cast_impl_.Initialize(url, frame_, delegate_id_); |
414 #endif | 415 #endif |
415 } | 416 } |
416 | 417 |
417 void WebMediaPlayerImpl::play() { | 418 void WebMediaPlayerImpl::play() { |
418 DVLOG(1) << __func__; | 419 DVLOG(1) << __func__; |
419 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 420 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
420 | 421 |
422 // User initiated play unlocks background video playback. | |
423 if (blink::WebUserGestureIndicator::isProcessingUserGesture()) | |
sandersd (OOO until July 31)
2017/02/23 00:38:31
Should we be consuming the gesture?
whywhat
2017/02/23 02:50:27
I don't think so, the page may call play() and pau
| |
424 video_locked_when_paused_when_hidden_ = false; | |
425 | |
421 #if defined(OS_ANDROID) // WMPI_CAST | 426 #if defined(OS_ANDROID) // WMPI_CAST |
422 if (isRemote()) { | 427 if (isRemote()) { |
423 cast_impl_.play(); | 428 cast_impl_.play(); |
424 return; | 429 return; |
425 } | 430 } |
426 #endif | 431 #endif |
427 // TODO(sandersd): Do we want to reset the idle timer here? | 432 // TODO(sandersd): Do we want to reset the idle timer here? |
428 delegate_->SetIdle(delegate_id_, false); | 433 delegate_->SetIdle(delegate_id_, false); |
429 paused_ = false; | 434 paused_ = false; |
430 pipeline_.SetPlaybackRate(playback_rate_); | 435 pipeline_.SetPlaybackRate(playback_rate_); |
(...skipping 16 matching lines...) Expand all Loading... | |
447 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 452 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
448 | 453 |
449 // We update the paused state even when casting, since we expect pause() to be | 454 // We update the paused state even when casting, since we expect pause() to be |
450 // called when casting begins, and when we exit casting we should end up in a | 455 // called when casting begins, and when we exit casting we should end up in a |
451 // paused state. | 456 // paused state. |
452 paused_ = true; | 457 paused_ = true; |
453 | 458 |
454 // No longer paused because it was hidden. | 459 // No longer paused because it was hidden. |
455 paused_when_hidden_ = false; | 460 paused_when_hidden_ = false; |
456 | 461 |
462 // User initiated pause locks background videos. | |
463 if (blink::WebUserGestureIndicator::isProcessingUserGesture()) | |
464 video_locked_when_paused_when_hidden_ = true; | |
465 | |
457 #if defined(OS_ANDROID) // WMPI_CAST | 466 #if defined(OS_ANDROID) // WMPI_CAST |
458 if (isRemote()) { | 467 if (isRemote()) { |
459 cast_impl_.pause(); | 468 cast_impl_.pause(); |
460 return; | 469 return; |
461 } | 470 } |
462 #endif | 471 #endif |
463 | 472 |
464 pipeline_.SetPlaybackRate(0.0); | 473 pipeline_.SetPlaybackRate(0.0); |
465 | 474 |
466 // pause() may be called after playback has ended and the HTMLMediaElement | 475 // pause() may be called after playback has ended and the HTMLMediaElement |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1427 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1436 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
1428 } | 1437 } |
1429 | 1438 |
1430 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() { | 1439 void WebMediaPlayerImpl::OnVideoAverageKeyframeDistanceUpdate() { |
1431 UpdateBackgroundVideoOptimizationState(); | 1440 UpdateBackgroundVideoOptimizationState(); |
1432 } | 1441 } |
1433 | 1442 |
1434 void WebMediaPlayerImpl::OnFrameHidden() { | 1443 void WebMediaPlayerImpl::OnFrameHidden() { |
1435 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1444 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1436 | 1445 |
1446 // Backgrounding a video requires a user gesture to resume playback. | |
1447 if (IsHidden()) | |
1448 video_locked_when_paused_when_hidden_ = true; | |
1449 | |
1437 if (watch_time_reporter_) | 1450 if (watch_time_reporter_) |
1438 watch_time_reporter_->OnHidden(); | 1451 watch_time_reporter_->OnHidden(); |
1439 | 1452 |
1440 // OnFrameHidden() can be called when frame is closed, then IsHidden() will | 1453 UpdateBackgroundVideoOptimizationState(); |
1441 // return false, so check explicitly. | |
1442 if (IsHidden()) { | |
1443 if (ShouldPauseVideoWhenHidden()) { | |
1444 PauseVideoIfNeeded(); | |
1445 return; | |
1446 } else { | |
1447 DisableVideoTrackIfNeeded(); | |
1448 } | |
1449 } | |
1450 | |
1451 UpdatePlayState(); | 1454 UpdatePlayState(); |
1452 | 1455 |
1453 // Schedule suspended playing media to be paused if the user doesn't come back | 1456 // Schedule suspended playing media to be paused if the user doesn't come back |
1454 // to it within some timeout period to avoid any autoplay surprises. | 1457 // to it within some timeout period to avoid any autoplay surprises. |
1455 ScheduleIdlePauseTimer(); | 1458 ScheduleIdlePauseTimer(); |
1456 } | 1459 } |
1457 | 1460 |
1458 void WebMediaPlayerImpl::OnFrameClosed() { | 1461 void WebMediaPlayerImpl::OnFrameClosed() { |
1459 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1462 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1460 UpdatePlayState(); | 1463 UpdatePlayState(); |
1461 } | 1464 } |
1462 | 1465 |
1463 void WebMediaPlayerImpl::OnFrameShown() { | 1466 void WebMediaPlayerImpl::OnFrameShown() { |
1464 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1467 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1465 background_pause_timer_.Stop(); | 1468 background_pause_timer_.Stop(); |
1466 | 1469 |
1470 // Foreground videos don't require user gesture to continue playback. | |
1471 video_locked_when_paused_when_hidden_ = false; | |
1472 | |
1467 if (watch_time_reporter_) | 1473 if (watch_time_reporter_) |
1468 watch_time_reporter_->OnShown(); | 1474 watch_time_reporter_->OnShown(); |
1469 | 1475 |
1470 // Only track the time to the first frame if playing or about to play because | 1476 // Only track the time to the first frame if playing or about to play because |
1471 // of being shown and only for videos we would optimize background playback | 1477 // of being shown and only for videos we would optimize background playback |
1472 // for. | 1478 // for. |
1473 if ((!paused_ && IsBackgroundOptimizationCandidate()) || | 1479 if ((!paused_ && IsBackgroundOptimizationCandidate()) || |
1474 paused_when_hidden_) { | 1480 paused_when_hidden_) { |
1475 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb = | 1481 VideoFrameCompositor::OnNewProcessedFrameCB new_processed_frame_cb = |
1476 BindToCurrentLoop(base::Bind( | 1482 BindToCurrentLoop(base::Bind( |
1477 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame, | 1483 &WebMediaPlayerImpl::ReportTimeFromForegroundToFirstFrame, |
1478 AsWeakPtr(), base::TimeTicks::Now())); | 1484 AsWeakPtr(), base::TimeTicks::Now())); |
1479 compositor_task_runner_->PostTask( | 1485 compositor_task_runner_->PostTask( |
1480 FROM_HERE, | 1486 FROM_HERE, |
1481 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback, | 1487 base::Bind(&VideoFrameCompositor::SetOnNewProcessedFrameCallback, |
1482 base::Unretained(compositor_), new_processed_frame_cb)); | 1488 base::Unretained(compositor_), new_processed_frame_cb)); |
1483 } | 1489 } |
1484 | 1490 |
1491 EnableVideoTrackIfNeeded(); | |
1492 | |
1485 if (paused_when_hidden_) { | 1493 if (paused_when_hidden_) { |
1486 paused_when_hidden_ = false; | 1494 paused_when_hidden_ = false; |
1487 OnPlay(); // Calls UpdatePlayState() so return afterwards. | 1495 OnPlay(); // Calls UpdatePlayState() so return afterwards. |
1488 return; | 1496 return; |
1489 } | 1497 } |
1490 | 1498 |
1491 EnableVideoTrackIfNeeded(); | |
1492 | |
1493 UpdatePlayState(); | 1499 UpdatePlayState(); |
1494 } | 1500 } |
1495 | 1501 |
1496 void WebMediaPlayerImpl::OnIdleTimeout() { | 1502 void WebMediaPlayerImpl::OnIdleTimeout() { |
1497 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1503 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1498 | 1504 |
1499 // If we are attempting preroll, clear the stale flag. | 1505 // If we are attempting preroll, clear the stale flag. |
1500 if (IsPrerollAttemptNeeded()) { | 1506 if (IsPrerollAttemptNeeded()) { |
1501 delegate_->ClearStaleFlag(delegate_id_); | 1507 delegate_->ClearStaleFlag(delegate_id_); |
1502 return; | 1508 return; |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1947 bool is_backgrounded) { | 1953 bool is_backgrounded) { |
1948 PlayState result; | 1954 PlayState result; |
1949 | 1955 |
1950 bool must_suspend = delegate_->IsFrameClosed(); | 1956 bool must_suspend = delegate_->IsFrameClosed(); |
1951 bool is_stale = delegate_->IsStale(delegate_id_); | 1957 bool is_stale = delegate_->IsStale(delegate_id_); |
1952 | 1958 |
1953 // This includes both data source (before pipeline startup) and pipeline | 1959 // This includes both data source (before pipeline startup) and pipeline |
1954 // errors. | 1960 // errors. |
1955 bool has_error = IsNetworkStateError(network_state_); | 1961 bool has_error = IsNetworkStateError(network_state_); |
1956 | 1962 |
1957 // After HaveMetadata, we know which tracks are present and the duration. | |
1958 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata; | |
1959 | |
1960 // After HaveFutureData, Blink will call play() if the state is not paused; | 1963 // After HaveFutureData, Blink will call play() if the state is not paused; |
1961 // prior to this point |paused_| is not accurate. | 1964 // prior to this point |paused_| is not accurate. |
1962 bool have_future_data = | 1965 bool have_future_data = |
1963 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; | 1966 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; |
1964 | 1967 |
1965 // Background suspend is not enabled for audio-only players unless paused, | 1968 // Background suspend is only enabled for paused players. |
1966 // though in the case of audio-only the session should be kept. | 1969 // In the case of players with audio the session should be kept. |
1967 // Videos are not suspended if the user resumed the playback via the remote | 1970 bool background_suspended = |
1968 // controls earlier and it's still playing. | |
1969 bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo(); | |
1970 bool can_play_backgrounded = is_backgrounded_video && !is_remote && | |
1971 hasAudio() && IsResumeBackgroundVideosEnabled(); | |
1972 bool is_background_playing = delegate_->IsBackgroundVideoPlaybackUnlocked(); | |
1973 bool background_suspended = can_auto_suspend && is_backgrounded_video && | |
1974 !(can_play_backgrounded && is_background_playing); | |
1975 bool background_pause_suspended = | |
1976 can_auto_suspend && is_backgrounded && paused_ && have_future_data; | 1971 can_auto_suspend && is_backgrounded && paused_ && have_future_data; |
1977 | 1972 |
1978 // Idle suspension is allowed prior to have future data since there exist | 1973 // Idle suspension is allowed prior to have future data since there exist |
1979 // mechanisms to exit the idle state when the player is capable of reaching | 1974 // mechanisms to exit the idle state when the player is capable of reaching |
1980 // the have future data state; see didLoadingProgress(). | 1975 // the have future data state; see didLoadingProgress(). |
1981 // | 1976 // |
1982 // TODO(sandersd): Make the delegate suspend idle players immediately when | 1977 // TODO(sandersd): Make the delegate suspend idle players immediately when |
1983 // hidden. | 1978 // hidden. |
1984 bool idle_suspended = | 1979 bool idle_suspended = |
1985 can_auto_suspend && is_stale && paused_ && !seeking_ && !overlay_enabled_; | 1980 can_auto_suspend && is_stale && paused_ && !seeking_ && !overlay_enabled_; |
1986 | 1981 |
1987 // If we're already suspended, see if we can wait for user interaction. Prior | 1982 // If we're already suspended, see if we can wait for user interaction. Prior |
1988 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale| | 1983 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale| |
1989 // will be cleared when we receive data which may take us to HaveFutureData. | 1984 // will be cleared when we receive data which may take us to HaveFutureData. |
1990 bool can_stay_suspended = | 1985 bool can_stay_suspended = |
1991 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_; | 1986 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_; |
1992 | 1987 |
1993 // Combined suspend state. | 1988 // Combined suspend state. |
1994 result.is_suspended = is_remote || must_suspend || idle_suspended || | 1989 result.is_suspended = is_remote || must_suspend || idle_suspended || |
1995 background_suspended || background_pause_suspended || | 1990 background_suspended || can_stay_suspended; |
1996 can_stay_suspended; | |
1997 | 1991 |
1998 // We do not treat |playback_rate_| == 0 as paused. For the media session, | 1992 // We do not treat |playback_rate_| == 0 as paused. For the media session, |
1999 // being paused implies displaying a play button, which is incorrect in this | 1993 // being paused implies displaying a play button, which is incorrect in this |
2000 // case. For memory usage reporting, we just use the same definition (but we | 1994 // case. For memory usage reporting, we just use the same definition (but we |
2001 // don't have to). | 1995 // don't have to). |
2002 // | 1996 // |
2003 // Similarly, we don't consider |ended_| to be paused. Blink will immediately | 1997 // Similarly, we don't consider |ended_| to be paused. Blink will immediately |
2004 // call pause() or seek(), so |ended_| should not affect the computation. | 1998 // call pause() or seek(), so |ended_| should not affect the computation. |
2005 // Despite that, |ended_| does result in a separate paused state, to simplfy | 1999 // Despite that, |ended_| does result in a separate paused state, to simplfy |
2006 // the contract for SetDelegateState(). | 2000 // the contract for SetDelegateState(). |
2007 // | 2001 // |
2008 // |has_session| is used to decide when to create a media session. Idle | 2002 // |has_session| is used to decide when to create a media session. Idle |
2009 // suspension does not destroy the media session, because we expect that the | 2003 // suspension does not destroy the media session, because we expect that the |
2010 // notification controls (and audio focus) remain. We also require: | 2004 // notification controls (and audio focus) remain. We also require: |
2011 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). | 2005 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). |
2012 // - |have_future_data|, since we need to know whether we are paused to | 2006 // - |have_future_data|, since we need to know whether we are paused to |
2013 // correctly configure the session. | 2007 // correctly configure the session. |
2014 // | 2008 // |
2015 // TODO(sandersd): If Blink told us the paused state sooner, we could create | 2009 // TODO(sandersd): If Blink told us the paused state sooner, we could create |
2016 // the media session sooner. | 2010 // the media session sooner. |
2017 bool can_play = !has_error && !is_remote && have_future_data; | 2011 bool can_play = !has_error && !is_remote && have_future_data; |
2018 bool has_session_playing = can_play && !must_suspend && !background_suspended; | 2012 bool has_session = |
2019 | 2013 can_play && !must_suspend && hasAudio() && |
2020 // |has_session_suspended| means the player is suspended from the media | 2014 (!hasVideo() || !is_backgrounded || !IsBackgroundedSuspendEnabled() || |
sandersd (OOO until July 31)
2017/02/23 00:38:31
This last condition isn't obvious, please pull it
whywhat
2017/02/23 02:50:27
Done. |have_metadata| is implied by |has_future_da
| |
2021 // element point of view but paused and can be resumed from the delegate point | 2015 IsResumeBackgroundVideosEnabled()); |
2022 // of view. Therefore it behaves like |paused_| for the delegate. | |
2023 bool has_session_suspended = can_play && !must_suspend && | |
2024 background_suspended && can_play_backgrounded; | |
2025 | |
2026 bool has_session = has_session_playing || has_session_suspended; | |
2027 | 2016 |
2028 if (!has_session) { | 2017 if (!has_session) { |
2029 result.delegate_state = DelegateState::GONE; | 2018 result.delegate_state = DelegateState::GONE; |
2030 result.is_idle = delegate_->IsIdle(delegate_id_); | 2019 result.is_idle = delegate_->IsIdle(delegate_id_); |
2031 } else if (paused_ || has_session_suspended) { | 2020 } else if (paused_) { |
2032 // TODO(sandersd): Is it possible to have a suspended session, be ended, | 2021 // TODO(sandersd): Is it possible to have a suspended session, be ended, |
2033 // and not be paused? If so we should be in a PLAYING state. | 2022 // and not be paused? If so we should be in a PLAYING state. |
2034 result.delegate_state = | 2023 result.delegate_state = |
2035 ended_ ? DelegateState::GONE : DelegateState::PAUSED; | 2024 ended_ ? DelegateState::GONE : DelegateState::PAUSED; |
2036 result.is_idle = !seeking_; | 2025 result.is_idle = !seeking_; |
2037 } else { | 2026 } else { |
2038 result.delegate_state = DelegateState::PLAYING; | 2027 result.delegate_state = DelegateState::PLAYING; |
2039 result.is_idle = false; | 2028 result.is_idle = false; |
2040 } | 2029 } |
2041 | 2030 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2099 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource", | 2088 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.DataSource", |
2100 data_source_memory_usage / 1024); | 2089 data_source_memory_usage / 1024); |
2101 } | 2090 } |
2102 if (demuxer_) { | 2091 if (demuxer_) { |
2103 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer", | 2092 UMA_HISTOGRAM_MEMORY_KB("Media.WebMediaPlayerImpl.Memory.Demuxer", |
2104 demuxer_memory_usage / 1024); | 2093 demuxer_memory_usage / 1024); |
2105 } | 2094 } |
2106 } | 2095 } |
2107 | 2096 |
2108 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { | 2097 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { |
2109 // Only schedule the pause timer if we're playing and are suspended. | 2098 // Only schedule the pause timer if we're not paused or paused but going to |
2110 if (paused_ || !pipeline_controller_.IsSuspended()) | 2099 // resume when foregrounded, and are suspended. |
2100 if ((paused_ && !paused_when_hidden_) || !pipeline_controller_.IsSuspended()) | |
2111 return; | 2101 return; |
2112 | 2102 |
2113 #if defined(OS_ANDROID) | 2103 #if defined(OS_ANDROID) |
2114 // Remote players will be suspended and locally paused. | 2104 // Remote players will be suspended and locally paused. |
2115 if (isRemote()) | 2105 if (isRemote()) |
2116 return; | 2106 return; |
2117 #endif | 2107 #endif |
2118 | 2108 |
2119 // Idle timeout chosen arbitrarily. | 2109 // Idle timeout chosen arbitrarily. |
2120 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), | 2110 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), |
(...skipping 27 matching lines...) Expand all Loading... | |
2148 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; | 2138 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; |
2149 } | 2139 } |
2150 | 2140 |
2151 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { | 2141 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { |
2152 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2142 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
2153 | 2143 |
2154 client_->activateViewportIntersectionMonitoring(activate); | 2144 client_->activateViewportIntersectionMonitoring(activate); |
2155 } | 2145 } |
2156 | 2146 |
2157 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { | 2147 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { |
2158 #if !defined(OS_ANDROID) | 2148 // If suspending background video, pause any video that's not remoted or |
2159 // On desktop, this behavior is behind the feature flag. | 2149 // not unlocked to play in the background. |
2160 if (!IsBackgroundVideoTrackOptimizationEnabled()) | 2150 if (IsBackgroundedSuspendEnabled()) { |
2161 return false; | 2151 if (!hasVideo()) |
2152 return false; | |
2153 | |
2154 #if defined(OS_ANDROID) | |
2155 if (isRemote()) | |
2156 return false; | |
2162 #endif | 2157 #endif |
2163 | 2158 |
2164 // Pause video-only players that match the criteria for being optimized. | 2159 return !hasAudio() || |
2165 return !hasAudio() && IsBackgroundOptimizationCandidate(); | 2160 (IsResumeBackgroundVideosEnabled() && |
2161 video_locked_when_paused_when_hidden_); | |
2162 } | |
2163 | |
2164 // Otherwise only pause if the optimization is on and it's a video-only | |
2165 // optimization candidate. | |
2166 return IsBackgroundVideoTrackOptimizationEnabled() && !hasAudio() && | |
2167 IsBackgroundOptimizationCandidate(); | |
2166 } | 2168 } |
2167 | 2169 |
2168 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { | 2170 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { |
2169 // This optimization is behind the flag on all platforms. | 2171 // This optimization is behind the flag on all platforms. |
2170 if (!IsBackgroundVideoTrackOptimizationEnabled()) | 2172 if (!IsBackgroundVideoTrackOptimizationEnabled()) |
2171 return false; | 2173 return false; |
2172 | 2174 |
2173 // Disable video track only for players with audio that match the criteria for | 2175 // Disable video track only for players with audio that match the criteria for |
2174 // being optimized. | 2176 // being optimized. |
2175 return hasAudio() && IsBackgroundOptimizationCandidate(); | 2177 return hasAudio() && IsBackgroundOptimizationCandidate(); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2286 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time; | 2288 base::TimeDelta time_to_first_frame = new_frame_time - foreground_time; |
2287 if (hasAudio()) { | 2289 if (hasAudio()) { |
2288 UMA_HISTOGRAM_TIMES( | 2290 UMA_HISTOGRAM_TIMES( |
2289 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", | 2291 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", |
2290 time_to_first_frame); | 2292 time_to_first_frame); |
2291 } else { | 2293 } else { |
2292 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", | 2294 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", |
2293 time_to_first_frame); | 2295 time_to_first_frame); |
2294 } | 2296 } |
2295 } | 2297 } |
2296 | |
2297 void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) { | 2298 void WebMediaPlayerImpl::SwitchRenderer(bool disable_pipeline_auto_suspend) { |
2298 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2299 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
2299 disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend; | 2300 disable_pipeline_auto_suspend_ = disable_pipeline_auto_suspend; |
2300 ScheduleRestart(); | 2301 ScheduleRestart(); |
2301 } | 2302 } |
2302 | 2303 |
2303 } // namespace media | 2304 } // namespace media |
OLD | NEW |