| 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 1095 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 opaque_ = opaque; | 1106 opaque_ = opaque; |
| 1107 // Modify content opaqueness of cc::Layer directly so that | 1107 // Modify content opaqueness of cc::Layer directly so that |
| 1108 // SetContentsOpaqueIsFixed is ignored. | 1108 // SetContentsOpaqueIsFixed is ignored. |
| 1109 if (video_weblayer_) | 1109 if (video_weblayer_) |
| 1110 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1110 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
| 1111 } | 1111 } |
| 1112 | 1112 |
| 1113 void WebMediaPlayerImpl::OnHidden() { | 1113 void WebMediaPlayerImpl::OnHidden() { |
| 1114 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1114 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1115 UpdatePlayState(); | 1115 UpdatePlayState(); |
| 1116 |
| 1117 // Schedule suspended playing media to be paused if the user doesn't come back |
| 1118 // to it within some timeout period to avoid any autoplay surprises. |
| 1119 ScheduleIdlePauseTimer(); |
| 1116 } | 1120 } |
| 1117 | 1121 |
| 1118 void WebMediaPlayerImpl::OnShown() { | 1122 void WebMediaPlayerImpl::OnShown() { |
| 1119 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1123 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1120 must_suspend_ = false; | 1124 must_suspend_ = false; |
| 1125 background_pause_timer_.Stop(); |
| 1121 UpdatePlayState(); | 1126 UpdatePlayState(); |
| 1122 } | 1127 } |
| 1123 | 1128 |
| 1124 void WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { | 1129 void WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { |
| 1125 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1130 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1126 | 1131 |
| 1127 if (must_suspend) { | 1132 if (must_suspend) { |
| 1128 must_suspend_ = true; | 1133 must_suspend_ = true; |
| 1129 } else { | 1134 } else { |
| 1130 // TODO(sandersd): Remove this when idleness is separate from play state. | 1135 // TODO(sandersd): Remove this when idleness is separate from play state. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 event.Wait(); | 1405 event.Wait(); |
| 1401 return video_frame; | 1406 return video_frame; |
| 1402 } | 1407 } |
| 1403 | 1408 |
| 1404 void WebMediaPlayerImpl::UpdatePlayState() { | 1409 void WebMediaPlayerImpl::UpdatePlayState() { |
| 1405 #if defined(OS_ANDROID) // WMPI_CAST | 1410 #if defined(OS_ANDROID) // WMPI_CAST |
| 1406 bool is_remote = isRemote(); | 1411 bool is_remote = isRemote(); |
| 1407 #else | 1412 #else |
| 1408 bool is_remote = false; | 1413 bool is_remote = false; |
| 1409 #endif | 1414 #endif |
| 1415 bool is_suspended = pipeline_controller_.IsSuspended(); |
| 1410 bool is_backgrounded = | 1416 bool is_backgrounded = |
| 1411 IsBackgroundedSuspendEnabled() && delegate_ && delegate_->IsHidden(); | 1417 IsBackgroundedSuspendEnabled() && delegate_ && delegate_->IsHidden(); |
| 1412 PlayState state = | 1418 PlayState state = UpdatePlayState_ComputePlayState(is_remote, is_suspended, |
| 1413 UpdatePlayState_ComputePlayState(is_remote, is_backgrounded); | 1419 is_backgrounded); |
| 1414 SetDelegateState(state.delegate_state); | 1420 SetDelegateState(state.delegate_state); |
| 1415 SetMemoryReportingState(state.is_memory_reporting_enabled); | 1421 SetMemoryReportingState(state.is_memory_reporting_enabled); |
| 1416 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); | 1422 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); |
| 1417 } | 1423 } |
| 1418 | 1424 |
| 1419 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state) { | 1425 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state) { |
| 1420 if (!delegate_ || delegate_state_ == new_state) | 1426 if (!delegate_ || delegate_state_ == new_state) |
| 1421 return; | 1427 return; |
| 1422 | 1428 |
| 1423 delegate_state_ = new_state; | 1429 delegate_state_ = new_state; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1492 | 1498 |
| 1493 if (is_suspended) { | 1499 if (is_suspended) { |
| 1494 pipeline_controller_.Suspend(); | 1500 pipeline_controller_.Suspend(); |
| 1495 } else { | 1501 } else { |
| 1496 pipeline_controller_.Resume(); | 1502 pipeline_controller_.Resume(); |
| 1497 } | 1503 } |
| 1498 } | 1504 } |
| 1499 | 1505 |
| 1500 WebMediaPlayerImpl::PlayState | 1506 WebMediaPlayerImpl::PlayState |
| 1501 WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote, | 1507 WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote, |
| 1508 bool is_suspended, |
| 1502 bool is_backgrounded) { | 1509 bool is_backgrounded) { |
| 1503 PlayState result; | 1510 PlayState result; |
| 1504 | 1511 |
| 1505 // This includes both data source (before pipeline startup) and pipeline | 1512 // This includes both data source (before pipeline startup) and pipeline |
| 1506 // errors. | 1513 // errors. |
| 1507 bool has_error = IsNetworkStateError(network_state_); | 1514 bool has_error = IsNetworkStateError(network_state_); |
| 1508 | 1515 |
| 1509 // After HaveMetadata, we know which tracks are present and the duration. | 1516 // After HaveMetadata, we know which tracks are present and the duration. |
| 1510 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata; | 1517 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata; |
| 1511 | 1518 |
| 1512 // After HaveFutureData, Blink will call play() if the state is not paused. | 1519 // After HaveFutureData, Blink will call play() if the state is not paused. |
| 1513 bool have_future_data = | 1520 bool have_future_data = |
| 1514 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; | 1521 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; |
| 1515 | 1522 |
| 1516 // Background suspend is not enabled for audio-only players. | 1523 // Background suspend is not enabled for audio-only players unless paused, |
| 1524 // though in the case of audio-only the session should be kept. |
| 1517 bool background_suspended = is_backgrounded && have_metadata && hasVideo(); | 1525 bool background_suspended = is_backgrounded && have_metadata && hasVideo(); |
| 1518 | 1526 |
| 1527 // The |paused_| state is not reliable until we |have_future_data|. |
| 1528 bool background_pause_suspended = |
| 1529 is_backgrounded && have_future_data && paused_; |
| 1530 |
| 1519 // Idle suspend is enabled once there is future data. We don't want to idle | 1531 // Idle suspend is enabled once there is future data. We don't want to idle |
| 1520 // suspend before that because play() may never be triggered to leave the idle | 1532 // suspend before that because play() may never be triggered to leave the idle |
| 1521 // state. There could be other theoretical problems if the page is waiting for | 1533 // state. There could be other theoretical problems if the page is waiting for |
| 1522 // other events before actually calling play(), but at least we don't break | 1534 // other events before actually calling play(), but at least we don't break |
| 1523 // Blink. | 1535 // Blink. |
| 1524 // | 1536 // |
| 1525 // TODO(sandersd): Make the delegate suspend idle players immediately when | 1537 // TODO(sandersd): Make the delegate suspend idle players immediately when |
| 1526 // hidden. | 1538 // hidden. |
| 1527 // TODO(sandersd): If Blink told us the paused state sooner, we could | 1539 // TODO(sandersd): If Blink told us the paused state sooner, we could |
| 1528 // idle suspend sooner. | 1540 // idle suspend sooner. |
| 1529 bool idle_suspended = is_idle_ && have_future_data; | 1541 bool idle_suspended = is_idle_ && have_future_data; |
| 1530 | 1542 |
| 1531 // Combined suspend state. | 1543 // Combined suspend state. |
| 1532 result.is_suspended = | 1544 result.is_suspended = |
| 1533 is_remote || must_suspend_ || idle_suspended || background_suspended; | 1545 is_remote || must_suspend_ || idle_suspended || background_suspended || |
| 1546 background_pause_suspended || |
| 1547 // If we're already suspended, see if we can wait for user interaction. |
| 1548 (is_suspended && have_future_data && paused_ && !seeking_); |
| 1534 | 1549 |
| 1535 // We do not treat |playback_rate_| == 0 as paused. For the media session, | 1550 // We do not treat |playback_rate_| == 0 as paused. For the media session, |
| 1536 // being paused implies displaying a play button, which is incorrect in this | 1551 // being paused implies displaying a play button, which is incorrect in this |
| 1537 // case. For memory usage reporting, we just use the same definition (but we | 1552 // case. For memory usage reporting, we just use the same definition (but we |
| 1538 // don't have to). | 1553 // don't have to). |
| 1539 // | 1554 // |
| 1540 // Similarly, we don't consider |ended_| to be paused. Blink will immediately | 1555 // Similarly, we don't consider |ended_| to be paused. Blink will immediately |
| 1541 // call pause() or seek(), so |ended_| should not affect the computation. | 1556 // call pause() or seek(), so |ended_| should not affect the computation. |
| 1542 // Despite that, |ended_| does result in a separate paused state, to simplfy | 1557 // Despite that, |ended_| does result in a separate paused state, to simplfy |
| 1543 // the contract for SetDelegateState(). | 1558 // the contract for SetDelegateState(). |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1561 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; | 1576 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; |
| 1562 } else if (ended_) { | 1577 } else if (ended_) { |
| 1563 result.delegate_state = DelegateState::ENDED; | 1578 result.delegate_state = DelegateState::ENDED; |
| 1564 } else { | 1579 } else { |
| 1565 result.delegate_state = DelegateState::PAUSED; | 1580 result.delegate_state = DelegateState::PAUSED; |
| 1566 } | 1581 } |
| 1567 } else { | 1582 } else { |
| 1568 result.delegate_state = DelegateState::PLAYING; | 1583 result.delegate_state = DelegateState::PLAYING; |
| 1569 } | 1584 } |
| 1570 | 1585 |
| 1571 // It's not critical if some cases where memory usage can change are missed, | 1586 // It's not critical if some cases where memory usage can change are missed, |
| 1572 // since media memory changes are usually gradual. | 1587 // since media memory changes are usually gradual. |
| 1573 result.is_memory_reporting_enabled = | 1588 result.is_memory_reporting_enabled = |
| 1574 can_play && !result.is_suspended && !paused_; | 1589 can_play && !result.is_suspended && !paused_; |
| 1575 | 1590 |
| 1576 return result; | 1591 return result; |
| 1577 } | 1592 } |
| 1578 | 1593 |
| 1579 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1594 void WebMediaPlayerImpl::ReportMemoryUsage() { |
| 1580 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1595 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1581 | 1596 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1609 DVLOG(2) << "Memory Usage -- Audio: " << stats.audio_memory_usage | 1624 DVLOG(2) << "Memory Usage -- Audio: " << stats.audio_memory_usage |
| 1610 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1625 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
| 1611 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1626 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
| 1612 << ", Demuxer: " << demuxer_memory_usage; | 1627 << ", Demuxer: " << demuxer_memory_usage; |
| 1613 | 1628 |
| 1614 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1629 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
| 1615 last_reported_memory_usage_ = current_memory_usage; | 1630 last_reported_memory_usage_ = current_memory_usage; |
| 1616 adjust_allocated_memory_cb_.Run(delta); | 1631 adjust_allocated_memory_cb_.Run(delta); |
| 1617 } | 1632 } |
| 1618 | 1633 |
| 1634 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { |
| 1635 // Only schedule the pause timer if we're playing and are suspended. We use |
| 1636 // delegate state as a proxy for suspended here since the suspension may be in |
| 1637 // flight at the time of this call. |
| 1638 if (paused_ || delegate_state_ != DelegateState::GONE) |
| 1639 return; |
| 1640 |
| 1641 #if defined(OS_ANDROID) |
| 1642 // Remote players will be suspended and locally paused. |
| 1643 if (isRemote()) |
| 1644 return; |
| 1645 #endif |
| 1646 |
| 1647 // Idle timeout chosen arbitrarily. |
| 1648 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), |
| 1649 this, &WebMediaPlayerImpl::OnPause); |
| 1650 } |
| 1651 |
| 1619 } // namespace media | 1652 } // namespace media |
| OLD | NEW |