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(), delegate), |
| 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 DCHECK(renderer_factory_); | 190 DCHECK(renderer_factory_); |
188 | 191 |
189 if (delegate) | 192 if (delegate) |
190 delegate->AddObserver(this); | 193 delegate->AddObserver(this); |
191 | 194 |
192 media_log_->AddEvent( | 195 media_log_->AddEvent( |
193 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 196 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
194 | 197 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 data_source_.reset(new BufferedDataSource( | 298 data_source_.reset(new BufferedDataSource( |
296 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), | 299 url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), |
297 main_task_runner_, frame_, media_log_.get(), | 300 main_task_runner_, frame_, media_log_.get(), |
298 &buffered_data_source_host_, | 301 &buffered_data_source_host_, |
299 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); | 302 base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); |
300 } | 303 } |
301 data_source_->SetPreload(preload_); | 304 data_source_->SetPreload(preload_); |
302 data_source_->SetBufferingStrategy(buffering_strategy_); | 305 data_source_->SetBufferingStrategy(buffering_strategy_); |
303 data_source_->Initialize( | 306 data_source_->Initialize( |
304 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); | 307 base::Bind(&WebMediaPlayerImpl::DataSourceInitialized, AsWeakPtr())); |
| 308 |
| 309 #if defined(OS_ANDROID) // WMPI_CAST |
| 310 cast_impl_.Initialize(url, frame_); |
| 311 #endif |
305 } | 312 } |
306 | 313 |
307 void WebMediaPlayerImpl::play() { | 314 void WebMediaPlayerImpl::play() { |
308 DVLOG(1) << __FUNCTION__; | 315 DVLOG(1) << __FUNCTION__; |
309 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 316 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
310 | 317 |
| 318 #if defined(OS_ANDROID) // WMPI_CAST |
| 319 if (isRemote()) { |
| 320 cast_impl_.play(); |
| 321 return; |
| 322 } |
| 323 #endif |
| 324 |
311 paused_ = false; | 325 paused_ = false; |
| 326 |
312 pipeline_.SetPlaybackRate(playback_rate_); | 327 pipeline_.SetPlaybackRate(playback_rate_); |
313 if (data_source_) | 328 if (data_source_) |
314 data_source_->MediaIsPlaying(); | 329 data_source_->MediaIsPlaying(); |
315 | 330 |
316 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); | 331 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PLAY)); |
317 | 332 |
318 if (delegate_ && playback_rate_ > 0) | 333 if (delegate_ && playback_rate_ > 0) |
319 NotifyPlaybackStarted(); | 334 NotifyPlaybackStarted(); |
320 } | 335 } |
321 | 336 |
322 void WebMediaPlayerImpl::pause() { | 337 void WebMediaPlayerImpl::pause() { |
323 DVLOG(1) << __FUNCTION__; | 338 DVLOG(1) << __FUNCTION__; |
324 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 339 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
325 | 340 |
326 const bool was_already_paused = paused_ || playback_rate_ == 0; | 341 const bool was_already_paused = paused_ || playback_rate_ == 0; |
327 paused_ = true; | 342 paused_ = true; |
| 343 |
| 344 #if defined(OS_ANDROID) // WMPI_CAST |
| 345 if (isRemote()) { |
| 346 cast_impl_.pause(); |
| 347 return; |
| 348 } |
| 349 #endif |
| 350 |
328 pipeline_.SetPlaybackRate(0.0); | 351 pipeline_.SetPlaybackRate(0.0); |
329 UpdatePausedTime(); | 352 UpdatePausedTime(); |
330 | 353 |
331 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); | 354 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); |
332 | 355 |
333 if (!was_already_paused && delegate_) | 356 if (!was_already_paused && delegate_) |
334 NotifyPlaybackPaused(); | 357 NotifyPlaybackPaused(); |
335 } | 358 } |
336 | 359 |
337 bool WebMediaPlayerImpl::supportsSave() const { | 360 bool WebMediaPlayerImpl::supportsSave() const { |
338 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 361 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
339 return supports_save_; | 362 return supports_save_; |
340 } | 363 } |
341 | 364 |
342 void WebMediaPlayerImpl::seek(double seconds) { | 365 void WebMediaPlayerImpl::seek(double seconds) { |
343 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; | 366 DVLOG(1) << __FUNCTION__ << "(" << seconds << "s)"; |
344 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 367 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
345 | 368 |
346 ended_ = false; | 369 ended_ = false; |
347 | 370 |
| 371 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); |
| 372 |
| 373 #if defined(OS_ANDROID) // WMPI_CAST |
| 374 if (isRemote()) { |
| 375 cast_impl_.seek(new_seek_time); |
| 376 return; |
| 377 } |
| 378 #endif |
| 379 |
348 ReadyState old_state = ready_state_; | 380 ReadyState old_state = ready_state_; |
349 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) | 381 if (ready_state_ > WebMediaPlayer::ReadyStateHaveMetadata) |
350 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); | 382 SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); |
351 | 383 |
352 base::TimeDelta new_seek_time = base::TimeDelta::FromSecondsD(seconds); | |
353 | |
354 if (seeking_ || suspended_) { | 384 if (seeking_ || suspended_) { |
355 // Once resuming, it's too late to change the resume time and so the | 385 // Once resuming, it's too late to change the resume time and so the |
356 // implementation is a little different. | 386 // implementation is a little different. |
357 bool is_suspended = suspended_ && !resuming_; | 387 bool is_suspended = suspended_ && !resuming_; |
358 | 388 |
359 // If we are currently seeking or resuming to |new_seek_time|, skip the | 389 // If we are currently seeking or resuming to |new_seek_time|, skip the |
360 // seek (except for MSE, which always seeks). | 390 // seek (except for MSE, which always seeks). |
361 if (!is_suspended && new_seek_time == seek_time_) { | 391 if (!is_suspended && new_seek_time == seek_time_) { |
362 if (chunk_demuxer_) { | 392 if (chunk_demuxer_) { |
363 // Don't suppress any redundant in-progress MSE seek. There could have | 393 // 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... |
417 return; | 447 return; |
418 } | 448 } |
419 } | 449 } |
420 | 450 |
421 seeking_ = true; | 451 seeking_ = true; |
422 seek_time_ = new_seek_time; | 452 seek_time_ = new_seek_time; |
423 | 453 |
424 if (chunk_demuxer_) | 454 if (chunk_demuxer_) |
425 chunk_demuxer_->StartWaitingForSeek(seek_time_); | 455 chunk_demuxer_->StartWaitingForSeek(seek_time_); |
426 | 456 |
427 // Kick off the asynchronous seek! | |
428 pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1( | 457 pipeline_.Seek(seek_time_, BIND_TO_RENDER_LOOP1( |
429 &WebMediaPlayerImpl::OnPipelineSeeked, true)); | 458 &WebMediaPlayerImpl::OnPipelineSeeked, true)); |
430 } | 459 } |
431 | 460 |
432 void WebMediaPlayerImpl::setRate(double rate) { | 461 void WebMediaPlayerImpl::setRate(double rate) { |
433 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; | 462 DVLOG(1) << __FUNCTION__ << "(" << rate << ")"; |
434 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 463 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
435 | 464 |
436 // TODO(kylep): Remove when support for negatives is added. Also, modify the | 465 // TODO(kylep): Remove when support for negatives is added. Also, modify the |
437 // following checks so rewind uses reasonable values also. | 466 // following checks so rewind uses reasonable values also. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 | 563 |
535 blink::WebSize WebMediaPlayerImpl::naturalSize() const { | 564 blink::WebSize WebMediaPlayerImpl::naturalSize() const { |
536 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 565 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
537 | 566 |
538 return blink::WebSize(pipeline_metadata_.natural_size); | 567 return blink::WebSize(pipeline_metadata_.natural_size); |
539 } | 568 } |
540 | 569 |
541 bool WebMediaPlayerImpl::paused() const { | 570 bool WebMediaPlayerImpl::paused() const { |
542 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 571 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
543 | 572 |
| 573 #if defined(OS_ANDROID) // WMPI_CAST |
| 574 if (isRemote()) |
| 575 return cast_impl_.paused(); |
| 576 #endif |
544 return pipeline_.GetPlaybackRate() == 0.0f; | 577 return pipeline_.GetPlaybackRate() == 0.0f; |
545 } | 578 } |
546 | 579 |
547 bool WebMediaPlayerImpl::seeking() const { | 580 bool WebMediaPlayerImpl::seeking() const { |
548 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 581 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
549 | 582 |
550 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) | 583 if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing) |
551 return false; | 584 return false; |
552 | 585 |
553 return seeking_; | 586 return seeking_; |
(...skipping 27 matching lines...) Expand all Loading... |
581 return duration(); | 614 return duration(); |
582 | 615 |
583 // We know the current seek time better than pipeline: pipeline may processing | 616 // We know the current seek time better than pipeline: pipeline may processing |
584 // an earlier seek before a pending seek has been started, or it might not yet | 617 // an earlier seek before a pending seek has been started, or it might not yet |
585 // have the current seek time returnable via GetMediaTime(). | 618 // have the current seek time returnable via GetMediaTime(). |
586 if (seeking()) { | 619 if (seeking()) { |
587 return pending_seek_ ? pending_seek_time_.InSecondsF() | 620 return pending_seek_ ? pending_seek_time_.InSecondsF() |
588 : seek_time_.InSecondsF(); | 621 : seek_time_.InSecondsF(); |
589 } | 622 } |
590 | 623 |
591 return (paused_ ? paused_time_ : pipeline_.GetMediaTime()).InSecondsF(); | 624 #if defined(OS_ANDROID) // WMPI_CAST |
| 625 if (isRemote()) { |
| 626 return cast_impl_.currentTime(); |
| 627 } |
| 628 #endif |
| 629 |
| 630 if (paused_) { |
| 631 return paused_time_.InSecondsF(); |
| 632 } |
| 633 |
| 634 return pipeline_.GetMediaTime().InSecondsF(); |
592 } | 635 } |
593 | 636 |
594 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { | 637 WebMediaPlayer::NetworkState WebMediaPlayerImpl::networkState() const { |
595 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 638 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
596 return network_state_; | 639 return network_state_; |
597 } | 640 } |
598 | 641 |
599 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { | 642 WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { |
600 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 643 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
601 return ready_state_; | 644 return ready_state_; |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; | 951 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; |
909 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 952 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
910 | 953 |
911 if (status != PIPELINE_OK) { | 954 if (status != PIPELINE_OK) { |
912 OnPipelineError(status); | 955 OnPipelineError(status); |
913 return; | 956 return; |
914 } | 957 } |
915 | 958 |
916 suspending_ = false; | 959 suspending_ = false; |
917 | 960 |
| 961 #if defined(OS_ANDROID) |
| 962 if (isRemote()) { |
| 963 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); |
| 964 if (frame) { |
| 965 compositor_->PaintFrameUsingOldRenderingPath(frame); |
| 966 } |
| 967 } |
| 968 #endif |
| 969 |
918 if (pending_resume_) { | 970 if (pending_resume_) { |
919 pending_resume_ = false; | 971 pending_resume_ = false; |
920 Resume(); | 972 Resume(); |
921 return; | 973 return; |
922 } | 974 } |
923 } | 975 } |
924 | 976 |
925 void WebMediaPlayerImpl::OnPipelineEnded() { | 977 void WebMediaPlayerImpl::OnPipelineEnded() { |
926 DVLOG(1) << __FUNCTION__; | 978 DVLOG(1) << __FUNCTION__; |
927 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 979 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 switches::kEnableMediaSuspend)) { | 1100 switches::kEnableMediaSuspend)) { |
1049 return; | 1101 return; |
1050 } | 1102 } |
1051 #endif // !defined(OS_ANDROID) | 1103 #endif // !defined(OS_ANDROID) |
1052 | 1104 |
1053 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1105 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
1054 switches::kDisableMediaSuspend)) { | 1106 switches::kDisableMediaSuspend)) { |
1055 return; | 1107 return; |
1056 } | 1108 } |
1057 | 1109 |
| 1110 #if defined(OS_ANDROID) |
| 1111 // If we're remote, the pipeline should already be suspended. |
| 1112 if (isRemote()) |
| 1113 return; |
| 1114 #endif |
| 1115 |
| 1116 ScheduleSuspend(); |
| 1117 } |
| 1118 |
| 1119 void WebMediaPlayerImpl::ScheduleSuspend() { |
1058 if (!pipeline_.IsRunning() || !hasVideo()) | 1120 if (!pipeline_.IsRunning() || !hasVideo()) |
1059 return; | 1121 return; |
1060 | 1122 |
1061 if (resuming_ || seeking_) { | 1123 if (resuming_ || seeking_) { |
1062 pending_suspend_ = true; | 1124 pending_suspend_ = true; |
1063 return; | 1125 return; |
1064 } | 1126 } |
1065 | 1127 |
1066 if (pending_resume_) { | 1128 if (pending_resume_) { |
1067 pending_resume_ = false; | 1129 pending_resume_ = false; |
(...skipping 21 matching lines...) Expand all Loading... |
1089 switches::kEnableMediaSuspend)) { | 1151 switches::kEnableMediaSuspend)) { |
1090 return; | 1152 return; |
1091 } | 1153 } |
1092 #endif // !defined(OS_ANDROID) | 1154 #endif // !defined(OS_ANDROID) |
1093 | 1155 |
1094 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 1156 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
1095 switches::kDisableMediaSuspend)) { | 1157 switches::kDisableMediaSuspend)) { |
1096 return; | 1158 return; |
1097 } | 1159 } |
1098 | 1160 |
| 1161 #if defined(OS_ANDROID) |
| 1162 // If we're remote, the pipeline should stay suspended. |
| 1163 if (isRemote()) |
| 1164 return; |
| 1165 #endif |
| 1166 |
| 1167 ScheduleResume(); |
| 1168 } |
| 1169 |
| 1170 void WebMediaPlayerImpl::ScheduleResume() { |
1099 if (!pipeline_.IsRunning()) | 1171 if (!pipeline_.IsRunning()) |
1100 return; | 1172 return; |
1101 | 1173 |
1102 if (suspending_) { | 1174 if (suspending_) { |
1103 pending_resume_ = true; | 1175 pending_resume_ = true; |
1104 return; | 1176 return; |
1105 } | 1177 } |
1106 | 1178 |
1107 if (pending_suspend_) { | 1179 if (pending_suspend_) { |
1108 pending_suspend_ = false; | 1180 pending_suspend_ = false; |
1109 return; | 1181 return; |
1110 } | 1182 } |
1111 | 1183 |
1112 // We may not be suspended if we were not yet subscribed or the pipeline was | 1184 // Might already be resuming iff we came back from remote playback recently. |
1113 // not yet started when OnHidden() fired. | 1185 if (suspended_ && !resuming_) |
1114 if (!suspended_) | 1186 Resume(); |
1115 return; | |
1116 | |
1117 Resume(); | |
1118 } | 1187 } |
1119 | 1188 |
1120 void WebMediaPlayerImpl::Resume() { | 1189 void WebMediaPlayerImpl::Resume() { |
1121 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1190 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1122 CHECK(suspended_); | 1191 CHECK(suspended_); |
1123 CHECK(!resuming_); | 1192 CHECK(!resuming_); |
1124 | 1193 |
1125 // If there was a time change pending when we suspended (which can happen when | 1194 // If there was a time change pending when we suspended (which can happen when |
1126 // we suspend immediately after a seek), surface it after resuming. | 1195 // we suspend immediately after a seek), surface it after resuming. |
1127 bool time_changed = pending_time_change_; | 1196 bool time_changed = pending_time_change_; |
(...skipping 15 matching lines...) Expand all Loading... |
1143 | 1212 |
1144 if (chunk_demuxer_) | 1213 if (chunk_demuxer_) |
1145 chunk_demuxer_->StartWaitingForSeek(seek_time_); | 1214 chunk_demuxer_->StartWaitingForSeek(seek_time_); |
1146 | 1215 |
1147 resuming_ = true; | 1216 resuming_ = true; |
1148 pipeline_.Resume(CreateRenderer(), seek_time_, | 1217 pipeline_.Resume(CreateRenderer(), seek_time_, |
1149 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, | 1218 BIND_TO_RENDER_LOOP1(&WebMediaPlayerImpl::OnPipelineSeeked, |
1150 time_changed)); | 1219 time_changed)); |
1151 } | 1220 } |
1152 | 1221 |
| 1222 #if defined(OS_ANDROID) // WMPI_CAST |
| 1223 |
| 1224 bool WebMediaPlayerImpl::isRemote() const { |
| 1225 return cast_impl_.isRemote(); |
| 1226 } |
| 1227 |
| 1228 void WebMediaPlayerImpl::SetMediaPlayerManager( |
| 1229 RendererMediaPlayerManagerInterface* media_player_manager) { |
| 1230 cast_impl_.SetMediaPlayerManager(media_player_manager); |
| 1231 } |
| 1232 |
| 1233 void WebMediaPlayerImpl::requestRemotePlayback() { |
| 1234 cast_impl_.requestRemotePlayback(); |
| 1235 } |
| 1236 |
| 1237 void WebMediaPlayerImpl::requestRemotePlaybackControl() { |
| 1238 cast_impl_.requestRemotePlaybackControl(); |
| 1239 } |
| 1240 |
| 1241 void WebMediaPlayerImpl::OnRemotePlaybackEnded() { |
| 1242 DVLOG(1) << __FUNCTION__; |
| 1243 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1244 |
| 1245 ended_ = true; |
| 1246 client_->timeChanged(); |
| 1247 } |
| 1248 |
| 1249 void WebMediaPlayerImpl::OnDisconnectedFromRemoteDevice(double t) { |
| 1250 paused_time_ = base::TimeDelta::FromSecondsD(t); |
| 1251 pending_seek_ = true; |
| 1252 pending_seek_time_ = paused_time_; |
| 1253 |
| 1254 ScheduleResume(); |
| 1255 |
| 1256 if (paused_time_ == pipeline_.GetMediaDuration()) { |
| 1257 ended_ = true; |
| 1258 } |
| 1259 // We already told the delegate we're paused when remoting started. |
| 1260 client_->playbackStateChanged(); |
| 1261 client_->disconnectedFromRemoteDevice(); |
| 1262 } |
| 1263 |
| 1264 void WebMediaPlayerImpl::SuspendForRemote() { |
| 1265 if (suspended_ && !suspending_) { |
| 1266 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); |
| 1267 if (frame) { |
| 1268 compositor_->PaintFrameUsingOldRenderingPath(frame); |
| 1269 } |
| 1270 } |
| 1271 ScheduleSuspend(); |
| 1272 } |
| 1273 |
| 1274 gfx::Size WebMediaPlayerImpl::GetCanvasSize() const { |
| 1275 if (!video_weblayer_) |
| 1276 return pipeline_metadata_.natural_size; |
| 1277 |
| 1278 return video_weblayer_->bounds(); |
| 1279 } |
| 1280 |
| 1281 void WebMediaPlayerImpl::SetDeviceScaleFactor(float scale_factor) { |
| 1282 cast_impl_.SetDeviceScaleFactor(scale_factor); |
| 1283 } |
| 1284 #endif // defined(OS_ANDROID) // WMPI_CAST |
| 1285 |
1153 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { | 1286 void WebMediaPlayerImpl::DataSourceInitialized(bool success) { |
1154 DVLOG(1) << __FUNCTION__; | 1287 DVLOG(1) << __FUNCTION__; |
1155 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1288 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1156 | 1289 |
1157 if (!success) { | 1290 if (!success) { |
1158 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); | 1291 SetNetworkState(WebMediaPlayer::NetworkStateFormatError); |
1159 return; | 1292 return; |
1160 } | 1293 } |
1161 | 1294 |
1162 StartPipeline(); | 1295 StartPipeline(); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 | 1457 |
1325 // pause() may be called after playback has ended and the HTMLMediaElement | 1458 // pause() may be called after playback has ended and the HTMLMediaElement |
1326 // requires that currentTime() == duration() after ending. We want to ensure | 1459 // requires that currentTime() == duration() after ending. We want to ensure |
1327 // |paused_time_| matches currentTime() in this case or a future seek() may | 1460 // |paused_time_| matches currentTime() in this case or a future seek() may |
1328 // incorrectly discard what it thinks is a seek to the existing time. | 1461 // incorrectly discard what it thinks is a seek to the existing time. |
1329 paused_time_ = | 1462 paused_time_ = |
1330 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); | 1463 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); |
1331 } | 1464 } |
1332 | 1465 |
1333 void WebMediaPlayerImpl::NotifyPlaybackStarted() { | 1466 void WebMediaPlayerImpl::NotifyPlaybackStarted() { |
| 1467 #if defined(OS_ANDROID) // WMPI_CAST |
| 1468 // We do not tell our delegates about remote playback, becuase that would |
| 1469 // keep the device awake, which is not what we want. |
| 1470 if (isRemote()) |
| 1471 return; |
| 1472 #endif |
1334 if (delegate_) | 1473 if (delegate_) |
1335 delegate_->DidPlay(this); | 1474 delegate_->DidPlay(this); |
1336 if (!memory_usage_reporting_timer_.IsRunning()) { | 1475 if (!memory_usage_reporting_timer_.IsRunning()) { |
1337 memory_usage_reporting_timer_.Start(FROM_HERE, | 1476 memory_usage_reporting_timer_.Start(FROM_HERE, |
1338 base::TimeDelta::FromSeconds(2), this, | 1477 base::TimeDelta::FromSeconds(2), this, |
1339 &WebMediaPlayerImpl::ReportMemoryUsage); | 1478 &WebMediaPlayerImpl::ReportMemoryUsage); |
1340 } | 1479 } |
1341 } | 1480 } |
1342 | 1481 |
1343 void WebMediaPlayerImpl::NotifyPlaybackPaused() { | 1482 void WebMediaPlayerImpl::NotifyPlaybackPaused() { |
| 1483 #if defined(OS_ANDROID) // WMPI_CAST |
| 1484 if (isRemote()) |
| 1485 return; |
| 1486 #endif |
1344 if (delegate_) | 1487 if (delegate_) |
1345 delegate_->DidPause(this); | 1488 delegate_->DidPause(this); |
1346 memory_usage_reporting_timer_.Stop(); | 1489 memory_usage_reporting_timer_.Stop(); |
1347 ReportMemoryUsage(); | 1490 ReportMemoryUsage(); |
1348 } | 1491 } |
1349 | 1492 |
1350 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1493 void WebMediaPlayerImpl::ReportMemoryUsage() { |
1351 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1494 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1352 | 1495 |
1353 // About base::Unretained() usage below: We destroy |demuxer_| on the main | 1496 // About base::Unretained() usage below: We destroy |demuxer_| on the main |
(...skipping 24 matching lines...) Expand all Loading... |
1378 << ", Video: " << stats.video_memory_usage << ", DataSource: " | 1521 << ", Video: " << stats.video_memory_usage << ", DataSource: " |
1379 << (data_source_ ? data_source_->GetMemoryUsage() : 0) | 1522 << (data_source_ ? data_source_->GetMemoryUsage() : 0) |
1380 << ", Demuxer: " << demuxer_memory_usage; | 1523 << ", Demuxer: " << demuxer_memory_usage; |
1381 | 1524 |
1382 const int64_t delta = current_memory_usage - last_reported_memory_usage_; | 1525 const int64_t delta = current_memory_usage - last_reported_memory_usage_; |
1383 last_reported_memory_usage_ = current_memory_usage; | 1526 last_reported_memory_usage_ = current_memory_usage; |
1384 adjust_allocated_memory_cb_.Run(delta); | 1527 adjust_allocated_memory_cb_.Run(delta); |
1385 } | 1528 } |
1386 | 1529 |
1387 } // namespace media | 1530 } // namespace media |
OLD | NEW |