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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 client_(client), | 212 client_(client), |
213 encrypted_client_(encrypted_client), | 213 encrypted_client_(encrypted_client), |
214 delegate_(delegate), | 214 delegate_(delegate), |
215 delegate_id_(0), | 215 delegate_id_(0), |
216 defer_load_cb_(params->defer_load_cb()), | 216 defer_load_cb_(params->defer_load_cb()), |
217 context_3d_cb_(params->context_3d_cb()), | 217 context_3d_cb_(params->context_3d_cb()), |
218 adjust_allocated_memory_cb_(params->adjust_allocated_memory_cb()), | 218 adjust_allocated_memory_cb_(params->adjust_allocated_memory_cb()), |
219 last_reported_memory_usage_(0), | 219 last_reported_memory_usage_(0), |
220 supports_save_(true), | 220 supports_save_(true), |
221 chunk_demuxer_(NULL), | 221 chunk_demuxer_(NULL), |
| 222 tick_clock_(new base::DefaultTickClock()), |
| 223 buffered_data_source_host_( |
| 224 base::Bind(&WebMediaPlayerImpl::OnProgress, AsWeakPtr()), |
| 225 tick_clock_.get()), |
222 url_index_(url_index), | 226 url_index_(url_index), |
223 // Threaded compositing isn't enabled universally yet. | 227 // Threaded compositing isn't enabled universally yet. |
224 compositor_task_runner_(params->compositor_task_runner() | 228 compositor_task_runner_(params->compositor_task_runner() |
225 ? params->compositor_task_runner() | 229 ? params->compositor_task_runner() |
226 : base::ThreadTaskRunnerHandle::Get()), | 230 : base::ThreadTaskRunnerHandle::Get()), |
227 compositor_(new VideoFrameCompositor(compositor_task_runner_)), | 231 compositor_(new VideoFrameCompositor(compositor_task_runner_)), |
228 #if defined(OS_ANDROID) // WMPI_CAST | 232 #if defined(OS_ANDROID) // WMPI_CAST |
229 cast_impl_(this, client_, params->context_3d_cb()), | 233 cast_impl_(this, client_, params->context_3d_cb()), |
230 #endif | 234 #endif |
231 volume_(1.0), | 235 volume_(1.0), |
(...skipping 13 matching lines...) Expand all Loading... |
245 enable_instant_source_buffer_gc_( | 249 enable_instant_source_buffer_gc_( |
246 params->enable_instant_source_buffer_gc()), | 250 params->enable_instant_source_buffer_gc()), |
247 embedded_media_experience_enabled_( | 251 embedded_media_experience_enabled_( |
248 params->embedded_media_experience_enabled()) { | 252 params->embedded_media_experience_enabled()) { |
249 DVLOG(1) << __func__; | 253 DVLOG(1) << __func__; |
250 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 254 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
251 DCHECK(renderer_factory_selector_); | 255 DCHECK(renderer_factory_selector_); |
252 DCHECK(client_); | 256 DCHECK(client_); |
253 DCHECK(delegate_); | 257 DCHECK(delegate_); |
254 | 258 |
255 tick_clock_.reset(new base::DefaultTickClock()); | |
256 | |
257 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 259 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
258 switches::kForceVideoOverlays); | 260 switches::kForceVideoOverlays); |
259 | 261 |
260 enable_fullscreen_video_overlays_ = | 262 enable_fullscreen_video_overlays_ = |
261 base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo); | 263 base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo); |
262 | 264 |
263 delegate_id_ = delegate_->AddObserver(this); | 265 delegate_id_ = delegate_->AddObserver(this); |
264 delegate_->SetIdle(delegate_id_, true); | 266 delegate_->SetIdle(delegate_id_, true); |
265 | 267 |
266 media_log_->AddEvent( | 268 media_log_->AddEvent( |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 tick_clock_->NowTicks() - preroll_attempt_start_time_; | 850 tick_clock_->NowTicks() - preroll_attempt_start_time_; |
849 return preroll_attempt_duration < kPrerollAttemptTimeout; | 851 return preroll_attempt_duration < kPrerollAttemptTimeout; |
850 } | 852 } |
851 | 853 |
852 bool WebMediaPlayerImpl::DidLoadingProgress() { | 854 bool WebMediaPlayerImpl::DidLoadingProgress() { |
853 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 855 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
854 | 856 |
855 // Note: Separate variables used to ensure both methods are called every time. | 857 // Note: Separate variables used to ensure both methods are called every time. |
856 const bool pipeline_progress = pipeline_controller_.DidLoadingProgress(); | 858 const bool pipeline_progress = pipeline_controller_.DidLoadingProgress(); |
857 const bool data_progress = buffered_data_source_host_.DidLoadingProgress(); | 859 const bool data_progress = buffered_data_source_host_.DidLoadingProgress(); |
858 const bool did_loading_progress = pipeline_progress || data_progress; | 860 return pipeline_progress || data_progress; |
859 | |
860 if (did_loading_progress && | |
861 highest_ready_state_ < ReadyState::kReadyStateHaveFutureData) { | |
862 // Reset the preroll attempt clock. | |
863 preroll_attempt_pending_ = true; | |
864 preroll_attempt_start_time_ = base::TimeTicks(); | |
865 | |
866 // Clear any 'stale' flag and give the pipeline a chance to resume. If we | |
867 // are already resumed, this will cause |preroll_attempt_start_time_| to be | |
868 // set. | |
869 // TODO(sandersd): Should this be on the same stack? It might be surprising | |
870 // that didLoadingProgress() can synchronously change state. | |
871 delegate_->ClearStaleFlag(delegate_id_); | |
872 UpdatePlayState(); | |
873 } | |
874 | |
875 return did_loading_progress; | |
876 } | 861 } |
877 | 862 |
878 void WebMediaPlayerImpl::Paint(blink::WebCanvas* canvas, | 863 void WebMediaPlayerImpl::Paint(blink::WebCanvas* canvas, |
879 const blink::WebRect& rect, | 864 const blink::WebRect& rect, |
880 cc::PaintFlags& flags) { | 865 cc::PaintFlags& flags) { |
881 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 866 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
882 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); | 867 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); |
883 | 868 |
884 // We can't copy from protected frames. | 869 // We can't copy from protected frames. |
885 if (cdm_) | 870 if (cdm_) |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 client_->SetWebLayer(video_weblayer_.get()); | 1274 client_->SetWebLayer(video_weblayer_.get()); |
1290 } | 1275 } |
1291 | 1276 |
1292 if (observer_) | 1277 if (observer_) |
1293 observer_->OnMetadataChanged(pipeline_metadata_); | 1278 observer_->OnMetadataChanged(pipeline_metadata_); |
1294 | 1279 |
1295 CreateWatchTimeReporter(); | 1280 CreateWatchTimeReporter(); |
1296 UpdatePlayState(); | 1281 UpdatePlayState(); |
1297 } | 1282 } |
1298 | 1283 |
| 1284 void WebMediaPlayerImpl::OnProgress() { |
| 1285 DVLOG(1) << __func__; |
| 1286 if (highest_ready_state_ < ReadyState::kReadyStateHaveFutureData) { |
| 1287 // Reset the preroll attempt clock. |
| 1288 preroll_attempt_pending_ = true; |
| 1289 preroll_attempt_start_time_ = base::TimeTicks(); |
| 1290 |
| 1291 // Clear any 'stale' flag and give the pipeline a chance to resume. If we |
| 1292 // are already resumed, this will cause |preroll_attempt_start_time_| to |
| 1293 // be set. |
| 1294 delegate_->ClearStaleFlag(delegate_id_); |
| 1295 UpdatePlayState(); |
| 1296 } else if (ready_state_ == ReadyState::kReadyStateHaveFutureData && |
| 1297 CanPlayThrough()) { |
| 1298 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); |
| 1299 } |
| 1300 } |
| 1301 |
| 1302 bool WebMediaPlayerImpl::CanPlayThrough() { |
| 1303 if (!base::FeatureList::IsEnabled(kSpecCompliantCanPlayThrough)) |
| 1304 return true; |
| 1305 if (chunk_demuxer_) |
| 1306 return true; |
| 1307 if (data_source_ && data_source_->assume_fully_buffered()) |
| 1308 return true; |
| 1309 // If we're not currently downloading, we have as much buffer as |
| 1310 // we're ever going to get, which means we say we can play through. |
| 1311 if (network_state_ == WebMediaPlayer::kNetworkStateIdle) |
| 1312 return true; |
| 1313 return buffered_data_source_host_.CanPlayThrough( |
| 1314 base::TimeDelta::FromSecondsD(CurrentTime()), |
| 1315 base::TimeDelta::FromSecondsD(Duration()), |
| 1316 playback_rate_ == 0.0 ? 1.0 : playback_rate_); |
| 1317 } |
| 1318 |
1299 void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { | 1319 void WebMediaPlayerImpl::OnBufferingStateChange(BufferingState state) { |
1300 DVLOG(1) << __func__ << "(" << state << ")"; | 1320 DVLOG(1) << __func__ << "(" << state << ")"; |
1301 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1321 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1302 | 1322 |
1303 // Ignore buffering state changes until we've completed all outstanding | 1323 // Ignore buffering state changes until we've completed all outstanding |
1304 // operations. | 1324 // operations. |
1305 if (!pipeline_controller_.IsStable()) | 1325 if (!pipeline_controller_.IsStable()) |
1306 return; | 1326 return; |
1307 | 1327 |
1308 media_log_->AddEvent(media_log_->CreateBufferingStateChangedEvent( | 1328 media_log_->AddEvent(media_log_->CreateBufferingStateChangedEvent( |
1309 "pipeline_buffering_state", state)); | 1329 "pipeline_buffering_state", state)); |
1310 | 1330 |
1311 if (state == BUFFERING_HAVE_ENOUGH) { | 1331 if (state == BUFFERING_HAVE_ENOUGH) { |
1312 if (highest_ready_state_ < WebMediaPlayer::kReadyStateHaveEnoughData) { | 1332 if (highest_ready_state_ < WebMediaPlayer::kReadyStateHaveEnoughData) { |
1313 // Record a zero value for underflow histogram so that the histogram | 1333 // Record a zero value for underflow histogram so that the histogram |
1314 // includes playbacks which never encounter an underflow event. | 1334 // includes playbacks which never encounter an underflow event. |
1315 RecordUnderflowDuration(base::TimeDelta()); | 1335 RecordUnderflowDuration(base::TimeDelta()); |
1316 } | 1336 } |
1317 | 1337 |
1318 // TODO(chcunningham): Monitor playback position vs buffered. Potentially | 1338 SetReadyState(CanPlayThrough() ? WebMediaPlayer::kReadyStateHaveEnoughData |
1319 // transition to HAVE_FUTURE_DATA here if not enough is buffered. | 1339 : WebMediaPlayer::kReadyStateHaveFutureData); |
1320 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); | |
1321 | 1340 |
1322 // Let the DataSource know we have enough data. It may use this information | 1341 // Let the DataSource know we have enough data. It may use this information |
1323 // to release unused network connections. | 1342 // to release unused network connections. |
1324 if (data_source_) | 1343 if (data_source_) |
1325 data_source_->OnBufferingHaveEnough(false); | 1344 data_source_->OnBufferingHaveEnough(false); |
1326 | 1345 |
1327 // Blink expects a timeChanged() in response to a seek(). | 1346 // Blink expects a timeChanged() in response to a seek(). |
1328 if (should_notify_time_changed_) { | 1347 if (should_notify_time_changed_) { |
1329 should_notify_time_changed_ = false; | 1348 should_notify_time_changed_ = false; |
1330 client_->TimeChanged(); | 1349 client_->TimeChanged(); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1643 // least this makes sure that the error handling code is in sync. | 1662 // least this makes sure that the error handling code is in sync. |
1644 UpdatePlayState(); | 1663 UpdatePlayState(); |
1645 | 1664 |
1646 return; | 1665 return; |
1647 } | 1666 } |
1648 | 1667 |
1649 StartPipeline(); | 1668 StartPipeline(); |
1650 } | 1669 } |
1651 | 1670 |
1652 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { | 1671 void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { |
1653 DVLOG(1) << __func__; | 1672 DVLOG(1) << __func__ << "(" << is_downloading << ")"; |
1654 if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading) | 1673 if (!is_downloading && network_state_ == WebMediaPlayer::kNetworkStateLoading) |
1655 SetNetworkState(WebMediaPlayer::kNetworkStateIdle); | 1674 SetNetworkState(WebMediaPlayer::kNetworkStateIdle); |
1656 else if (is_downloading && | 1675 else if (is_downloading && |
1657 network_state_ == WebMediaPlayer::kNetworkStateIdle) | 1676 network_state_ == WebMediaPlayer::kNetworkStateIdle) |
1658 SetNetworkState(WebMediaPlayer::kNetworkStateLoading); | 1677 SetNetworkState(WebMediaPlayer::kNetworkStateLoading); |
| 1678 if (ready_state_ == ReadyState::kReadyStateHaveFutureData && !is_downloading) |
| 1679 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); |
1659 media_log_->AddEvent( | 1680 media_log_->AddEvent( |
1660 media_log_->CreateBooleanEvent(MediaLogEvent::NETWORK_ACTIVITY_SET, | 1681 media_log_->CreateBooleanEvent(MediaLogEvent::NETWORK_ACTIVITY_SET, |
1661 "is_downloading_data", is_downloading)); | 1682 "is_downloading_data", is_downloading)); |
1662 } | 1683 } |
1663 | 1684 |
1664 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { | 1685 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { |
1665 overlay_surface_id_ = surface_id; | 1686 overlay_surface_id_ = surface_id; |
1666 if (!set_surface_cb_.is_null()) { | 1687 if (!set_surface_cb_.is_null()) { |
1667 // If restart is required, the callback is one-shot only. | 1688 // If restart is required, the callback is one-shot only. |
1668 if (decoder_requires_restart_for_overlay_) | 1689 if (decoder_requires_restart_for_overlay_) |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.MSE", height); | 2415 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.MSE", height); |
2395 | 2416 |
2396 if (is_encrypted_) | 2417 if (is_encrypted_) |
2397 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.EME", height); | 2418 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.EME", height); |
2398 | 2419 |
2399 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.All", height); | 2420 UMA_HISTOGRAM_VIDEO_HEIGHT("Media.VideoHeight.Initial.All", height); |
2400 } | 2421 } |
2401 | 2422 |
2402 #undef UMA_HISTOGRAM_VIDEO_HEIGHT | 2423 #undef UMA_HISTOGRAM_VIDEO_HEIGHT |
2403 | 2424 |
| 2425 void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { |
| 2426 tick_clock_.reset(tick_clock); |
| 2427 buffered_data_source_host_.SetTickClockForTest(tick_clock); |
| 2428 } |
| 2429 |
2404 } // namespace media | 2430 } // namespace media |
OLD | NEW |