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

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

Issue 2618883002: [Media, Video] Enable the video track for a new renderer. (Closed)
Patch Set: Added OnBeforeResume callback Created 3 years, 11 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
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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 set_cdm_result_->completeWithError( 1058 set_cdm_result_->completeWithError(
1058 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0, 1059 blink::WebContentDecryptionModuleExceptionNotSupportedError, 0,
1059 "Unable to set ContentDecryptionModule object"); 1060 "Unable to set ContentDecryptionModule object");
1060 set_cdm_result_.reset(); 1061 set_cdm_result_.reset();
1061 } 1062 }
1062 } 1063 }
1063 1064
1064 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) { 1065 void WebMediaPlayerImpl::OnPipelineSeeked(bool time_updated) {
1065 seeking_ = false; 1066 seeking_ = false;
1066 seek_time_ = base::TimeDelta(); 1067 seek_time_ = base::TimeDelta();
1068
1067 if (paused_) { 1069 if (paused_) {
1068 #if defined(OS_ANDROID) // WMPI_CAST 1070 #if defined(OS_ANDROID) // WMPI_CAST
1069 if (isRemote()) { 1071 if (isRemote()) {
1070 paused_time_ = base::TimeDelta::FromSecondsD(cast_impl_.currentTime()); 1072 paused_time_ = base::TimeDelta::FromSecondsD(cast_impl_.currentTime());
1071 } else { 1073 } else {
1072 paused_time_ = pipeline_.GetMediaTime(); 1074 paused_time_ = pipeline_.GetMediaTime();
1073 } 1075 }
1074 #else 1076 #else
1075 paused_time_ = pipeline_.GetMediaTime(); 1077 paused_time_ = pipeline_.GetMediaTime();
1076 #endif 1078 #endif
1077 } else { 1079 } else {
1078 DCHECK(watch_time_reporter_); 1080 DCHECK(watch_time_reporter_);
1079 watch_time_reporter_->OnPlaying(); 1081 watch_time_reporter_->OnPlaying();
1080 } 1082 }
1081 if (time_updated) 1083 if (time_updated)
1082 should_notify_time_changed_ = true; 1084 should_notify_time_changed_ = true;
1083 1085
1084 // Reset underflow count upon seek; this prevents looping videos and user 1086 // Reset underflow count upon seek; this prevents looping videos and user
1085 // actions from artificially inflating the underflow count. 1087 // actions from artificially inflating the underflow count.
1086 underflow_count_ = 0; 1088 underflow_count_ = 0;
1089
1090 // Apply optimizations for the hidden videos if hidden.
1091 if (IsHidden())
1092 OnHidden();
sandersd (OOO until July 31) 2017/01/10 21:34:37 OnHidden() does a bit more than what is requested,
whywhat 2017/01/11 19:41:30 I think that's the point of it, no? We initialize
sandersd (OOO until July 31) 2017/01/11 21:54:51 The target state for this code is that OnHidden()
1087 } 1093 }
1088 1094
1089 void WebMediaPlayerImpl::OnPipelineSuspended() { 1095 void WebMediaPlayerImpl::OnPipelineSuspended() {
1090 #if defined(OS_ANDROID) 1096 #if defined(OS_ANDROID)
1091 if (isRemote()) { 1097 if (isRemote()) {
1092 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner(); 1098 scoped_refptr<VideoFrame> frame = cast_impl_.GetCastingBanner();
1093 if (frame) 1099 if (frame)
1094 compositor_->PaintSingleFrame(frame); 1100 compositor_->PaintSingleFrame(frame);
1095 } 1101 }
1096 #endif 1102 #endif
1097 1103
1098 // If we're not in an aggressive buffering state, tell the data source we have 1104 // If we're not in an aggressive buffering state, tell the data source we have
1099 // enough data so that it may release the connection. 1105 // enough data so that it may release the connection.
1100 if (buffering_strategy_ != 1106 if (buffering_strategy_ !=
1101 MultibufferDataSource::BUFFERING_STRATEGY_AGGRESSIVE) { 1107 MultibufferDataSource::BUFFERING_STRATEGY_AGGRESSIVE) {
1102 if (data_source_) 1108 if (data_source_)
1103 data_source_->OnBufferingHaveEnough(true); 1109 data_source_->OnBufferingHaveEnough(true);
1104 } 1110 }
1105 1111
1106 ReportMemoryUsage(); 1112 ReportMemoryUsage();
1107 1113
1108 if (pending_suspend_resume_cycle_) { 1114 if (pending_suspend_resume_cycle_) {
1109 pending_suspend_resume_cycle_ = false; 1115 pending_suspend_resume_cycle_ = false;
1110 UpdatePlayState(); 1116 UpdatePlayState();
1111 } 1117 }
1112 } 1118 }
1113 1119
1120 void WebMediaPlayerImpl::OnBeforePipelineResume() {
1121 // Enable video track if we disabled it in the background - this way the new
1122 // renderer will attach its callbacks to the video stream properly.
1123 // TODO(avayvod): Remove this when disabling and enabling video tracks in
1124 // non-playing state works correctly. See https://crbug.com/678374.
1125 EnableVideoTrackIfNeeded();
1126 is_pipeline_resuming_ = true;
1127 }
1128
1129 void WebMediaPlayerImpl::OnPipelineResumed() {
1130 is_pipeline_resuming_ = false;
1131
1132 if (IsHidden()) {
1133 DisableVideoTrackIfNeeded();
1134 return;
sandersd (OOO until July 31) 2017/01/10 21:34:37 Nit: This may be a case where early return is more
whywhat 2017/01/11 19:41:30 Done. For some reason, I expect lint to complain t
1135 }
1136
1137 EnableVideoTrackIfNeeded();
1138 }
1139
1114 void WebMediaPlayerImpl::OnDemuxerOpened() { 1140 void WebMediaPlayerImpl::OnDemuxerOpened() {
1115 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1141 DCHECK(main_task_runner_->BelongsToCurrentThread());
1116 client_->mediaSourceOpened( 1142 client_->mediaSourceOpened(
1117 new WebMediaSourceImpl(chunk_demuxer_, media_log_)); 1143 new WebMediaSourceImpl(chunk_demuxer_, media_log_));
1118 } 1144 }
1119 1145
1120 void WebMediaPlayerImpl::OnError(PipelineStatus status) { 1146 void WebMediaPlayerImpl::OnError(PipelineStatus status) {
1121 DVLOG(1) << __func__; 1147 DVLOG(1) << __func__;
1122 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1148 DCHECK(main_task_runner_->BelongsToCurrentThread());
1123 DCHECK_NE(status, PIPELINE_OK); 1149 DCHECK_NE(status, PIPELINE_OK);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 if (video_weblayer_) 1372 if (video_weblayer_)
1347 video_weblayer_->layer()->SetContentsOpaque(opaque_); 1373 video_weblayer_->layer()->SetContentsOpaque(opaque_);
1348 } 1374 }
1349 1375
1350 void WebMediaPlayerImpl::OnHidden() { 1376 void WebMediaPlayerImpl::OnHidden() {
1351 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1377 DCHECK(main_task_runner_->BelongsToCurrentThread());
1352 1378
1353 if (watch_time_reporter_) 1379 if (watch_time_reporter_)
1354 watch_time_reporter_->OnHidden(); 1380 watch_time_reporter_->OnHidden();
1355 1381
1356 if (!IsStreaming() && IsBackgroundVideoTrackOptimizationEnabled()) { 1382 if (!paused_when_hidden_ && ShouldPauseWhenHidden()) {
sandersd (OOO until July 31) 2017/01/10 21:34:37 As a matter of style, I prefer idempotency whereve
whywhat 2017/01/11 19:41:30 I think it won't because ShouldPauseWhenHidden and
1357 if (ShouldPauseWhenHidden()) { 1383 // OnPause() will set |paused_when_hidden_| to false and call
1358 // OnPause() will set |paused_when_hidden_| to false and call 1384 // UpdatePlayState(), so set the flag to true after and then return.
1359 // UpdatePlayState(), so set the flag to true after and then return. 1385 OnPause();
1360 OnPause(); 1386 paused_when_hidden_ = true;
1361 paused_when_hidden_ = true; 1387 return;
1362 return; 1388 }
1363 }
1364 1389
1365 selectedVideoTrackChanged(nullptr); 1390 DisableVideoTrackIfNeeded();
1366 }
1367 1391
1368 UpdatePlayState(); 1392 UpdatePlayState();
1369 1393
1370 // Schedule suspended playing media to be paused if the user doesn't come back 1394 // Schedule suspended playing media to be paused if the user doesn't come back
1371 // to it within some timeout period to avoid any autoplay surprises. 1395 // to it within some timeout period to avoid any autoplay surprises.
1372 ScheduleIdlePauseTimer(); 1396 ScheduleIdlePauseTimer();
1373 } 1397 }
1374 1398
1375 void WebMediaPlayerImpl::OnShown() { 1399 void WebMediaPlayerImpl::OnShown() {
1376 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1400 DCHECK(main_task_runner_->BelongsToCurrentThread());
1377 if (watch_time_reporter_) 1401 if (watch_time_reporter_)
1378 watch_time_reporter_->OnShown(); 1402 watch_time_reporter_->OnShown();
1379 1403
1380 compositor_task_runner_->PostTask( 1404 compositor_task_runner_->PostTask(
1381 FROM_HERE, 1405 FROM_HERE,
1382 base::Bind(&VideoFrameCompositor::SetForegroundTime, 1406 base::Bind(&VideoFrameCompositor::SetForegroundTime,
1383 base::Unretained(compositor_), base::TimeTicks::Now())); 1407 base::Unretained(compositor_), base::TimeTicks::Now()));
1384 1408
1385 if (!IsStreaming() && IsBackgroundVideoTrackOptimizationEnabled()) { 1409 if (paused_when_hidden_) {
sandersd (OOO until July 31) 2017/01/10 21:34:37 By the same reasoning, this should go right before
whywhat 2017/01/11 19:41:30 Moved the state update above the new logic. I don
1386 if (paused_when_hidden_) { 1410 paused_when_hidden_ = false;
1387 paused_when_hidden_ = false; 1411 OnPlay(); // Calls UpdatePlayState() so return afterwards.
1388 OnPlay(); // Calls UpdatePlayState() so return afterwards. 1412 return;
1389 return; 1413 }
1390 }
1391 1414
1392 if (client_->hasSelectedVideoTrack()) { 1415 EnableVideoTrackIfNeeded();
1393 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId();
1394 selectedVideoTrackChanged(&trackId);
1395 }
1396 }
1397 1416
1398 must_suspend_ = false; 1417 must_suspend_ = false;
1399 background_pause_timer_.Stop(); 1418 background_pause_timer_.Stop();
1400 1419
1401 UpdatePlayState(); 1420 UpdatePlayState();
1402 } 1421 }
1403 1422
1404 bool WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { 1423 bool WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) {
1405 DCHECK(main_task_runner_->BelongsToCurrentThread()); 1424 DCHECK(main_task_runner_->BelongsToCurrentThread());
1406 1425
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after
2073 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; 2092 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0;
2074 } 2093 }
2075 2094
2076 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { 2095 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) {
2077 DCHECK(main_task_runner_->BelongsToCurrentThread()); 2096 DCHECK(main_task_runner_->BelongsToCurrentThread());
2078 2097
2079 client_->activateViewportIntersectionMonitoring(activate); 2098 client_->activateViewportIntersectionMonitoring(activate);
2080 } 2099 }
2081 2100
2082 bool WebMediaPlayerImpl::ShouldPauseWhenHidden() const { 2101 bool WebMediaPlayerImpl::ShouldPauseWhenHidden() const {
2102 DCHECK(IsHidden());
2103 // Don't pause videos being Cast (Android only) or if the background video
2104 // optimizations are off (desktop only).
2083 #if defined(OS_ANDROID) // WMPI_CAST 2105 #if defined(OS_ANDROID) // WMPI_CAST
2084 if (isRemote()) 2106 if (isRemote())
2085 return false; 2107 return false;
2086 #endif // defined(OS_ANDROID) // WMPI_CAST 2108 #else // defined(OS_ANDROID)
2109 if (!IsBackgroundVideoTrackOptimizationEnabled())
2110 return false;
2111 #endif // defined(OS_ANDROID)
2087 2112
2088 return hasVideo() && !hasAudio(); 2113 return hasVideo() && !hasAudio();
sandersd (OOO until July 31) 2017/01/10 21:34:37 Probably worth a comment somewhere: these conditio
whywhat 2017/01/11 19:41:30 Should I make an even stronger comment that they w
sandersd (OOO until July 31) 2017/01/11 21:54:51 OnMetadata is called after demuxer initialization,
2089 } 2114 }
2090 2115
2116 bool WebMediaPlayerImpl::ShouldDisableVideoWhenHidden() const {
2117 DCHECK(IsHidden());
2118 return IsBackgroundVideoTrackOptimizationEnabled() && hasVideo() &&
2119 hasAudio() && !IsStreaming();
2120 }
2121
2122 void WebMediaPlayerImpl::EnableVideoTrackIfNeeded() {
2123 DCHECK(!IsHidden());
2124
2125 // Don't change video track while the pipeline is resuming or seeking.
2126 if (is_pipeline_resuming_ || seeking_)
2127 return;
2128
2129 if (video_track_disabled_) {
2130 video_track_disabled_ = false;
2131 if (client_->hasSelectedVideoTrack()) {
2132 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId();
2133 selectedVideoTrackChanged(&trackId);
2134 }
2135 }
2136 }
2137
2138 void WebMediaPlayerImpl::DisableVideoTrackIfNeeded() {
2139 DCHECK(IsHidden());
2140
2141 // Don't change video track while the pipeline is resuming or seeking.
2142 if (is_pipeline_resuming_ || seeking_)
2143 return;
2144
2145 if (!video_track_disabled_ && ShouldDisableVideoWhenHidden()) {
2146 video_track_disabled_ = true;
2147 selectedVideoTrackChanged(nullptr);
2148 }
2149 }
2150
2091 } // namespace media 2151 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698