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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 media_task_runner_(params.media_task_runner()), | 193 media_task_runner_(params.media_task_runner()), |
194 worker_task_runner_(params.worker_task_runner()), | 194 worker_task_runner_(params.worker_task_runner()), |
195 media_log_(params.media_log()), | 195 media_log_(params.media_log()), |
196 pipeline_(media_task_runner_, media_log_.get()), | 196 pipeline_(media_task_runner_, media_log_.get()), |
197 pipeline_controller_( | 197 pipeline_controller_( |
198 &pipeline_, | 198 &pipeline_, |
199 base::Bind(&WebMediaPlayerImpl::CreateRenderer, | 199 base::Bind(&WebMediaPlayerImpl::CreateRenderer, |
200 base::Unretained(this)), | 200 base::Unretained(this)), |
201 base::Bind(&WebMediaPlayerImpl::OnPipelineSeeked, AsWeakPtr()), | 201 base::Bind(&WebMediaPlayerImpl::OnPipelineSeeked, AsWeakPtr()), |
202 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), | 202 base::Bind(&WebMediaPlayerImpl::OnPipelineSuspended, AsWeakPtr()), |
| 203 base::Bind(&WebMediaPlayerImpl::OnBeforePipelineResume, AsWeakPtr()), |
| 204 base::Bind(&WebMediaPlayerImpl::OnPipelineResumed, AsWeakPtr()), |
203 base::Bind(&WebMediaPlayerImpl::OnError, AsWeakPtr())), | 205 base::Bind(&WebMediaPlayerImpl::OnError, AsWeakPtr())), |
204 load_type_(LoadTypeURL), | 206 load_type_(LoadTypeURL), |
205 opaque_(false), | 207 opaque_(false), |
206 playback_rate_(0.0), | 208 playback_rate_(0.0), |
207 paused_(true), | 209 paused_(true), |
208 paused_when_hidden_(false), | 210 paused_when_hidden_(false), |
209 seeking_(false), | 211 seeking_(false), |
210 pending_suspend_resume_cycle_(false), | 212 pending_suspend_resume_cycle_(false), |
211 ended_(false), | 213 ended_(false), |
212 should_notify_time_changed_(false), | 214 should_notify_time_changed_(false), |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // incorrectly discard what it thinks is a seek to the existing time. | 469 // incorrectly discard what it thinks is a seek to the existing time. |
468 paused_time_ = | 470 paused_time_ = |
469 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); | 471 ended_ ? pipeline_.GetMediaDuration() : pipeline_.GetMediaTime(); |
470 | 472 |
471 if (observer_) | 473 if (observer_) |
472 observer_->OnPaused(); | 474 observer_->OnPaused(); |
473 | 475 |
474 DCHECK(watch_time_reporter_); | 476 DCHECK(watch_time_reporter_); |
475 watch_time_reporter_->OnPaused(); | 477 watch_time_reporter_->OnPaused(); |
476 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); | 478 media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::PAUSE)); |
| 479 |
477 UpdatePlayState(); | 480 UpdatePlayState(); |
478 } | 481 } |
479 | 482 |
480 bool WebMediaPlayerImpl::supportsSave() const { | 483 bool WebMediaPlayerImpl::supportsSave() const { |
481 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 484 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
482 return supports_save_; | 485 return supports_save_; |
483 } | 486 } |
484 | 487 |
485 void WebMediaPlayerImpl::seek(double seconds) { | 488 void WebMediaPlayerImpl::seek(double seconds) { |
486 DVLOG(1) << __func__ << "(" << seconds << "s)"; | 489 DVLOG(1) << __func__ << "(" << seconds << "s)"; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
664 << "]"; | 667 << "]"; |
665 pipeline_.OnEnabledAudioTracksChanged(enabledMediaTrackIds); | 668 pipeline_.OnEnabledAudioTracksChanged(enabledMediaTrackIds); |
666 } | 669 } |
667 | 670 |
668 void WebMediaPlayerImpl::selectedVideoTrackChanged( | 671 void WebMediaPlayerImpl::selectedVideoTrackChanged( |
669 blink::WebMediaPlayer::TrackId* selectedTrackId) { | 672 blink::WebMediaPlayer::TrackId* selectedTrackId) { |
670 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 673 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
671 | 674 |
672 std::ostringstream logstr; | 675 std::ostringstream logstr; |
673 std::vector<MediaTrack::Id> selectedVideoMediaTrackId; | 676 std::vector<MediaTrack::Id> selectedVideoMediaTrackId; |
674 bool canAddVideoTrack = | 677 if (selectedTrackId && !video_track_disabled_) { |
675 !IsBackgroundVideoTrackOptimizationEnabled() || !IsHidden(); | |
676 if (selectedTrackId && canAddVideoTrack) { | |
677 selectedVideoMediaTrackId.push_back(selectedTrackId->utf8().data()); | 678 selectedVideoMediaTrackId.push_back(selectedTrackId->utf8().data()); |
678 logstr << selectedVideoMediaTrackId[0]; | 679 logstr << selectedVideoMediaTrackId[0]; |
679 } | 680 } |
680 MEDIA_LOG(INFO, media_log_) << "Selected video track: [" << logstr.str() | 681 MEDIA_LOG(INFO, media_log_) << "Selected video track: [" << logstr.str() |
681 << "]"; | 682 << "]"; |
682 pipeline_.OnSelectedVideoTrackChanged(selectedVideoMediaTrackId); | 683 pipeline_.OnSelectedVideoTrackChanged(selectedVideoMediaTrackId); |
683 } | 684 } |
684 | 685 |
685 blink::WebSize WebMediaPlayerImpl::naturalSize() const { | 686 blink::WebSize WebMediaPlayerImpl::naturalSize() const { |
686 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 687 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 set_cdm_result_->completeWithError( | 1066 set_cdm_result_->completeWithError( |
1066 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0, | 1067 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0, |
1067 "Unable to set ContentDecryptionModule object"); | 1068 "Unable to set ContentDecryptionModule object"); |
1068 set_cdm_result_.reset(); | 1069 set_cdm_result_.reset(); |
1069 } | 1070 } |
1070 } | 1071 } |
1071 | 1072 |
1072 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) { | 1073 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) { |
1073 seeking_ = false; | 1074 seeking_ = false; |
1074 seek_time_ = base::TimeDelta(); | 1075 seek_time_ = base::TimeDelta(); |
| 1076 |
1075 if (paused_) { | 1077 if (paused_) { |
1076 #if defined(OS_ANDROID) // WMPI_CAST | 1078 #if defined(OS_ANDROID) // WMPI_CAST |
1077 if (isRemote()) { | 1079 if (isRemote()) { |
1078 paused_time_ = base::TimeDelta::FromSecondsD(cast_impl_.currentTime()); | 1080 paused_time_ = base::TimeDelta::FromSecondsD(cast_impl_.currentTime()); |
1079 } else { | 1081 } else { |
1080 paused_time_ = pipeline_.GetMediaTime(); | 1082 paused_time_ = pipeline_.GetMediaTime(); |
1081 } | 1083 } |
1082 #else | 1084 #else |
1083 paused_time_ = pipeline_.GetMediaTime(); | 1085 paused_time_ = pipeline_.GetMediaTime(); |
1084 #endif | 1086 #endif |
(...skipping 27 matching lines...) Expand all Loading... |
1112 } | 1114 } |
1113 | 1115 |
1114 ReportMemoryUsage(); | 1116 ReportMemoryUsage(); |
1115 | 1117 |
1116 if (pending_suspend_resume_cycle_) { | 1118 if (pending_suspend_resume_cycle_) { |
1117 pending_suspend_resume_cycle_ = false; | 1119 pending_suspend_resume_cycle_ = false; |
1118 UpdatePlayState(); | 1120 UpdatePlayState(); |
1119 } | 1121 } |
1120 } | 1122 } |
1121 | 1123 |
| 1124 void WebMediaPlayerImpl::OnBeforePipelineResume() { |
| 1125 // Enable video track if we disabled it in the background - this way the new |
| 1126 // renderer will attach its callbacks to the video stream properly. |
| 1127 // TODO(avayvod): Remove this when disabling and enabling video tracks in |
| 1128 // non-playing state works correctly. See https://crbug.com/678374. |
| 1129 EnableVideoTrackIfNeeded(); |
| 1130 is_pipeline_resuming_ = true; |
| 1131 } |
| 1132 |
| 1133 void WebMediaPlayerImpl::OnPipelineResumed() { |
| 1134 is_pipeline_resuming_ = false; |
| 1135 |
| 1136 if (IsHidden()) { |
| 1137 DisableVideoTrackIfNeeded(); |
| 1138 } else { |
| 1139 EnableVideoTrackIfNeeded(); |
| 1140 } |
| 1141 } |
| 1142 |
1122 void WebMediaPlayerImpl::OnDemuxerOpened() { | 1143 void WebMediaPlayerImpl::OnDemuxerOpened() { |
1123 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1144 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1124 client_->mediaSourceOpened( | 1145 client_->mediaSourceOpened( |
1125 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); | 1146 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); |
1126 } | 1147 } |
1127 | 1148 |
1128 void WebMediaPlayerImpl::OnError(PipelineStatus status) { | 1149 void WebMediaPlayerImpl::OnError(PipelineStatus status) { |
1129 DVLOG(1) << __func__; | 1150 DVLOG(1) << __func__; |
1130 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1151 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1131 DCHECK_NE(status, PIPELINE_OK); | 1152 DCHECK_NE(status, PIPELINE_OK); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 if (video_weblayer_) | 1374 if (video_weblayer_) |
1354 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1375 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
1355 } | 1376 } |
1356 | 1377 |
1357 void WebMediaPlayerImpl::OnHidden() { | 1378 void WebMediaPlayerImpl::OnHidden() { |
1358 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1379 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1359 | 1380 |
1360 if (watch_time_reporter_) | 1381 if (watch_time_reporter_) |
1361 watch_time_reporter_->OnHidden(); | 1382 watch_time_reporter_->OnHidden(); |
1362 | 1383 |
1363 if (!IsStreaming() && IsBackgroundVideoTrackOptimizationEnabled()) { | 1384 if (ShouldPauseWhenHidden()) { |
1364 if (ShouldPauseWhenHidden()) { | 1385 if (!paused_when_hidden_) { |
1365 // OnPause() will set |paused_when_hidden_| to false and call | 1386 // OnPause() will set |paused_when_hidden_| to false and call |
1366 // UpdatePlayState(), so set the flag to true after and then return. | 1387 // UpdatePlayState(), so set the flag to true after and then return. |
1367 OnPause(); | 1388 OnPause(); |
1368 paused_when_hidden_ = true; | 1389 paused_when_hidden_ = true; |
1369 return; | 1390 return; |
1370 } | 1391 } |
1371 | 1392 } else { |
1372 selectedVideoTrackChanged(nullptr); | 1393 DisableVideoTrackIfNeeded(); |
1373 } | 1394 } |
1374 | 1395 |
1375 UpdatePlayState(); | 1396 UpdatePlayState(); |
1376 | 1397 |
1377 // Schedule suspended playing media to be paused if the user doesn't come back | 1398 // Schedule suspended playing media to be paused if the user doesn't come back |
1378 // to it within some timeout period to avoid any autoplay surprises. | 1399 // to it within some timeout period to avoid any autoplay surprises. |
1379 ScheduleIdlePauseTimer(); | 1400 ScheduleIdlePauseTimer(); |
1380 } | 1401 } |
1381 | 1402 |
1382 void WebMediaPlayerImpl::OnShown() { | 1403 void WebMediaPlayerImpl::OnShown() { |
1383 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1404 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1384 if (watch_time_reporter_) | 1405 if (watch_time_reporter_) |
1385 watch_time_reporter_->OnShown(); | 1406 watch_time_reporter_->OnShown(); |
1386 | 1407 |
1387 compositor_task_runner_->PostTask( | 1408 compositor_task_runner_->PostTask( |
1388 FROM_HERE, | 1409 FROM_HERE, |
1389 base::Bind(&VideoFrameCompositor::SetForegroundTime, | 1410 base::Bind(&VideoFrameCompositor::SetForegroundTime, |
1390 base::Unretained(compositor_), base::TimeTicks::Now())); | 1411 base::Unretained(compositor_), base::TimeTicks::Now())); |
1391 | 1412 |
1392 if (!IsStreaming() && IsBackgroundVideoTrackOptimizationEnabled()) { | |
1393 if (paused_when_hidden_) { | |
1394 paused_when_hidden_ = false; | |
1395 OnPlay(); // Calls UpdatePlayState() so return afterwards. | |
1396 return; | |
1397 } | |
1398 | |
1399 if (client_->hasSelectedVideoTrack()) { | |
1400 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); | |
1401 selectedVideoTrackChanged(&trackId); | |
1402 } | |
1403 } | |
1404 | |
1405 must_suspend_ = false; | 1413 must_suspend_ = false; |
1406 background_pause_timer_.Stop(); | 1414 background_pause_timer_.Stop(); |
1407 | 1415 |
| 1416 if (paused_when_hidden_) { |
| 1417 paused_when_hidden_ = false; |
| 1418 OnPlay(); // Calls UpdatePlayState() so return afterwards. |
| 1419 return; |
| 1420 } |
| 1421 |
| 1422 EnableVideoTrackIfNeeded(); |
| 1423 |
1408 UpdatePlayState(); | 1424 UpdatePlayState(); |
1409 } | 1425 } |
1410 | 1426 |
1411 bool WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { | 1427 bool WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { |
1412 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1428 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
1413 | 1429 |
1414 if (must_suspend) { | 1430 if (must_suspend) { |
1415 must_suspend_ = true; | 1431 must_suspend_ = true; |
1416 UpdatePlayState(); | 1432 UpdatePlayState(); |
1417 return true; | 1433 return true; |
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; | 2085 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; |
2070 } | 2086 } |
2071 | 2087 |
2072 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { | 2088 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { |
2073 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2089 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
2074 | 2090 |
2075 client_->activateViewportIntersectionMonitoring(activate); | 2091 client_->activateViewportIntersectionMonitoring(activate); |
2076 } | 2092 } |
2077 | 2093 |
2078 bool WebMediaPlayerImpl::ShouldPauseWhenHidden() const { | 2094 bool WebMediaPlayerImpl::ShouldPauseWhenHidden() const { |
| 2095 DCHECK(IsHidden()); |
| 2096 // Don't pause videos being Cast (Android only) or if the background video |
| 2097 // optimizations are off (desktop only). |
2079 #if defined(OS_ANDROID) // WMPI_CAST | 2098 #if defined(OS_ANDROID) // WMPI_CAST |
2080 if (isRemote()) | 2099 if (isRemote()) |
2081 return false; | 2100 return false; |
2082 #endif // defined(OS_ANDROID) // WMPI_CAST | 2101 #else // defined(OS_ANDROID) |
| 2102 if (!IsBackgroundVideoTrackOptimizationEnabled()) |
| 2103 return false; |
| 2104 #endif // defined(OS_ANDROID) |
2083 | 2105 |
2084 return hasVideo() && !hasAudio(); | 2106 return hasVideo() && !hasAudio(); |
2085 } | 2107 } |
2086 | 2108 |
| 2109 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const { |
| 2110 DCHECK(IsHidden()); |
| 2111 return IsBackgroundVideoTrackOptimizationEnabled() && hasVideo() && |
| 2112 hasAudio() && !IsStreaming(); |
| 2113 } |
| 2114 |
| 2115 void WebMediaPlayerImpl::EnableVideoTrackIfNeeded() { |
| 2116 DCHECK(!IsHidden()); |
| 2117 |
| 2118 // Don't change video track while the pipeline is resuming or seeking. |
| 2119 if (is_pipeline_resuming_ || seeking_) |
| 2120 return; |
| 2121 |
| 2122 if (video_track_disabled_) { |
| 2123 video_track_disabled_ = false; |
| 2124 if (client_->hasSelectedVideoTrack()) { |
| 2125 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); |
| 2126 selectedVideoTrackChanged(&trackId); |
| 2127 } |
| 2128 } |
| 2129 } |
| 2130 |
| 2131 void WebMediaPlayerImpl::DisableVideoTrackIfNeeded() { |
| 2132 DCHECK(IsHidden()); |
| 2133 |
| 2134 // Don't change video track while the pipeline is resuming or seeking. |
| 2135 if (is_pipeline_resuming_ || seeking_) |
| 2136 return; |
| 2137 |
| 2138 if (!video_track_disabled_ && ShouldDisableVideoWhenHidden()) { |
| 2139 video_track_disabled_ = true; |
| 2140 selectedVideoTrackChanged(nullptr); |
| 2141 } |
| 2142 } |
| 2143 |
2087 } // namespace media | 2144 } // namespace media |
OLD | NEW |