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