Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(989)

Side by Side Diff: media/blink/webmediaplayer_impl.cc

Issue 2796193002: fix canplaythrough (Closed)
Patch Set: kSpecCompliantCanPlayThrough Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/blink/webmediaplayer_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « media/blink/webmediaplayer_impl.h ('k') | media/blink/webmediaplayer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698