| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |