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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 57 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
58 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" | 58 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
59 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" | 59 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" |
60 #include "third_party/WebKit/public/web/WebView.h" | 60 #include "third_party/WebKit/public/web/WebView.h" |
61 | 61 |
62 using blink::WebCanvas; | 62 using blink::WebCanvas; |
63 using blink::WebMediaPlayer; | 63 using blink::WebMediaPlayer; |
64 using blink::WebRect; | 64 using blink::WebRect; |
65 using blink::WebSize; | 65 using blink::WebSize; |
66 using blink::WebString; | 66 using blink::WebString; |
67 using gpu::gles2::GLES2Interface; | |
68 | |
69 namespace media { | |
67 | 70 |
68 namespace { | 71 namespace { |
69 | 72 |
70 // Limits the range of playback rate. | 73 // Limits the range of playback rate. |
71 // | 74 // |
72 // TODO(kylep): Revisit these. | 75 // TODO(kylep): Revisit these. |
73 // | 76 // |
74 // Vista has substantially lower performance than XP or Windows7. If you speed | 77 // Vista has substantially lower performance than XP or Windows7. If you speed |
75 // up a video too much, it can't keep up, and rendering stops updating except on | 78 // up a video too much, it can't keep up, and rendering stops updating except on |
76 // the time bar. For really high speeds, audio becomes a bottleneck and we just | 79 // the time bar. For really high speeds, audio becomes a bottleneck and we just |
77 // use up the data we have, which may not achieve the speed requested, but will | 80 // use up the data we have, which may not achieve the speed requested, but will |
78 // not crash the tab. | 81 // not crash the tab. |
79 // | 82 // |
80 // A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems | 83 // A very slow speed, ie 0.00000001x, causes the machine to lock up. (It seems |
81 // like a busy loop). It gets unresponsive, although its not completely dead. | 84 // like a busy loop). It gets unresponsive, although its not completely dead. |
82 // | 85 // |
83 // Also our timers are not very accurate (especially for ogg), which becomes | 86 // Also our timers are not very accurate (especially for ogg), which becomes |
84 // evident at low speeds and on Vista. Since other speeds are risky and outside | 87 // evident at low speeds and on Vista. Since other speeds are risky and outside |
85 // the norms, we think 1/16x to 16x is a safe and useful range for now. | 88 // the norms, we think 1/16x to 16x is a safe and useful range for now. |
86 const double kMinRate = 0.0625; | 89 const double kMinRate = 0.0625; |
87 const double kMaxRate = 16.0; | 90 const double kMaxRate = 16.0; |
88 | 91 |
89 void SetSinkIdOnMediaThread( | 92 void SetSinkIdOnMediaThread(scoped_refptr<WebAudioSourceProviderImpl> sink, |
90 scoped_refptr<media::WebAudioSourceProviderImpl> sink, | 93 const std::string& device_id, |
91 const std::string& device_id, | 94 const url::Origin& security_origin, |
92 const url::Origin& security_origin, | 95 const SwitchOutputDeviceCB& callback) { |
93 const media::SwitchOutputDeviceCB& callback) { | |
94 if (sink->GetOutputDevice()) { | 96 if (sink->GetOutputDevice()) { |
95 sink->GetOutputDevice()->SwitchOutputDevice(device_id, security_origin, | 97 sink->GetOutputDevice()->SwitchOutputDevice(device_id, security_origin, |
96 callback); | 98 callback); |
97 } else { | 99 } else { |
98 callback.Run(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL); | 100 callback.Run(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL); |
99 } | 101 } |
100 } | 102 } |
101 | 103 |
102 } // namespace | 104 } // namespace |
103 | 105 |
104 namespace media { | |
105 | |
106 class BufferedDataSourceHostImpl; | 106 class BufferedDataSourceHostImpl; |
107 | 107 |
108 #define STATIC_ASSERT_MATCHING_ENUM(name, name2) \ | 108 #define STATIC_ASSERT_MATCHING_ENUM(name, name2) \ |
109 static_assert(static_cast<int>(WebMediaPlayer::CORSMode##name) == \ | 109 static_assert(static_cast<int>(WebMediaPlayer::CORSMode##name) == \ |
110 static_cast<int>(UrlData::name2), \ | 110 static_cast<int>(UrlData::name2), \ |
111 "mismatching enum values: " #name) | 111 "mismatching enum values: " #name) |
112 STATIC_ASSERT_MATCHING_ENUM(Unspecified, CORS_UNSPECIFIED); | 112 STATIC_ASSERT_MATCHING_ENUM(Unspecified, CORS_UNSPECIFIED); |
113 STATIC_ASSERT_MATCHING_ENUM(Anonymous, CORS_ANONYMOUS); | 113 STATIC_ASSERT_MATCHING_ENUM(Anonymous, CORS_ANONYMOUS); |
114 STATIC_ASSERT_MATCHING_ENUM(UseCredentials, CORS_USE_CREDENTIALS); | 114 STATIC_ASSERT_MATCHING_ENUM(UseCredentials, CORS_USE_CREDENTIALS); |
115 #undef STATIC_ASSERT_MATCHING_ENUM | 115 #undef STATIC_ASSERT_MATCHING_ENUM |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 compositor_task_runner_, | 175 compositor_task_runner_, |
176 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), | 176 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnNaturalSizeChanged), |
177 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), | 177 BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnOpacityChanged))), |
178 encrypted_media_support_(cdm_factory, | 178 encrypted_media_support_(cdm_factory, |
179 encrypted_client, | 179 encrypted_client, |
180 params.media_permission(), | 180 params.media_permission(), |
181 base::Bind(&WebMediaPlayerImpl::SetCdm, | 181 base::Bind(&WebMediaPlayerImpl::SetCdm, |
182 AsWeakPtr(), | 182 AsWeakPtr(), |
183 base::Bind(&IgnoreCdmAttached))), | 183 base::Bind(&IgnoreCdmAttached))), |
184 is_cdm_attached_(false), | 184 is_cdm_attached_(false), |
185 #if defined(OS_ANDROID) // WMPI_CAST | |
186 cast_impl_(this, client_, params.context_3d_cb()), | |
187 #endif | |
185 renderer_factory_(std::move(renderer_factory)) { | 188 renderer_factory_(std::move(renderer_factory)) { |
186 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 189 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
187 | 190 |
188 if (delegate) | 191 if (delegate) |
189 delegate->AddObserver(this); | 192 delegate->AddObserver(this); |
190 | 193 |
191 media_log_->AddEvent( | 194 media_log_->AddEvent( |
192 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 195 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
193 | 196 |
194 if (params.initial_cdm()) { | 197 if (params.initial_cdm()) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 data_source_.reset(new BufferedDataSource( | 297 data_source_.reset(new BufferedDataSource( |
295 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 298 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
296 main_task_runner_, frame_, media_log_.get(), | 299 main_task_runner_, frame_, media_log_.get(), |
297 &buffered_data_source_host_, | 300 &buffered_data_source_host_, |
298 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 301 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
299 } | 302 } |
300 data_source_->SetPreload(preload_); | 303 data_source_->SetPreload(preload_); |
301 data_source_->SetBufferingStrategy(buffering_strategy_); | 304 data_source_->SetBufferingStrategy(buffering_strategy_); |
302 data_source_->Initialize( | 305 data_source_->Initialize( |
303 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); | 306 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); |
307 | |
308 #if defined(OS_ANDROID) // WMPI_CAST | |
309 cast_impl_.Initialize(url, frame_); | |
310 #endif | |
304 } | 311 } |
305 | 312 |
306 void WebMediaPlayerImpl::play() { | 313 void WebMediaPlayerImpl::play() { |
307 DVLOG(1) << __FUNCTION__; | 314 DVLOG(1) << __FUNCTION__; |
308 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 315 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
309 | 316 |
317 #if defined(OS_ANDROID) // WMPI_CAST | |
318 if (cast_impl_.isRemote()) { | |
319 cast_impl_.play(); | |
320 return; | |
321 } | |
322 #endif | |
323 | |
310 paused_ = false; | 324 paused_ = false; |
325 | |
311 pipeline_.SetPlaybackRate(playback_rate_); | 326 pipeline_.SetPlaybackRate(playback_rate_); |
312 if (data_source_) | 327 if (data_source_) |
313 data_source_->MediaIsPlaying(); | 328 data_source_->MediaIsPlaying(); |
314 | 329 |
315 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); | 330 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); |
316 | 331 |
317 if (delegate_ && playback_rate_ > 0) | 332 if (delegate_ && playback_rate_ > 0) |
318 NotifyPlaybackStarted(); | 333 NotifyPlaybackStarted(); |
319 } | 334 } |
320 | 335 |
321 void WebMediaPlayerImpl::pause() { | 336 void WebMediaPlayerImpl::pause() { |
322 DVLOG(1) << __FUNCTION__; | 337 DVLOG(1) << __FUNCTION__; |
323 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 338 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
324 | 339 |
325 const bool was_already_paused = paused_ || playback_rate_ == 0; | 340 const bool was_already_paused = paused_ || playback_rate_ == 0; |
326 paused_ = true; | 341 paused_ = true; |
342 | |
343 #if defined(OS_ANDROID) // WMPI_CAST | |
344 if (cast_impl_.isRemote()) { | |
345 cast_impl_.pause(); | |
346 return; | |
347 } | |
348 #endif | |
349 | |
327 pipeline_.SetPlaybackRate(0.0); | 350 pipeline_.SetPlaybackRate(0.0); |
328 UpdatePausedTime(); | 351 UpdatePausedTime(); |
329 | 352 |
330 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); | 353 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); |
331 | 354 |
332 if (!was_already_paused && delegate_) | 355 if (!was_already_paused && delegate_) |
333 NotifyPlaybackPaused(); | 356 NotifyPlaybackPaused(); |
334 } | 357 } |
335 | 358 |
336 bool WebMediaPlayerImpl::supportsSave() const { | 359 bool WebMediaPlayerImpl::supportsSave() const { |
337 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 360 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
338 return supports_save_; | 361 return supports_save_; |
339 } | 362 } |
340 | 363 |
341 void WebMediaPlayerImpl::seek(double seconds) { | 364 void WebMediaPlayerImpl::seek(double seconds) { |
342 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; | 365 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; |
343 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 366 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
344 | 367 |
345 ended_ = false; | 368 ended_ = false; |
346 | 369 |
370 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); | |
371 | |
372 #if defined(OS_ANDROID) // WMPI_CAST | |
373 if (cast_impl_.isRemote()) { | |
374 cast_impl_.seek(new_seek_time); | |
375 return; | |
376 } | |
377 #endif | |
378 | |
347 ReadyState old_state = ready_state_; | 379 ReadyState old_state = ready_state_; |
348 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) | 380 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) |
349 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 381 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
350 | 382 |
351 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); | |
352 | |
353 if (seeking_ || suspended_) { | 383 if (seeking_ || suspended_) { |
354 // Once resuming, it's too late to change the resume time and so the | 384 // Once resuming, it's too late to change the resume time and so the |
355 // implementation is a little different. | 385 // implementation is a little different. |
356 bool is_suspended = suspended_ && !resuming_; | 386 bool is_suspended = suspended_ && !resuming_; |
357 | 387 |
358 // If we are currently seeking or resuming to |new_seek_time|, skip the | 388 // If we are currently seeking or resuming to |new_seek_time|, skip the |
359 // seek (except for MSE, which always seeks). | 389 // seek (except for MSE, which always seeks). |
360 if (!is_suspended && new_seek_time == seek_time_) { | 390 if (!is_suspended && new_seek_time == seek_time_) { |
361 if (chunk_demuxer_) { | 391 if (chunk_demuxer_) { |
362 // Don't suppress any redundant in-progress MSE seek. There could have | 392 // Don't suppress any redundant in-progress MSE seek. There could have |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 return; | 446 return; |
417 } | 447 } |
418 } | 448 } |
419 | 449 |
420 seeking_ = true; | 450 seeking_ = true; |
421 seek_time_ = new_seek_time; | 451 seek_time_ = new_seek_time; |
422 | 452 |
423 if (chunk_demuxer_) | 453 if (chunk_demuxer_) |
424 chunk_demuxer_->StartWaitingForSeek(seek_time_); | 454 chunk_demuxer_->StartWaitingForSeek(seek_time_); |
425 | 455 |
426 // Kick off the asynchronous seek! | |
427 pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1( | 456 pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1( |
428 &WebMediaPlayerImpl::OnPipelineSeeked, true)); | 457 &WebMediaPlayerImpl::OnPipelineSeeked, true)); |
429 } | 458 } |
430 | 459 |
431 void WebMediaPlayerImpl::setRate(double rate) { | 460 void WebMediaPlayerImpl::setRate(double rate) { |
432 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; | 461 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; |
433 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 462 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
434 | 463 |
435 // TODO(kylep): Remove when support for negatives is added. Also, modify the | 464 // TODO(kylep): Remove when support for negatives is added. Also, modify the |
436 // following checks so rewind uses reasonable values also. | 465 // following checks so rewind uses reasonable values also. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
533 | 562 |
534 blink::WebSize WebMediaPlayerImpl::naturalSize() const { | 563 blink::WebSize WebMediaPlayerImpl::naturalSize() const { |
535 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 564 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
536 | 565 |
537 return blink::WebSize(pipeline_metadata_.natural_size); | 566 return blink::WebSize(pipeline_metadata_.natural_size); |
538 } | 567 } |
539 | 568 |
540 bool WebMediaPlayerImpl::paused() const { | 569 bool WebMediaPlayerImpl::paused() const { |
541 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 570 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
542 | 571 |
572 #if defined(OS_ANDROID) // WMPI_CAST | |
573 if (cast_impl_.isRemote()) | |
574 return cast_impl_.paused(); | |
575 #endif | |
543 return pipeline_.GetPlaybackRate() == 0.0f; | 576 return pipeline_.GetPlaybackRate() == 0.0f; |
544 } | 577 } |
545 | 578 |
546 bool WebMediaPlayerImpl::seeking() const { | 579 bool WebMediaPlayerImpl::seeking() const { |
547 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 580 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
548 | 581 |
549 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 582 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
550 return false; | 583 return false; |
551 | 584 |
552 return seeking_; | 585 return seeking_; |
(...skipping 27 matching lines...) Expand all Loading... | |
580 return duration(); | 613 return duration(); |
581 | 614 |
582 // We know the current seek time better than pipeline: pipeline may processing | 615 // We know the current seek time better than pipeline: pipeline may processing |
583 // an earlier seek before a pending seek has been started, or it might not yet | 616 // an earlier seek before a pending seek has been started, or it might not yet |
584 // have the current seek time returnable via GetMediaTime(). | 617 // have the current seek time returnable via GetMediaTime(). |
585 if (seeking()) { | 618 if (seeking()) { |
586 return pending_seek_ ? pending_seek_time_.InSecondsF() | 619 return pending_seek_ ? pending_seek_time_.InSecondsF() |
587 : seek_time_.InSecondsF(); | 620 : seek_time_.InSecondsF(); |
588 } | 621 } |
589 | 622 |
590 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); | 623 #if defined(OS_ANDROID) // WMPI_CAST |
624 if (cast_impl_.isRemote()) { | |
625 return cast_impl_.currentTime(); | |
626 } | |
627 #endif | |
628 | |
629 if (paused_) { | |
630 return paused_time_.InSecondsF(); | |
631 } | |
632 | |
633 return pipeline_.GetMediaTime().InSecondsF(); | |
591 } | 634 } |
592 | 635 |
593 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { | 636 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { |
594 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 637 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
595 return network_state_; | 638 return network_state_; |
596 } | 639 } |
597 | 640 |
598 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { | 641 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { |
599 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 642 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
600 return ready_state_; | 643 return ready_state_; |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
907 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; | 950 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; |
908 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 951 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
909 | 952 |
910 if (status != PIPELINE_OK) { | 953 if (status != PIPELINE_OK) { |
911 OnPipelineError(status); | 954 OnPipelineError(status); |
912 return; | 955 return; |
913 } | 956 } |
914 | 957 |
915 suspending_ = false; | 958 suspending_ = false; |
916 | 959 |
960 #if defined(OS_ANDROID) | |
961 if (cast_impl_.isRemote()) { | |
962 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); | |
963 if (frame) { | |
964 compositor_->PaintFrameUsingOldRenderingPath(frame); | |
965 } | |
966 } | |
967 #endif | |
968 | |
917 if (pending_resume_) { | 969 if (pending_resume_) { |
918 pending_resume_ = false; | 970 pending_resume_ = false; |
919 Resume(); | 971 Resume(); |
920 return; | 972 return; |
921 } | 973 } |
922 } | 974 } |
923 | 975 |
924 void WebMediaPlayerImpl::OnPipelineEnded() { | 976 void WebMediaPlayerImpl::OnPipelineEnded() { |
925 DVLOG(1) << __FUNCTION__; | 977 DVLOG(1) << __FUNCTION__; |
926 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 978 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1047 switches::kEnableMediaSuspend)) { | 1099 switches::kEnableMediaSuspend)) { |
1048 return; | 1100 return; |
1049 } | 1101 } |
1050 #endif // !defined(OS_ANDROID) | 1102 #endif // !defined(OS_ANDROID) |
1051 | 1103 |
1052 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1104 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
1053 switches::kDisableMediaSuspend)) { | 1105 switches::kDisableMediaSuspend)) { |
1054 return; | 1106 return; |
1055 } | 1107 } |
1056 | 1108 |
1109 #if defined(OS_ANDROID) | |
1110 // If we're remote, the pipeline should already be suspended. | |
1111 if (cast_impl_.isRemote()) | |
1112 return; | |
1113 #endif | |
1114 | |
1115 ScheduleSuspend(); | |
1116 } | |
1117 | |
1118 void WebMediaPlayerImpl::ScheduleSuspend() { | |
1057 if (!pipeline_.IsRunning() || !hasVideo()) | 1119 if (!pipeline_.IsRunning() || !hasVideo()) |
1058 return; | 1120 return; |
1059 | 1121 |
1060 if (resuming_ || seeking_) { | 1122 if (resuming_ || seeking_) { |
1061 pending_suspend_ = true; | 1123 pending_suspend_ = true; |
1062 return; | 1124 return; |
1063 } | 1125 } |
1064 | 1126 |
1065 if (pending_resume_) { | 1127 if (pending_resume_) { |
1066 pending_resume_ = false; | 1128 pending_resume_ = false; |
(...skipping 21 matching lines...) Expand all Loading... | |
1088 switches::kEnableMediaSuspend)) { | 1150 switches::kEnableMediaSuspend)) { |
1089 return; | 1151 return; |
1090 } | 1152 } |
1091 #endif // !defined(OS_ANDROID) | 1153 #endif // !defined(OS_ANDROID) |
1092 | 1154 |
1093 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1155 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
1094 switches::kDisableMediaSuspend)) { | 1156 switches::kDisableMediaSuspend)) { |
1095 return; | 1157 return; |
1096 } | 1158 } |
1097 | 1159 |
1160 #if defined(OS_ANDROID) | |
1161 // If we're remote, the pipeline should stay suspended. | |
1162 if (cast_impl_.isRemote()) | |
1163 return; | |
1164 #endif | |
1165 | |
1166 ScheduleResume(); | |
1167 } | |
1168 | |
1169 void WebMediaPlayerImpl::ScheduleResume() { | |
1098 if (!pipeline_.IsRunning()) | 1170 if (!pipeline_.IsRunning()) |
1099 return; | 1171 return; |
1100 | 1172 |
1101 if (suspending_) { | 1173 if (suspending_) { |
1102 pending_resume_ = true; | 1174 pending_resume_ = true; |
1103 return; | 1175 return; |
1104 } | 1176 } |
1105 | 1177 |
1106 if (pending_suspend_) { | 1178 if (pending_suspend_) { |
1107 pending_suspend_ = false; | 1179 pending_suspend_ = false; |
1108 return; | 1180 return; |
1109 } | 1181 } |
1110 | 1182 |
1111 // We may not be suspended if we were not yet subscribed or the pipeline was | 1183 // Might already be resuming iff we came back from remote playback recently. |
1112 // not yet started when OnHidden() fired. | 1184 if (suspended_ && !resuming_) |
1113 if (!suspended_) | 1185 Resume(); |
1114 return; | |
1115 | |
1116 Resume(); | |
1117 } | 1186 } |
1118 | 1187 |
1119 void WebMediaPlayerImpl::Resume() { | 1188 void WebMediaPlayerImpl::Resume() { |
1120 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1189 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1121 CHECK(suspended_); | 1190 CHECK(suspended_); |
1122 CHECK(!resuming_); | 1191 CHECK(!resuming_); |
1123 | 1192 |
1124 // If there was a time change pending when we suspended (which can happen when | 1193 // If there was a time change pending when we suspended (which can happen when |
1125 // we suspend immediately after a seek), surface it after resuming. | 1194 // we suspend immediately after a seek), surface it after resuming. |
1126 bool time_changed = pending_time_change_; | 1195 bool time_changed = pending_time_change_; |
(...skipping 15 matching lines...) Expand all Loading... | |
1142 | 1211 |
1143 if (chunk_demuxer_) | 1212 if (chunk_demuxer_) |
1144 chunk_demuxer_->StartWaitingForSeek(seek_time_); | 1213 chunk_demuxer_->StartWaitingForSeek(seek_time_); |
1145 | 1214 |
1146 resuming_ = true; | 1215 resuming_ = true; |
1147 pipeline_.Resume(CreateRenderer(), seek_time_, | 1216 pipeline_.Resume(CreateRenderer(), seek_time_, |
1148 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, | 1217 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, |
1149 time_changed)); | 1218 time_changed)); |
1150 } | 1219 } |
1151 | 1220 |
1221 #if defined(OS_ANDROID) // WMPI_CAST | |
1222 void WebMediaPlayerImpl::set_media_player_manager( | |
1223 RendererMediaPlayerManagerInterface* media_player_manager) { | |
1224 cast_impl_.set_media_player_manager(media_player_manager); | |
1225 } | |
1226 | |
1227 void WebMediaPlayerImpl::requestRemotePlayback() { | |
1228 cast_impl_.requestRemotePlayback(); | |
1229 } | |
1230 | |
1231 void WebMediaPlayerImpl::requestRemotePlaybackControl() { | |
1232 cast_impl_.requestRemotePlaybackControl(); | |
1233 } | |
1234 | |
1235 void WebMediaPlayerImpl::OnRemotePlaybackEnded() { | |
1236 DVLOG(1) << __FUNCTION__; | |
1237 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
1238 | |
1239 ended_ = true; | |
1240 client_->timeChanged(); | |
1241 } | |
1242 | |
1243 void WebMediaPlayerImpl::OnDisconnectedFromRemoteDevice(double t) { | |
1244 paused_time_ = base::TimeDelta::FromSecondsD(t); | |
1245 | |
1246 DCHECK(!pending_seek_); | |
sandersd (OOO until July 31)
2016/01/13 23:05:43
Looks like you're correct that the currentTime() r
hubbe
2016/01/14 00:25:53
Done.
| |
1247 pending_seek_ = true; | |
1248 pending_seek_time_ = paused_time_; | |
1249 | |
1250 ScheduleResume(); | |
1251 | |
1252 if (paused_time_ == pipeline_.GetMediaDuration()) { | |
1253 ended_ = true; | |
1254 } | |
1255 // We already told the delegate we're paused when remoting started. | |
1256 client_->playbackStateChanged(); | |
1257 client_->disconnectedFromRemoteDevice(); | |
1258 } | |
1259 | |
1260 void WebMediaPlayerImpl::SuspendForRemote() { | |
1261 if (suspended_ && !suspending_) { | |
1262 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); | |
1263 if (frame) { | |
1264 compositor_->PaintFrameUsingOldRenderingPath(frame); | |
1265 } | |
1266 } | |
1267 ScheduleSuspend(); | |
1268 } | |
1269 | |
1270 gfx::Size WebMediaPlayerImpl::GetCanvasSize() const { | |
1271 if (!video_weblayer_) | |
1272 return gfx::Size(0, 0); | |
1273 | |
1274 gfx::Size video_size_css_px = video_weblayer_->bounds(); | |
1275 float device_scale_factor = frame_->view()->deviceScaleFactor(); | |
1276 // canvas_size will be the size in device pixels when pageScaleFactor == 1 | |
1277 gfx::Size canvas_size( | |
1278 static_cast<int>(video_size_css_px.width() * device_scale_factor), | |
1279 static_cast<int>(video_size_css_px.height() * device_scale_factor)); | |
1280 return canvas_size; | |
1281 } | |
1282 #endif // defined(OS_ANDROID) // WMPI_CAST | |
1283 | |
1152 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { | 1284 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { |
1153 DVLOG(1) << __FUNCTION__; | 1285 DVLOG(1) << __FUNCTION__; |
1154 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1286 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1155 | 1287 |
1156 if (!success) { | 1288 if (!success) { |
1157 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 1289 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
1158 return; | 1290 return; |
1159 } | 1291 } |
1160 | 1292 |
1161 StartPipeline(); | 1293 StartPipeline(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1323 | 1455 |
1324 // pause() may be called after playback has ended and the HTMLMediaElement | 1456 // pause() may be called after playback has ended and the HTMLMediaElement |
1325 // requires that currentTime() == duration() after ending. We want to ensure | 1457 // requires that currentTime() == duration() after ending. We want to ensure |
1326 // |paused_time_| matches currentTime() in this case or a future seek() may | 1458 // |paused_time_| matches currentTime() in this case or a future seek() may |
1327 // incorrectly discard what it thinks is a seek to the existing time. | 1459 // incorrectly discard what it thinks is a seek to the existing time. |
1328 paused_time_ = | 1460 paused_time_ = |
1329 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); | 1461 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); |
1330 } | 1462 } |
1331 | 1463 |
1332 void WebMediaPlayerImpl::NotifyPlaybackStarted() { | 1464 void WebMediaPlayerImpl::NotifyPlaybackStarted() { |
1465 #if defined(OS_ANDROID) // WMPI_CAST | |
1466 // We do not tell our delegates about remote playback, becuase that would | |
1467 // keep the device awake, which is not what we want. | |
1468 if (cast_impl_.isRemote()) | |
1469 return; | |
1470 #endif | |
1333 if (delegate_) | 1471 if (delegate_) |
1334 delegate_->DidPlay(this); | 1472 delegate_->DidPlay(this); |
1335 if (!memory_usage_reporting_timer_.IsRunning()) { | 1473 if (!memory_usage_reporting_timer_.IsRunning()) { |
1336 memory_usage_reporting_timer_.Start(FROM_HERE, | 1474 memory_usage_reporting_timer_.Start(FROM_HERE, |
1337 base::TimeDelta::FromSeconds(2), this, | 1475 base::TimeDelta::FromSeconds(2), this, |
1338 &WebMediaPlayerImpl::ReportMemoryUsage); | 1476 &WebMediaPlayerImpl::ReportMemoryUsage); |
1339 } | 1477 } |
1340 } | 1478 } |
1341 | 1479 |
1342 void WebMediaPlayerImpl::NotifyPlaybackPaused() { | 1480 void WebMediaPlayerImpl::NotifyPlaybackPaused() { |
1481 #if defined(OS_ANDROID) // WMPI_CAST | |
1482 if (cast_impl_.isRemote()) | |
1483 return; | |
1484 #endif | |
1343 if (delegate_) | 1485 if (delegate_) |
1344 delegate_->DidPause(this); | 1486 delegate_->DidPause(this); |
1345 memory_usage_reporting_timer_.Stop(); | 1487 memory_usage_reporting_timer_.Stop(); |
1346 ReportMemoryUsage(); | 1488 ReportMemoryUsage(); |
1347 } | 1489 } |
1348 | 1490 |
1349 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1491 void WebMediaPlayerImpl::ReportMemoryUsage() { |
1350 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1492 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1351 | 1493 |
1352 // About base::Unretained() usage below: We destroy |demuxer_| on the main | 1494 // About base::Unretained() usage below: We destroy |demuxer_| on the main |
(...skipping 24 matching lines...) Expand all Loading... | |
1377 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1519 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
1378 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1520 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
1379 << ", Demuxer: " << demuxer_memory_usage; | 1521 << ", Demuxer: " << demuxer_memory_usage; |
1380 | 1522 |
1381 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1523 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
1382 last_reported_memory_usage_ = current_memory_usage; | 1524 last_reported_memory_usage_ = current_memory_usage; |
1383 adjust_allocated_memory_cb_.Run(delta); | 1525 adjust_allocated_memory_cb_.Run(delta); |
1384 } | 1526 } |
1385 | 1527 |
1386 } // namespace media | 1528 } // namespace media |
OLD | NEW |