Chromium Code Reviews| 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(); |
| 1529 // The |paused_| state is not reliable until we |have_future_data|. | |
|
sandersd (OOO until July 31)
2016/06/10 18:27:12
Newline before.
DaleCurtis
2016/06/10 19:54:20
Done.
| |
| 1530 bool background_pause_suspended = | |
| 1531 is_backgrounded && have_future_data && paused_; | |
| 1521 | 1532 |
| 1522 // Idle suspend is enabled once there is future data. We don't want to idle | 1533 // 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 | 1534 // 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 | 1535 // 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 | 1536 // other events before actually calling play(), but at least we don't break |
| 1526 // Blink. | 1537 // Blink. |
| 1527 // | 1538 // |
| 1528 // TODO(sandersd): Make the delegate suspend idle players immediately when | 1539 // TODO(sandersd): Make the delegate suspend idle players immediately when |
| 1529 // hidden. | 1540 // hidden. |
| 1530 // TODO(sandersd): If Blink told us the paused state sooner, we could | 1541 // TODO(sandersd): If Blink told us the paused state sooner, we could |
| 1531 // idle suspend sooner. | 1542 // idle suspend sooner. |
| 1532 bool idle_suspended = is_idle_ && have_future_data; | 1543 bool idle_suspended = is_idle_ && have_future_data; |
| 1533 | 1544 |
| 1534 // Combined suspend state. | 1545 // Combined suspend state. |
| 1535 result.is_suspended = | 1546 result.is_suspended = is_remote || must_suspend_ || idle_suspended || |
| 1536 is_remote || must_suspend_ || idle_suspended || background_suspended; | 1547 background_suspended || background_pause_suspended; |
| 1548 | |
| 1549 // If we're already suspended and the target state is unsuspended, check to | |
| 1550 // see if we really must resume right now or can just wait for user action. | |
| 1551 if (is_suspended && !result.is_suspended && have_future_data && paused_ && | |
| 1552 !seeking_) { | |
|
sandersd (OOO until July 31)
2016/06/10 18:27:12
Doesn't actually need the |!result.is_suspended| c
DaleCurtis
2016/06/10 19:54:20
Done.
| |
| 1553 result.is_suspended = true; | |
| 1554 } | |
| 1537 | 1555 |
| 1538 // We do not treat |playback_rate_| == 0 as paused. For the media session, | 1556 // 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 | 1557 // 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 | 1558 // case. For memory usage reporting, we just use the same definition (but we |
| 1541 // don't have to). | 1559 // don't have to). |
| 1542 // | 1560 // |
| 1543 // Similarly, we don't consider |ended_| to be paused. Blink will immediately | 1561 // Similarly, we don't consider |ended_| to be paused. Blink will immediately |
| 1544 // call pause() or seek(), so |ended_| should not affect the computation. | 1562 // call pause() or seek(), so |ended_| should not affect the computation. |
| 1545 // Despite that, |ended_| does result in a separate paused state, to simplfy | 1563 // Despite that, |ended_| does result in a separate paused state, to simplfy |
| 1546 // the contract for SetDelegateState(). | 1564 // the contract for SetDelegateState(). |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1564 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; | 1582 result.delegate_state = DelegateState::PAUSED_BUT_NOT_IDLE; |
| 1565 } else if (ended_) { | 1583 } else if (ended_) { |
| 1566 result.delegate_state = DelegateState::ENDED; | 1584 result.delegate_state = DelegateState::ENDED; |
| 1567 } else { | 1585 } else { |
| 1568 result.delegate_state = DelegateState::PAUSED; | 1586 result.delegate_state = DelegateState::PAUSED; |
| 1569 } | 1587 } |
| 1570 } else { | 1588 } else { |
| 1571 result.delegate_state = DelegateState::PLAYING; | 1589 result.delegate_state = DelegateState::PLAYING; |
| 1572 } | 1590 } |
| 1573 | 1591 |
| 1574 // It's not critical if some cases where memory usage can change are missed, | 1592 // It's not critical if some cases where memory usage can change are missed, |
| 1575 // since media memory changes are usually gradual. | 1593 // since media memory changes are usually gradual. |
| 1576 result.is_memory_reporting_enabled = | 1594 result.is_memory_reporting_enabled = |
| 1577 can_play && !result.is_suspended && !paused_; | 1595 can_play && !result.is_suspended && !paused_; |
| 1578 | 1596 |
| 1579 return result; | 1597 return result; |
| 1580 } | 1598 } |
| 1581 | 1599 |
| 1582 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1600 void WebMediaPlayerImpl::ReportMemoryUsage() { |
| 1583 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1601 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1584 | 1602 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1612 DVLOG(2) << "Memory Usage -- Audio: " << stats.audio_memory_usage | 1630 DVLOG(2) << "Memory Usage -- Audio: " << stats.audio_memory_usage |
| 1613 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1631 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
| 1614 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1632 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
| 1615 << ", Demuxer: " << demuxer_memory_usage; | 1633 << ", Demuxer: " << demuxer_memory_usage; |
| 1616 | 1634 |
| 1617 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1635 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
| 1618 last_reported_memory_usage_ = current_memory_usage; | 1636 last_reported_memory_usage_ = current_memory_usage; |
| 1619 adjust_allocated_memory_cb_.Run(delta); | 1637 adjust_allocated_memory_cb_.Run(delta); |
| 1620 } | 1638 } |
| 1621 | 1639 |
| 1640 void WebMediaPlayerImpl::ScheduleIdlePauseTimer() { | |
| 1641 // Only schedule the pause timer if we're playing and are suspended. We use | |
| 1642 // delegate state as a proxy for suspended here since the suspension may be in | |
| 1643 // flight at the time of this call. | |
| 1644 if (paused_ || delegate_state_ != DelegateState::GONE) | |
| 1645 return; | |
| 1646 | |
| 1647 #if defined(OS_ANDROID) | |
| 1648 // Remote players will be suspended and locally paused. | |
| 1649 if (isRemote()) | |
| 1650 return; | |
| 1651 #endif | |
| 1652 | |
| 1653 // Idle timeout chosen arbitrarily. | |
| 1654 background_pause_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), | |
| 1655 this, &WebMediaPlayerImpl::OnPause); | |
| 1656 } | |
| 1657 | |
| 1622 } // namespace media | 1658 } // namespace media |
| OLD | NEW |