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 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 if (video_weblayer_) | 1398 if (video_weblayer_) |
1399 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1399 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
1400 } | 1400 } |
1401 | 1401 |
1402 void WebMediaPlayerImpl::OnFrameHidden() { | 1402 void WebMediaPlayerImpl::OnFrameHidden() { |
1403 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1403 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1404 | 1404 |
1405 if (watch_time_reporter_) | 1405 if (watch_time_reporter_) |
1406 watch_time_reporter_->OnHidden(); | 1406 watch_time_reporter_->OnHidden(); |
1407 | 1407 |
1408 // OnFrameHidden() can be called when frame is closed, then IsHidden() will | 1408 if (IsBackground()) { |
1409 // return false, so check explicitly. | 1409 if (ShouldPauseVideoWhenBackground()) { |
1410 if (IsHidden()) { | |
1411 if (ShouldPauseVideoWhenHidden()) { | |
1412 PauseVideoIfNeeded(); | 1410 PauseVideoIfNeeded(); |
1413 return; | 1411 return; |
1414 } else { | 1412 } else { |
1415 DisableVideoTrackIfNeeded(); | 1413 DisableVideoTrackIfNeeded(); |
1416 } | 1414 } |
1417 } | 1415 } |
1418 | 1416 |
1419 UpdatePlayState(); | 1417 UpdatePlayState(); |
1420 | 1418 |
1421 // Schedule suspended playing media to be paused if the user doesn't come back | 1419 // Schedule suspended playing media to be paused if the user doesn't come back |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 | 1795 |
1798 #if defined(OS_ANDROID) // WMPI_CAST | 1796 #if defined(OS_ANDROID) // WMPI_CAST |
1799 bool is_remote = isRemote(); | 1797 bool is_remote = isRemote(); |
1800 bool is_streaming = false; | 1798 bool is_streaming = false; |
1801 #else | 1799 #else |
1802 bool is_remote = false; | 1800 bool is_remote = false; |
1803 bool is_streaming = IsStreaming(); | 1801 bool is_streaming = IsStreaming(); |
1804 #endif | 1802 #endif |
1805 | 1803 |
1806 bool is_suspended = pipeline_controller_.IsSuspended(); | 1804 bool is_suspended = pipeline_controller_.IsSuspended(); |
1807 bool is_backgrounded = IsBackgroundedSuspendEnabled() && IsHidden(); | 1805 bool is_backgrounded = IsBackgroundedSuspendEnabled() && IsBackground(); |
1808 PlayState state = UpdatePlayState_ComputePlayState( | 1806 PlayState state = UpdatePlayState_ComputePlayState( |
1809 is_remote, is_streaming, is_suspended, is_backgrounded); | 1807 is_remote, is_streaming, is_suspended, is_backgrounded); |
1810 SetDelegateState(state.delegate_state, state.is_idle); | 1808 SetDelegateState(state.delegate_state, state.is_idle); |
1811 SetMemoryReportingState(state.is_memory_reporting_enabled); | 1809 SetMemoryReportingState(state.is_memory_reporting_enabled); |
1812 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); | 1810 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); |
1813 } | 1811 } |
1814 | 1812 |
1815 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state, | 1813 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state, |
1816 bool is_idle) { | 1814 bool is_idle) { |
1817 DCHECK(delegate_); | 1815 DCHECK(delegate_); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 hasAudio(), hasVideo(), !!chunk_demuxer_, is_encrypted_, media_log_, | 2094 hasAudio(), hasVideo(), !!chunk_demuxer_, is_encrypted_, media_log_, |
2097 pipeline_metadata_.natural_size, | 2095 pipeline_metadata_.natural_size, |
2098 base::Bind(&GetCurrentTimeInternal, this))); | 2096 base::Bind(&GetCurrentTimeInternal, this))); |
2099 watch_time_reporter_->OnVolumeChange(volume_); | 2097 watch_time_reporter_->OnVolumeChange(volume_); |
2100 if (delegate_->IsFrameHidden()) | 2098 if (delegate_->IsFrameHidden()) |
2101 watch_time_reporter_->OnHidden(); | 2099 watch_time_reporter_->OnHidden(); |
2102 else | 2100 else |
2103 watch_time_reporter_->OnShown(); | 2101 watch_time_reporter_->OnShown(); |
2104 } | 2102 } |
2105 | 2103 |
2106 bool WebMediaPlayerImpl::IsHidden() const { | 2104 bool WebMediaPlayerImpl::IsBackground() const { |
2107 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2105 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
2108 | 2106 |
| 2107 // Nothing related to the media being in the background should matter if the |
| 2108 // frame is closed. However, the delegate might call OnFrameHidden() when |
| 2109 // closed so specifically exclude this case. |
2109 return delegate_->IsFrameHidden() && !delegate_->IsFrameClosed(); | 2110 return delegate_->IsFrameHidden() && !delegate_->IsFrameClosed(); |
2110 } | 2111 } |
2111 | 2112 |
2112 bool WebMediaPlayerImpl::IsStreaming() const { | 2113 bool WebMediaPlayerImpl::IsStreaming() const { |
2113 return data_source_ && data_source_->IsStreaming(); | 2114 return data_source_ && data_source_->IsStreaming(); |
2114 } | 2115 } |
2115 | 2116 |
2116 bool WebMediaPlayerImpl::DoesOverlaySupportMetadata() const { | 2117 bool WebMediaPlayerImpl::DoesOverlaySupportMetadata() const { |
2117 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; | 2118 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; |
2118 } | 2119 } |
2119 | 2120 |
2120 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { | 2121 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { |
2121 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2122 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
2122 | 2123 |
2123 client_->activateViewportIntersectionMonitoring(activate); | 2124 client_->activateViewportIntersectionMonitoring(activate); |
2124 } | 2125 } |
2125 | 2126 |
2126 bool WebMediaPlayerImpl::ShouldPauseVideoWhenHidden() const { | 2127 bool WebMediaPlayerImpl::ShouldPauseVideoWhenBackground() const { |
2127 #if !defined(OS_ANDROID) | 2128 #if !defined(OS_ANDROID) |
2128 // On desktop, this behavior is behind the feature flag. | 2129 // On desktop, this behavior is behind the feature flag. |
2129 if (!IsBackgroundVideoTrackOptimizationEnabled()) | 2130 if (!IsBackgroundVideoTrackOptimizationEnabled()) |
2130 return false; | 2131 return false; |
2131 #endif | 2132 #endif |
2132 | 2133 |
2133 // Pause video-only players that match the criteria for being optimized. | 2134 // Pause video-only players that match the criteria for being optimized. |
2134 return !hasAudio() && IsBackgroundOptimizationCandidate(); | 2135 return !hasAudio() && IsBackgroundOptimizationCandidate(); |
2135 } | 2136 } |
2136 | 2137 |
2137 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { | 2138 bool WebMediaPlayerImpl::ShouldDisableVideoWhenBackground() const { |
2138 // This optimization is behind the flag on all platforms. | 2139 // This optimization is behind the flag on all platforms. |
2139 if (!IsBackgroundVideoTrackOptimizationEnabled()) | 2140 if (!IsBackgroundVideoTrackOptimizationEnabled()) |
2140 return false; | 2141 return false; |
2141 | 2142 |
2142 // Disable video track only for players with audio that match the criteria for | 2143 // Disable video track only for players with audio that match the criteria for |
2143 // being optimized. | 2144 // being optimized. |
2144 return hasAudio() && IsBackgroundOptimizationCandidate(); | 2145 return hasAudio() && IsBackgroundOptimizationCandidate(); |
2145 } | 2146 } |
2146 | 2147 |
2147 bool WebMediaPlayerImpl::IsBackgroundOptimizationCandidate() const { | 2148 bool WebMediaPlayerImpl::IsBackgroundOptimizationCandidate() const { |
(...skipping 19 matching lines...) Expand all Loading... |
2167 if (duration < max_keyframe_distance_to_disable_background_video_) | 2168 if (duration < max_keyframe_distance_to_disable_background_video_) |
2168 return true; | 2169 return true; |
2169 | 2170 |
2170 // Otherwise, only optimize videos with shorter average keyframe distance. | 2171 // Otherwise, only optimize videos with shorter average keyframe distance. |
2171 PipelineStatistics stats = GetPipelineStatistics(); | 2172 PipelineStatistics stats = GetPipelineStatistics(); |
2172 return stats.video_keyframe_distance_average < | 2173 return stats.video_keyframe_distance_average < |
2173 max_keyframe_distance_to_disable_background_video_; | 2174 max_keyframe_distance_to_disable_background_video_; |
2174 } | 2175 } |
2175 | 2176 |
2176 void WebMediaPlayerImpl::UpdateBackgroundVideoOptimizationState() { | 2177 void WebMediaPlayerImpl::UpdateBackgroundVideoOptimizationState() { |
2177 if (IsHidden()) { | 2178 if (IsBackground()) { |
2178 if (ShouldPauseVideoWhenHidden()) | 2179 if (ShouldPauseVideoWhenBackground()) |
2179 PauseVideoIfNeeded(); | 2180 PauseVideoIfNeeded(); |
2180 else | 2181 else |
2181 DisableVideoTrackIfNeeded(); | 2182 DisableVideoTrackIfNeeded(); |
2182 } else { | 2183 } else { |
2183 EnableVideoTrackIfNeeded(); | 2184 EnableVideoTrackIfNeeded(); |
2184 } | 2185 } |
2185 } | 2186 } |
2186 | 2187 |
2187 void WebMediaPlayerImpl::PauseVideoIfNeeded() { | 2188 void WebMediaPlayerImpl::PauseVideoIfNeeded() { |
2188 DCHECK(IsHidden()); | 2189 DCHECK(IsBackground()); |
2189 | 2190 |
2190 // Don't pause video while the pipeline is stopped, resuming or seeking. | 2191 // Don't pause video while the pipeline is stopped, resuming or seeking. |
2191 // Also if the video is paused already. | 2192 // Also if the video is paused already. |
2192 if (!pipeline_.IsRunning() || is_pipeline_resuming_ || seeking_ || paused_) | 2193 if (!pipeline_.IsRunning() || is_pipeline_resuming_ || seeking_ || paused_) |
2193 return; | 2194 return; |
2194 | 2195 |
2195 // OnPause() will set |paused_when_hidden_| to false and call | 2196 // OnPause() will set |paused_when_hidden_| to false and call |
2196 // UpdatePlayState(), so set the flag to true after and then return. | 2197 // UpdatePlayState(), so set the flag to true after and then return. |
2197 OnPause(); | 2198 OnPause(); |
2198 paused_when_hidden_ = true; | 2199 paused_when_hidden_ = true; |
2199 } | 2200 } |
2200 | 2201 |
2201 void WebMediaPlayerImpl::EnableVideoTrackIfNeeded() { | 2202 void WebMediaPlayerImpl::EnableVideoTrackIfNeeded() { |
2202 // Don't change video track while the pipeline is stopped, resuming or | 2203 // Don't change video track while the pipeline is stopped, resuming or |
2203 // seeking. | 2204 // seeking. |
2204 if (!pipeline_.IsRunning() || is_pipeline_resuming_ || seeking_) | 2205 if (!pipeline_.IsRunning() || is_pipeline_resuming_ || seeking_) |
2205 return; | 2206 return; |
2206 | 2207 |
2207 if (video_track_disabled_) { | 2208 if (video_track_disabled_) { |
2208 video_track_disabled_ = false; | 2209 video_track_disabled_ = false; |
2209 if (client_->hasSelectedVideoTrack()) { | 2210 if (client_->hasSelectedVideoTrack()) { |
2210 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); | 2211 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); |
2211 selectedVideoTrackChanged(&trackId); | 2212 selectedVideoTrackChanged(&trackId); |
2212 } | 2213 } |
2213 } | 2214 } |
2214 } | 2215 } |
2215 | 2216 |
2216 void WebMediaPlayerImpl::DisableVideoTrackIfNeeded() { | 2217 void WebMediaPlayerImpl::DisableVideoTrackIfNeeded() { |
2217 DCHECK(IsHidden()); | 2218 DCHECK(IsBackground()); |
2218 | 2219 |
2219 // Don't change video track while the pipeline is resuming or seeking. | 2220 // Don't change video track while the pipeline is resuming or seeking. |
2220 if (is_pipeline_resuming_ || seeking_) | 2221 if (is_pipeline_resuming_ || seeking_) |
2221 return; | 2222 return; |
2222 | 2223 |
2223 if (!video_track_disabled_ && ShouldDisableVideoWhenHidden()) { | 2224 if (!video_track_disabled_ && ShouldDisableVideoWhenBackground()) { |
2224 video_track_disabled_ = true; | 2225 video_track_disabled_ = true; |
2225 selectedVideoTrackChanged(nullptr); | 2226 selectedVideoTrackChanged(nullptr); |
2226 } | 2227 } |
2227 } | 2228 } |
2228 | 2229 |
2229 void WebMediaPlayerImpl::SetPipelineStatisticsForTest( | 2230 void WebMediaPlayerImpl::SetPipelineStatisticsForTest( |
2230 const PipelineStatistics& stats) { | 2231 const PipelineStatistics& stats) { |
2231 pipeline_statistics_for_test_ = base::make_optional(stats); | 2232 pipeline_statistics_for_test_ = base::make_optional(stats); |
2232 } | 2233 } |
2233 | 2234 |
(...skipping 23 matching lines...) Expand all Loading... |
2257 UMA_HISTOGRAM_TIMES( | 2258 UMA_HISTOGRAM_TIMES( |
2258 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", | 2259 "Media.Video.TimeFromForegroundToFirstFrame.DisableTrack", |
2259 time_to_first_frame); | 2260 time_to_first_frame); |
2260 } else { | 2261 } else { |
2261 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", | 2262 UMA_HISTOGRAM_TIMES("Media.Video.TimeFromForegroundToFirstFrame.Paused", |
2262 time_to_first_frame); | 2263 time_to_first_frame); |
2263 } | 2264 } |
2264 } | 2265 } |
2265 | 2266 |
2266 } // namespace media | 2267 } // namespace media |
OLD | NEW |