Chromium Code Reviews| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 return natural_size; | 142 return natural_size; |
| 143 } | 143 } |
| 144 | 144 |
| 145 base::TimeDelta GetCurrentTimeInternal(WebMediaPlayerImpl* p_this) { | 145 base::TimeDelta GetCurrentTimeInternal(WebMediaPlayerImpl* p_this) { |
| 146 // We wrap currentTime() instead of using pipeline_.GetMediaTime() since there | 146 // We wrap currentTime() instead of using pipeline_.GetMediaTime() since there |
| 147 // are a variety of cases in which that time is not accurate; e.g., while | 147 // are a variety of cases in which that time is not accurate; e.g., while |
| 148 // remoting and during a pause or seek. | 148 // remoting and during a pause or seek. |
| 149 return base::TimeDelta::FromSecondsD(p_this->currentTime()); | 149 return base::TimeDelta::FromSecondsD(p_this->currentTime()); |
| 150 } | 150 } |
| 151 | 151 |
| 152 // How much time must have elapsed since loading last progressed before the | 152 // How much time must have elapsed since loading last progressed before we |
| 153 // player is eligible for idle suspension. | 153 // assume that the decoder will have had time to complete preroll. |
| 154 constexpr base::TimeDelta kLoadingToIdleTimeout = | 154 constexpr base::TimeDelta kPrerollAttemptTimeout = |
| 155 base::TimeDelta::FromSeconds(3); | 155 base::TimeDelta::FromSeconds(3); |
| 156 | 156 |
| 157 } // namespace | 157 } // namespace |
| 158 | 158 |
| 159 class BufferedDataSourceHostImpl; | 159 class BufferedDataSourceHostImpl; |
| 160 | 160 |
| 161 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeUnspecified, | 161 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeUnspecified, |
| 162 UrlData::CORS_UNSPECIFIED); | 162 UrlData::CORS_UNSPECIFIED); |
| 163 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeAnonymous, UrlData::CORS_ANONYMOUS); | 163 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeAnonymous, UrlData::CORS_ANONYMOUS); |
| 164 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeUseCredentials, | 164 STATIC_ASSERT_ENUM(WebMediaPlayer::CORSModeUseCredentials, |
| 165 UrlData::CORS_USE_CREDENTIALS); | 165 UrlData::CORS_USE_CREDENTIALS); |
| 166 | 166 |
| 167 #define BIND_TO_RENDER_LOOP(function) \ | 167 #define BIND_TO_RENDER_LOOP(function) \ |
| 168 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ | 168 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
| 169 BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) | 169 BindToCurrentLoop(base::Bind(function, AsWeakPtr()))) |
| 170 | 170 |
| 171 #define BIND_TO_RENDER_LOOP1(function, arg1) \ | 171 #define BIND_TO_RENDER_LOOP1(function, arg1) \ |
| 172 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ | 172 (DCHECK(main_task_runner_->BelongsToCurrentThread()), \ |
| 173 BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) | 173 BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1))) |
| 174 | 174 |
| 175 WebMediaPlayerImpl::WebMediaPlayerImpl( | 175 WebMediaPlayerImpl::WebMediaPlayerImpl( |
| 176 blink::WebLocalFrame* frame, | 176 blink::WebLocalFrame* frame, |
| 177 blink::WebMediaPlayerClient* client, | 177 blink::WebMediaPlayerClient* client, |
| 178 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, | 178 blink::WebMediaPlayerEncryptedMediaClient* encrypted_client, |
| 179 base::WeakPtr<WebMediaPlayerDelegate> delegate, | 179 base::WeakPtr<WebMediaPlayerDelegate> delegate, |
| 180 std::unique_ptr<RendererFactory> renderer_factory, | 180 std::unique_ptr<RendererFactory> renderer_factory, |
| 181 linked_ptr<UrlIndex> url_index, | 181 linked_ptr<UrlIndex> url_index, |
| 182 const WebMediaPlayerParams& params) | 182 const WebMediaPlayerParams& params) |
| 183 : frame_(frame), | 183 : frame_(frame), |
| 184 delegate_state_(DelegateState::GONE), | |
| 185 is_idle_(false), | |
| 186 must_suspend_(false), | |
| 187 network_state_(WebMediaPlayer::NetworkStateEmpty), | 184 network_state_(WebMediaPlayer::NetworkStateEmpty), |
| 188 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 185 ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 189 highest_ready_state_(WebMediaPlayer::ReadyStateHaveNothing), | 186 highest_ready_state_(WebMediaPlayer::ReadyStateHaveNothing), |
| 190 preload_(MultibufferDataSource::AUTO), | 187 preload_(MultibufferDataSource::AUTO), |
| 191 buffering_strategy_(MultibufferDataSource::BUFFERING_STRATEGY_NORMAL), | 188 buffering_strategy_(MultibufferDataSource::BUFFERING_STRATEGY_NORMAL), |
| 192 main_task_runner_(frame->loadingTaskRunner()), | 189 main_task_runner_(frame->loadingTaskRunner()), |
| 193 media_task_runner_(params.media_task_runner()), | 190 media_task_runner_(params.media_task_runner()), |
| 194 worker_task_runner_(params.worker_task_runner()), | 191 worker_task_runner_(params.worker_task_runner()), |
| 195 media_log_(params.media_log()), | 192 media_log_(params.media_log()), |
| 196 pipeline_(media_task_runner_, media_log_.get()), | 193 pipeline_(media_task_runner_, media_log_.get()), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 233 volume_(1.0), | 230 volume_(1.0), |
| 234 volume_multiplier_(1.0), | 231 volume_multiplier_(1.0), |
| 235 renderer_factory_(std::move(renderer_factory)), | 232 renderer_factory_(std::move(renderer_factory)), |
| 236 surface_manager_(params.surface_manager()), | 233 surface_manager_(params.surface_manager()), |
| 237 overlay_surface_id_(SurfaceManager::kNoSurfaceID), | 234 overlay_surface_id_(SurfaceManager::kNoSurfaceID), |
| 238 suppress_destruction_errors_(false), | 235 suppress_destruction_errors_(false), |
| 239 can_suspend_state_(CanSuspendState::UNKNOWN), | 236 can_suspend_state_(CanSuspendState::UNKNOWN), |
| 240 use_fallback_path_(false), | 237 use_fallback_path_(false), |
| 241 is_encrypted_(false), | 238 is_encrypted_(false), |
| 242 underflow_count_(0), | 239 underflow_count_(0), |
| 240 preroll_attempt_pending_(false), | |
| 243 observer_(params.media_observer()) { | 241 observer_(params.media_observer()) { |
| 244 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 242 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 245 DCHECK(renderer_factory_); | 243 DCHECK(renderer_factory_); |
| 246 DCHECK(client_); | 244 DCHECK(client_); |
| 247 | 245 |
| 248 tick_clock_.reset(new base::DefaultTickClock()); | 246 tick_clock_.reset(new base::DefaultTickClock()); |
| 249 | 247 |
| 250 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 248 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 251 switches::kForceVideoOverlays); | 249 switches::kForceVideoOverlays); |
| 252 | 250 |
| 253 if (delegate_) | 251 if (delegate_) { |
| 254 delegate_id_ = delegate_->AddObserver(this); | 252 delegate_id_ = delegate_->AddObserver(this); |
| 253 delegate_->SetIdle(delegate_id_, true); | |
| 254 } | |
| 255 | 255 |
| 256 media_log_->AddEvent( | 256 media_log_->AddEvent( |
| 257 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); | 257 media_log_->CreateEvent(MediaLogEvent::WEBMEDIAPLAYER_CREATED)); |
| 258 | 258 |
| 259 if (params.initial_cdm()) | 259 if (params.initial_cdm()) |
| 260 SetCdm(params.initial_cdm()); | 260 SetCdm(params.initial_cdm()); |
| 261 | 261 |
| 262 // TODO(xhwang): When we use an external Renderer, many methods won't work, | 262 // TODO(xhwang): When we use an external Renderer, many methods won't work, |
| 263 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 | 263 // e.g. GetCurrentFrameFromCompositor(). See http://crbug.com/434861 |
| 264 audio_source_provider_ = | 264 audio_source_provider_ = |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 void WebMediaPlayerImpl::play() { | 415 void WebMediaPlayerImpl::play() { |
| 416 DVLOG(1) << __func__; | 416 DVLOG(1) << __func__; |
| 417 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 417 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 418 | 418 |
| 419 #if defined(OS_ANDROID) // WMPI_CAST | 419 #if defined(OS_ANDROID) // WMPI_CAST |
| 420 if (isRemote()) { | 420 if (isRemote()) { |
| 421 cast_impl_.play(); | 421 cast_impl_.play(); |
| 422 return; | 422 return; |
| 423 } | 423 } |
| 424 #endif | 424 #endif |
| 425 // TODO(sandersd): Do we want to reset the idle timer here? | |
| 426 if (delegate_) | |
| 427 delegate_->SetIdle(delegate_id_, false); | |
| 425 paused_ = false; | 428 paused_ = false; |
| 426 is_idle_ = false; | |
| 427 pipeline_.SetPlaybackRate(playback_rate_); | 429 pipeline_.SetPlaybackRate(playback_rate_); |
| 428 background_pause_timer_.Stop(); | 430 background_pause_timer_.Stop(); |
| 429 | 431 |
| 430 if (data_source_) | 432 if (data_source_) |
| 431 data_source_->MediaIsPlaying(); | 433 data_source_->MediaIsPlaying(); |
| 432 | 434 |
| 433 if (observer_) | 435 if (observer_) |
| 434 observer_->OnPlaying(); | 436 observer_->OnPlaying(); |
| 435 | 437 |
| 436 DCHECK(watch_time_reporter_); | 438 DCHECK(watch_time_reporter_); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 517 AsWeakPtr(), BUFFERING_HAVE_ENOUGH)); | 519 AsWeakPtr(), BUFFERING_HAVE_ENOUGH)); |
| 518 } | 520 } |
| 519 return; | 521 return; |
| 520 } | 522 } |
| 521 | 523 |
| 522 // Call this before setting |seeking_| so that the current media time can be | 524 // Call this before setting |seeking_| so that the current media time can be |
| 523 // recorded by the reporter. | 525 // recorded by the reporter. |
| 524 if (watch_time_reporter_) | 526 if (watch_time_reporter_) |
| 525 watch_time_reporter_->OnSeeking(); | 527 watch_time_reporter_->OnSeeking(); |
| 526 | 528 |
| 527 // TODO(sandersd): Ideally we would not clear the idle state if | 529 // TODO(sandersd): Move |seeking_| to PipelineController. |
| 528 // |pipeline_controller_| can elide the seek. | 530 // TODO(sandersd): Do we want to reset the idle timer here? |
| 529 is_idle_ = false; | 531 if (delegate_) |
| 532 delegate_->SetIdle(delegate_id_, false); | |
| 530 ended_ = false; | 533 ended_ = false; |
| 531 | |
| 532 seeking_ = true; | 534 seeking_ = true; |
| 533 seek_time_ = time; | 535 seek_time_ = time; |
| 534 if (paused_) | 536 if (paused_) |
| 535 paused_time_ = time; | 537 paused_time_ = time; |
| 536 pipeline_controller_.Seek(time, time_updated); | 538 pipeline_controller_.Seek(time, time_updated); |
| 537 | 539 |
| 538 // This needs to be called after Seek() so that if a resume is triggered, it | 540 // This needs to be called after Seek() so that if a resume is triggered, it |
| 539 // is to the correct time. | 541 // is to the correct time. |
| 540 UpdatePlayState(); | 542 UpdatePlayState(); |
| 541 } | 543 } |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 std::isfinite(seekable_end); | 790 std::isfinite(seekable_end); |
| 789 | 791 |
| 790 // TODO(dalecurtis): Technically this allows seeking on media which return an | 792 // TODO(dalecurtis): Technically this allows seeking on media which return an |
| 791 // infinite duration so long as DataSource::IsStreaming() is false. While not | 793 // infinite duration so long as DataSource::IsStreaming() is false. While not |
| 792 // expected, disabling this breaks semi-live players, http://crbug.com/427412. | 794 // expected, disabling this breaks semi-live players, http://crbug.com/427412. |
| 793 const blink::WebTimeRange seekable_range( | 795 const blink::WebTimeRange seekable_range( |
| 794 0.0, allow_seek_to_zero ? 0.0 : seekable_end); | 796 0.0, allow_seek_to_zero ? 0.0 : seekable_end); |
| 795 return blink::WebTimeRanges(&seekable_range, 1); | 797 return blink::WebTimeRanges(&seekable_range, 1); |
| 796 } | 798 } |
| 797 | 799 |
| 800 bool WebMediaPlayerImpl::IsPrerollAttemptNeeded() { | |
| 801 // TODO(sandersd): Replace with |highest_ready_state_since_seek_| if we need | |
| 802 // to ensure that preroll always gets a chance to complete. | |
| 803 // See http://crbug.com/671525. | |
| 804 if (highest_ready_state_ >= ReadyState::ReadyStateHaveFutureData) | |
| 805 return false; | |
| 806 | |
| 807 if (preroll_attempt_pending_) | |
| 808 return true; | |
| 809 | |
| 810 // Freshly initialized; there has never been any loading progress. (Otherwise | |
| 811 // |preroll_attempt_pending_| would be true when the start time is null.) | |
| 812 if (preroll_attempt_start_time_.is_null()) | |
| 813 return false; | |
| 814 | |
| 815 base::TimeDelta preroll_attempt_duration = | |
| 816 tick_clock_->NowTicks() - preroll_attempt_start_time_; | |
| 817 return preroll_attempt_duration < kPrerollAttemptTimeout; | |
| 818 } | |
| 819 | |
| 798 bool WebMediaPlayerImpl::didLoadingProgress() { | 820 bool WebMediaPlayerImpl::didLoadingProgress() { |
| 799 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 821 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 800 | 822 |
| 801 // Note: Separate variables used to ensure both methods are called every time. | 823 // Note: Separate variables used to ensure both methods are called every time. |
| 802 const bool pipeline_progress = pipeline_.DidLoadingProgress(); | 824 const bool pipeline_progress = pipeline_.DidLoadingProgress(); |
| 803 const bool data_progress = buffered_data_source_host_.DidLoadingProgress(); | 825 const bool data_progress = buffered_data_source_host_.DidLoadingProgress(); |
| 804 const bool did_loading_progress = pipeline_progress || data_progress; | 826 const bool did_loading_progress = pipeline_progress || data_progress; |
| 805 | 827 |
| 806 // If we've idle suspended before reaching kHaveFutureData and loading has | 828 if (did_loading_progress && |
| 807 // progressed we need to spin up the renderer and figure out if we have enough | 829 highest_ready_state_ < ReadyState::ReadyStateHaveFutureData) { |
| 808 // data yet; |client_| may be waiting on this signal to trigger playback. The | 830 // Reset the preroll attempt clock. |
| 809 // idle timeout is long enough that this is a low-cost operation. | 831 preroll_attempt_pending_ = true; |
| 810 if (highest_ready_state_ < ReadyState::ReadyStateHaveFutureData && | 832 preroll_attempt_start_time_ = base::TimeTicks(); |
| 811 pipeline_controller_.IsSuspended() && did_loading_progress && is_idle_) { | 833 |
| 812 is_idle_ = false; | 834 // Clear any 'stale' flag and give the pipeline a chance to resume. If we |
| 835 // are already resumed, this will cause |preroll_attempt_start_time_| to be | |
| 836 // set. | |
| 837 // TODO(sandersd): Should this be on the same stack? It might be surprising | |
| 838 // that didLoadingProgress() can synchronously change state. | |
| 839 if (delegate_) | |
| 840 delegate_->ClearStaleFlag(delegate_id_); | |
| 813 UpdatePlayState(); | 841 UpdatePlayState(); |
| 814 } | 842 } |
| 815 | 843 |
| 816 if (did_loading_progress) | |
| 817 last_time_loading_progressed_ = tick_clock_->NowTicks(); | |
| 818 | |
| 819 return did_loading_progress; | 844 return did_loading_progress; |
| 820 } | 845 } |
| 821 | 846 |
| 822 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, | 847 void WebMediaPlayerImpl::paint(blink::WebCanvas* canvas, |
| 823 const blink::WebRect& rect, | 848 const blink::WebRect& rect, |
| 824 SkPaint& paint) { | 849 SkPaint& paint) { |
| 825 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 850 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 826 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); | 851 TRACE_EVENT0("media", "WebMediaPlayerImpl:paint"); |
| 827 | 852 |
| 828 // TODO(sandersd): Move this check into GetCurrentFrameFromCompositor() when | 853 // TODO(sandersd): Move this check into GetCurrentFrameFromCompositor() when |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 // TODO(chcunningham): Monitor playback position vs buffered. Potentially | 1234 // TODO(chcunningham): Monitor playback position vs buffered. Potentially |
| 1210 // transition to HAVE_FUTURE_DATA here if not enough is buffered. | 1235 // transition to HAVE_FUTURE_DATA here if not enough is buffered. |
| 1211 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); | 1236 SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); |
| 1212 | 1237 |
| 1213 // Let the DataSource know we have enough data. It may use this information | 1238 // Let the DataSource know we have enough data. It may use this information |
| 1214 // to release unused network connections. | 1239 // to release unused network connections. |
| 1215 if (data_source_) | 1240 if (data_source_) |
| 1216 data_source_->OnBufferingHaveEnough(false); | 1241 data_source_->OnBufferingHaveEnough(false); |
| 1217 | 1242 |
| 1218 // Blink expects a timeChanged() in response to a seek(). | 1243 // Blink expects a timeChanged() in response to a seek(). |
| 1219 if (should_notify_time_changed_) | 1244 if (should_notify_time_changed_) { |
| 1245 should_notify_time_changed_ = false; | |
| 1220 client_->timeChanged(); | 1246 client_->timeChanged(); |
| 1247 } | |
| 1221 | 1248 |
| 1222 // Once we have enough, start reporting the total memory usage. We'll also | 1249 // Once we have enough, start reporting the total memory usage. We'll also |
| 1223 // report once playback starts. | 1250 // report once playback starts. |
| 1224 ReportMemoryUsage(); | 1251 ReportMemoryUsage(); |
| 1225 | 1252 |
| 1226 // Report the amount of time it took to leave the underflow state. Don't | 1253 // Report the amount of time it took to leave the underflow state. Don't |
| 1227 // bother to report this for MSE playbacks since it's out of our control. | 1254 // bother to report this for MSE playbacks since it's out of our control. |
| 1228 if (underflow_timer_ && data_source_) { | 1255 if (underflow_timer_ && data_source_) { |
| 1229 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", | 1256 UMA_HISTOGRAM_TIMES("Media.UnderflowDuration", |
| 1230 underflow_timer_->Elapsed()); | 1257 underflow_timer_->Elapsed()); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1326 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1353 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1327 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); | 1354 DCHECK_NE(ready_state_, WebMediaPlayer::ReadyStateHaveNothing); |
| 1328 | 1355 |
| 1329 opaque_ = opaque; | 1356 opaque_ = opaque; |
| 1330 // Modify content opaqueness of cc::Layer directly so that | 1357 // Modify content opaqueness of cc::Layer directly so that |
| 1331 // SetContentsOpaqueIsFixed is ignored. | 1358 // SetContentsOpaqueIsFixed is ignored. |
| 1332 if (video_weblayer_) | 1359 if (video_weblayer_) |
| 1333 video_weblayer_->layer()->SetContentsOpaque(opaque_); | 1360 video_weblayer_->layer()->SetContentsOpaque(opaque_); |
| 1334 } | 1361 } |
| 1335 | 1362 |
| 1336 void WebMediaPlayerImpl::OnHidden() { | 1363 void WebMediaPlayerImpl::OnFrameHidden() { |
|
whywhat
2017/01/06 17:18:52
nit: Following discussion with Dale around naming
sandersd (OOO until July 31)
2017/01/06 23:08:35
I think I prefer to keep these names, since they a
DaleCurtis
2017/01/07 00:31:03
Saving the rename for later sgtm.
| |
| 1337 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1364 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1338 | 1365 |
| 1339 if (IsBackgroundVideoTrackOptimizationEnabled()) | 1366 if (IsBackgroundVideoTrackOptimizationEnabled()) |
| 1340 selectedVideoTrackChanged(nullptr); | 1367 selectedVideoTrackChanged(nullptr); |
| 1341 | 1368 |
| 1342 if (watch_time_reporter_) | 1369 if (watch_time_reporter_) |
| 1343 watch_time_reporter_->OnHidden(); | 1370 watch_time_reporter_->OnHidden(); |
| 1344 | 1371 |
| 1345 UpdatePlayState(); | 1372 UpdatePlayState(); |
| 1346 | 1373 |
| 1347 // Schedule suspended playing media to be paused if the user doesn't come back | 1374 // Schedule suspended playing media to be paused if the user doesn't come back |
| 1348 // to it within some timeout period to avoid any autoplay surprises. | 1375 // to it within some timeout period to avoid any autoplay surprises. |
| 1349 ScheduleIdlePauseTimer(); | 1376 ScheduleIdlePauseTimer(); |
| 1350 } | 1377 } |
| 1351 | 1378 |
| 1352 void WebMediaPlayerImpl::OnShown() { | 1379 void WebMediaPlayerImpl::OnFrameClosed() { |
| 1353 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1380 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1381 UpdatePlayState(); | |
| 1382 } | |
| 1383 | |
| 1384 void WebMediaPlayerImpl::OnFrameShown() { | |
| 1385 DCHECK(main_task_runner_->BelongsToCurrentThread()); | |
| 1386 background_pause_timer_.Stop(); | |
| 1387 | |
| 1354 if (watch_time_reporter_) | 1388 if (watch_time_reporter_) |
| 1355 watch_time_reporter_->OnShown(); | 1389 watch_time_reporter_->OnShown(); |
| 1356 | 1390 |
| 1357 if (IsBackgroundVideoTrackOptimizationEnabled() && | 1391 if (IsBackgroundVideoTrackOptimizationEnabled() && |
| 1358 client_->hasSelectedVideoTrack()) { | 1392 client_->hasSelectedVideoTrack()) { |
| 1359 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); | 1393 WebMediaPlayer::TrackId trackId = client_->getSelectedVideoTrackId(); |
| 1360 selectedVideoTrackChanged(&trackId); | 1394 selectedVideoTrackChanged(&trackId); |
| 1361 } | 1395 } |
| 1362 | 1396 |
| 1363 must_suspend_ = false; | |
| 1364 background_pause_timer_.Stop(); | |
| 1365 | |
| 1366 UpdatePlayState(); | 1397 UpdatePlayState(); |
| 1367 } | 1398 } |
| 1368 | 1399 |
| 1369 bool WebMediaPlayerImpl::OnSuspendRequested(bool must_suspend) { | 1400 void WebMediaPlayerImpl::OnIdleTimeout() { |
| 1370 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1401 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1371 | 1402 |
| 1372 if (must_suspend) { | 1403 // If we are attempting preroll, clear the stale flag. |
| 1373 must_suspend_ = true; | 1404 if (IsPrerollAttemptNeeded()) { |
| 1374 UpdatePlayState(); | 1405 if (delegate_) |
| 1375 return true; | 1406 delegate_->ClearStaleFlag(delegate_id_); |
| 1407 return; | |
| 1376 } | 1408 } |
| 1377 | 1409 |
| 1378 // If we're beyond HaveFutureData, we can safely suspend at any time. | 1410 UpdatePlayState(); |
| 1379 if (highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData) { | |
| 1380 is_idle_ = true; | |
| 1381 UpdatePlayState(); | |
| 1382 return true; | |
| 1383 } | |
| 1384 | |
| 1385 // Before HaveFutureData blink will not call play(), so we must be careful to | |
| 1386 // only suspend if we'll eventually receive an event that will trigger a | |
| 1387 // resume. If the last time loading progressed was a while ago, and we still | |
| 1388 // haven't reached HaveFutureData, we assume that we're waiting on more data | |
| 1389 // to continue pre-rolling. When that data is loaded the pipeline will be | |
| 1390 // resumed by didLoadingProgress(). | |
| 1391 if (last_time_loading_progressed_.is_null() || | |
| 1392 (tick_clock_->NowTicks() - last_time_loading_progressed_) > | |
| 1393 kLoadingToIdleTimeout) { | |
| 1394 is_idle_ = true; | |
| 1395 UpdatePlayState(); | |
| 1396 return true; | |
| 1397 } | |
| 1398 | |
| 1399 return false; | |
| 1400 } | 1411 } |
| 1401 | 1412 |
| 1402 void WebMediaPlayerImpl::OnPlay() { | 1413 void WebMediaPlayerImpl::OnPlay() { |
| 1403 play(); | 1414 play(); |
| 1404 client_->playbackStateChanged(); | 1415 client_->playbackStateChanged(); |
| 1405 } | 1416 } |
| 1406 | 1417 |
| 1407 void WebMediaPlayerImpl::OnPause() { | 1418 void WebMediaPlayerImpl::OnPause() { |
| 1408 pause(); | 1419 pause(); |
| 1409 client_->playbackStateChanged(); | 1420 client_->playbackStateChanged(); |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1737 bool is_streaming = false; | 1748 bool is_streaming = false; |
| 1738 #else | 1749 #else |
| 1739 bool is_remote = false; | 1750 bool is_remote = false; |
| 1740 bool is_streaming = data_source_ && data_source_->IsStreaming(); | 1751 bool is_streaming = data_source_ && data_source_->IsStreaming(); |
| 1741 #endif | 1752 #endif |
| 1742 | 1753 |
| 1743 bool is_suspended = pipeline_controller_.IsSuspended(); | 1754 bool is_suspended = pipeline_controller_.IsSuspended(); |
| 1744 bool is_backgrounded = IsBackgroundedSuspendEnabled() && IsHidden(); | 1755 bool is_backgrounded = IsBackgroundedSuspendEnabled() && IsHidden(); |
| 1745 PlayState state = UpdatePlayState_ComputePlayState( | 1756 PlayState state = UpdatePlayState_ComputePlayState( |
| 1746 is_remote, is_streaming, is_suspended, is_backgrounded); | 1757 is_remote, is_streaming, is_suspended, is_backgrounded); |
| 1747 SetDelegateState(state.delegate_state); | 1758 SetDelegateState(state.delegate_state, state.is_idle); |
| 1748 SetMemoryReportingState(state.is_memory_reporting_enabled); | 1759 SetMemoryReportingState(state.is_memory_reporting_enabled); |
| 1749 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); | 1760 SetSuspendState(state.is_suspended || pending_suspend_resume_cycle_); |
| 1750 } | 1761 } |
| 1751 | 1762 |
| 1752 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state) { | 1763 void WebMediaPlayerImpl::SetDelegateState(DelegateState new_state, |
| 1764 bool is_idle) { | |
| 1753 if (!delegate_) | 1765 if (!delegate_) |
| 1754 return; | 1766 return; |
| 1755 | 1767 |
| 1756 if (delegate_state_ == new_state) { | 1768 switch (new_state) { |
| 1757 if (delegate_state_ != DelegateState::PLAYING || | |
| 1758 autoplay_muted_ == client_->isAutoplayingMuted()) { | |
| 1759 return; | |
| 1760 } | |
| 1761 } | |
| 1762 | |
| 1763 delegate_state_ = new_state; | |
| 1764 | |
| 1765 switch (delegate_state_) { | |
| 1766 case DelegateState::GONE: | 1769 case DelegateState::GONE: |
| 1767 delegate_->PlayerGone(delegate_id_); | 1770 delegate_->PlayerGone(delegate_id_); |
| 1768 break; | 1771 break; |
| 1769 case DelegateState::PLAYING: { | 1772 case DelegateState::PLAYING: { |
| 1770 autoplay_muted_ = client_->isAutoplayingMuted(); | 1773 bool has_audio = hasAudio() && !client_->isAutoplayingMuted(); |
| 1771 bool has_audio = autoplay_muted_ ? false : hasAudio(); | |
| 1772 delegate_->DidPlay( | 1774 delegate_->DidPlay( |
| 1773 delegate_id_, hasVideo(), has_audio, false, | 1775 delegate_id_, has_audio, hasVideo(), |
| 1774 media::DurationToMediaContentType(pipeline_.GetMediaDuration())); | 1776 media::DurationToMediaContentType(pipeline_.GetMediaDuration())); |
| 1775 break; | 1777 break; |
| 1776 } | 1778 } |
| 1777 case DelegateState::PAUSED: | 1779 case DelegateState::PAUSED: |
| 1778 delegate_->DidPause(delegate_id_, false); | 1780 delegate_->DidPause(delegate_id_); |
| 1779 break; | |
| 1780 case DelegateState::ENDED: | |
| 1781 delegate_->DidPause(delegate_id_, true); | |
| 1782 break; | 1781 break; |
| 1783 } | 1782 } |
| 1783 | |
| 1784 delegate_->SetIdle(delegate_id_, is_idle); | |
| 1784 } | 1785 } |
| 1785 | 1786 |
| 1786 void WebMediaPlayerImpl::SetMemoryReportingState( | 1787 void WebMediaPlayerImpl::SetMemoryReportingState( |
| 1787 bool is_memory_reporting_enabled) { | 1788 bool is_memory_reporting_enabled) { |
| 1788 if (memory_usage_reporting_timer_.IsRunning() == | 1789 if (memory_usage_reporting_timer_.IsRunning() == |
| 1789 is_memory_reporting_enabled) { | 1790 is_memory_reporting_enabled) { |
| 1790 return; | 1791 return; |
| 1791 } | 1792 } |
| 1792 | 1793 |
| 1793 if (is_memory_reporting_enabled) { | 1794 if (is_memory_reporting_enabled) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1819 can_suspend_state_ = | 1820 can_suspend_state_ = |
| 1820 frame->metadata()->IsTrue(VideoFrameMetadata::DECODER_OWNS_FRAME) | 1821 frame->metadata()->IsTrue(VideoFrameMetadata::DECODER_OWNS_FRAME) |
| 1821 ? CanSuspendState::NO | 1822 ? CanSuspendState::NO |
| 1822 : CanSuspendState::YES; | 1823 : CanSuspendState::YES; |
| 1823 } | 1824 } |
| 1824 } | 1825 } |
| 1825 #else | 1826 #else |
| 1826 can_suspend_state_ = CanSuspendState::YES; | 1827 can_suspend_state_ = CanSuspendState::YES; |
| 1827 #endif | 1828 #endif |
| 1828 | 1829 |
| 1829 if (can_suspend_state_ == CanSuspendState::NO) | 1830 if (is_suspended && can_suspend_state_ != CanSuspendState::NO) { |
| 1830 return; | 1831 // If we were not resumed for long enough to satisfy the preroll attempt, |
| 1831 | 1832 // reset the clock. |
| 1832 if (is_suspended) { | 1833 if (!preroll_attempt_pending_ && IsPrerollAttemptNeeded()) { |
| 1834 preroll_attempt_pending_ = true; | |
| 1835 preroll_attempt_start_time_ = base::TimeTicks(); | |
| 1836 } | |
| 1833 pipeline_controller_.Suspend(); | 1837 pipeline_controller_.Suspend(); |
| 1834 } else { | 1838 } else { |
| 1839 // When resuming, start the preroll attempt clock. | |
| 1840 if (preroll_attempt_pending_) { | |
| 1841 preroll_attempt_pending_ = false; | |
| 1842 preroll_attempt_start_time_ = tick_clock_->NowTicks(); | |
| 1843 } | |
| 1835 pipeline_controller_.Resume(); | 1844 pipeline_controller_.Resume(); |
| 1836 } | 1845 } |
| 1837 } | 1846 } |
| 1838 | 1847 |
| 1839 WebMediaPlayerImpl::PlayState | 1848 WebMediaPlayerImpl::PlayState |
| 1840 WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote, | 1849 WebMediaPlayerImpl::UpdatePlayState_ComputePlayState(bool is_remote, |
| 1841 bool is_streaming, | 1850 bool is_streaming, |
| 1842 bool is_suspended, | 1851 bool is_suspended, |
| 1843 bool is_backgrounded) { | 1852 bool is_backgrounded) { |
| 1844 PlayState result; | 1853 PlayState result; |
| 1845 | 1854 |
| 1855 bool must_suspend = delegate_ && delegate_->IsFrameClosed(); | |
| 1856 bool is_stale = delegate_ && delegate_->IsStale(delegate_id_); | |
| 1857 | |
| 1846 // This includes both data source (before pipeline startup) and pipeline | 1858 // This includes both data source (before pipeline startup) and pipeline |
| 1847 // errors. | 1859 // errors. |
| 1848 bool has_error = IsNetworkStateError(network_state_); | 1860 bool has_error = IsNetworkStateError(network_state_); |
| 1849 | 1861 |
| 1850 // After HaveMetadata, we know which tracks are present and the duration. | 1862 // After HaveMetadata, we know which tracks are present and the duration. |
| 1851 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata; | 1863 bool have_metadata = ready_state_ >= WebMediaPlayer::ReadyStateHaveMetadata; |
| 1852 | 1864 |
| 1853 // After HaveFutureData, Blink will call play() if the state is not paused; | 1865 // After HaveFutureData, Blink will call play() if the state is not paused; |
| 1854 // prior to this point |paused_| is not accurate. | 1866 // prior to this point |paused_| is not accurate. |
| 1855 bool have_future_data = | 1867 bool have_future_data = |
| 1856 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; | 1868 highest_ready_state_ >= WebMediaPlayer::ReadyStateHaveFutureData; |
| 1857 | 1869 |
| 1858 // Background suspend is not enabled for audio-only players unless paused, | 1870 // Background suspend is not enabled for audio-only players unless paused, |
| 1859 // though in the case of audio-only the session should be kept. | 1871 // though in the case of audio-only the session should be kept. |
| 1860 // Videos are not suspended if the user resumed the playback via the remote | 1872 // Videos are not suspended if the user resumed the playback via the remote |
| 1861 // controls earlier and it's still playing. | 1873 // controls earlier and it's still playing. |
| 1862 bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo(); | 1874 bool is_backgrounded_video = is_backgrounded && have_metadata && hasVideo(); |
| 1863 bool can_play_backgrounded = is_backgrounded_video && !is_remote && | 1875 bool can_play_backgrounded = is_backgrounded_video && !is_remote && |
| 1864 hasAudio() && IsResumeBackgroundVideosEnabled(); | 1876 hasAudio() && IsResumeBackgroundVideosEnabled(); |
| 1865 bool is_background_playing = | 1877 bool is_background_playing = |
| 1866 delegate_ && delegate_->IsPlayingBackgroundVideo(); | 1878 delegate_ && delegate_->IsBackgroundVideoPlaybackAllowed(); |
|
whywhat
2017/01/06 17:18:51
nit: I'm a bit concerned that IsBgVideoPlaybackAll
sandersd (OOO until July 31)
2017/01/06 23:08:35
Done.
| |
| 1867 bool background_suspended = !is_streaming && is_backgrounded_video && | 1879 bool background_suspended = !is_streaming && is_backgrounded_video && |
| 1868 !(can_play_backgrounded && is_background_playing); | 1880 !(can_play_backgrounded && is_background_playing); |
| 1869 bool background_pause_suspended = | 1881 bool background_pause_suspended = |
| 1870 !is_streaming && is_backgrounded && paused_ && have_future_data; | 1882 !is_streaming && is_backgrounded && paused_ && have_future_data; |
| 1871 | 1883 |
| 1872 // Idle suspension is allowed prior to have future data since there exist | 1884 // Idle suspension is allowed prior to have future data since there exist |
| 1873 // mechanisms to exit the idle state when the player is capable of reaching | 1885 // mechanisms to exit the idle state when the player is capable of reaching |
| 1874 // the have future data state; see didLoadingProgress(). | 1886 // the have future data state; see didLoadingProgress(). |
| 1875 // | 1887 // |
| 1876 // TODO(sandersd): Make the delegate suspend idle players immediately when | 1888 // TODO(sandersd): Make the delegate suspend idle players immediately when |
| 1877 // hidden. | 1889 // hidden. |
| 1878 bool idle_suspended = | 1890 bool idle_suspended = |
| 1879 !is_streaming && is_idle_ && paused_ && !seeking_ && !overlay_enabled_; | 1891 !is_streaming && is_stale && paused_ && !seeking_ && !overlay_enabled_; |
| 1880 | 1892 |
| 1881 // If we're already suspended, see if we can wait for user interaction. Prior | 1893 // If we're already suspended, see if we can wait for user interaction. Prior |
| 1882 // to HaveFutureData, we require |is_idle_| to remain suspended. |is_idle_| | 1894 // to HaveFutureData, we require |is_stale| to remain suspended. |is_stale| |
| 1883 // will be cleared when we receive data which may take us to HaveFutureData. | 1895 // will be cleared when we receive data which may take us to HaveFutureData. |
| 1884 bool can_stay_suspended = | 1896 bool can_stay_suspended = |
| 1885 (is_idle_ || have_future_data) && is_suspended && paused_ && !seeking_; | 1897 (is_stale || have_future_data) && is_suspended && paused_ && !seeking_; |
| 1886 | 1898 |
| 1887 // Combined suspend state. | 1899 // Combined suspend state. |
| 1888 result.is_suspended = is_remote || must_suspend_ || idle_suspended || | 1900 result.is_suspended = is_remote || must_suspend || idle_suspended || |
| 1889 background_suspended || background_pause_suspended || | 1901 background_suspended || background_pause_suspended || |
| 1890 can_stay_suspended; | 1902 can_stay_suspended; |
| 1891 | 1903 |
| 1892 // We do not treat |playback_rate_| == 0 as paused. For the media session, | 1904 // We do not treat |playback_rate_| == 0 as paused. For the media session, |
| 1893 // being paused implies displaying a play button, which is incorrect in this | 1905 // being paused implies displaying a play button, which is incorrect in this |
| 1894 // case. For memory usage reporting, we just use the same definition (but we | 1906 // case. For memory usage reporting, we just use the same definition (but we |
| 1895 // don't have to). | 1907 // don't have to). |
| 1896 // | 1908 // |
| 1897 // Similarly, we don't consider |ended_| to be paused. Blink will immediately | 1909 // Similarly, we don't consider |ended_| to be paused. Blink will immediately |
| 1898 // call pause() or seek(), so |ended_| should not affect the computation. | 1910 // call pause() or seek(), so |ended_| should not affect the computation. |
| 1899 // Despite that, |ended_| does result in a separate paused state, to simplfy | 1911 // Despite that, |ended_| does result in a separate paused state, to simplfy |
| 1900 // the contract for SetDelegateState(). | 1912 // the contract for SetDelegateState(). |
| 1901 // | 1913 // |
| 1902 // |has_session| is used to decide when to create a media session. Idle | 1914 // |has_session| is used to decide when to create a media session. Idle |
| 1903 // suspension does not destroy the media session, because we expect that the | 1915 // suspension does not destroy the media session, because we expect that the |
| 1904 // notification controls (and audio focus) remain. We also require: | 1916 // notification controls (and audio focus) remain. We also require: |
| 1905 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). | 1917 // - |have_metadata|, since the tracks and duration are passed to DidPlay(). |
| 1906 // - |have_future_data|, since we need to know whether we are paused to | 1918 // - |have_future_data|, since we need to know whether we are paused to |
| 1907 // correctly configure the session. | 1919 // correctly configure the session. |
| 1908 // | 1920 // |
| 1909 // TODO(sandersd): If Blink told us the paused state sooner, we could create | 1921 // TODO(sandersd): If Blink told us the paused state sooner, we could create |
| 1910 // the media session sooner. | 1922 // the media session sooner. |
| 1911 bool can_play = !has_error && !is_remote && have_future_data; | 1923 bool can_play = !has_error && !is_remote && have_future_data; |
| 1912 bool has_session_playing = | 1924 bool has_session_playing = can_play && !must_suspend && !background_suspended; |
| 1913 can_play && !must_suspend_ && !background_suspended; | |
| 1914 | 1925 |
| 1915 // |has_session_suspended| means the player is suspended from the media | 1926 // |has_session_suspended| means the player is suspended from the media |
| 1916 // element point of view but paused and can be resumed from the delegate point | 1927 // element point of view but paused and can be resumed from the delegate point |
| 1917 // of view. Therefore it behaves like |paused_| for the delegate. | 1928 // of view. Therefore it behaves like |paused_| for the delegate. |
| 1918 bool has_session_suspended = can_play && !must_suspend_ && | 1929 bool has_session_suspended = can_play && !must_suspend && |
| 1919 background_suspended && can_play_backgrounded; | 1930 background_suspended && can_play_backgrounded; |
| 1920 | 1931 |
| 1921 bool has_session = has_session_playing || has_session_suspended; | 1932 bool has_session = has_session_playing || has_session_suspended; |
| 1922 | 1933 |
| 1923 if (!has_session) { | 1934 if (!has_session) { |
| 1924 result.delegate_state = DelegateState::GONE; | 1935 result.delegate_state = DelegateState::GONE; |
| 1936 result.is_idle = delegate_ && delegate_->IsIdle(delegate_id_); | |
| 1925 } else if (paused_ || has_session_suspended) { | 1937 } else if (paused_ || has_session_suspended) { |
| 1938 // TODO(sandersd): Is it possible to have a suspended session, be ended, | |
| 1939 // and not be paused? If so we should be in a PLAYING state. | |
| 1926 result.delegate_state = | 1940 result.delegate_state = |
| 1927 ended_ ? DelegateState::ENDED : DelegateState::PAUSED; | 1941 ended_ ? DelegateState::GONE : DelegateState::PAUSED; |
| 1942 result.is_idle = !seeking_; | |
| 1928 } else { | 1943 } else { |
| 1929 result.delegate_state = DelegateState::PLAYING; | 1944 result.delegate_state = DelegateState::PLAYING; |
| 1945 result.is_idle = false; | |
| 1930 } | 1946 } |
| 1931 | 1947 |
| 1932 // It's not critical if some cases where memory usage can change are missed, | 1948 // It's not critical if some cases where memory usage can change are missed, |
| 1933 // since media memory changes are usually gradual. | 1949 // since media memory changes are usually gradual. |
| 1934 result.is_memory_reporting_enabled = | 1950 result.is_memory_reporting_enabled = |
| 1935 can_play && !result.is_suspended && !paused_; | 1951 can_play && !result.is_suspended && (!paused_ || seeking_); |
| 1936 | 1952 |
| 1937 return result; | 1953 return result; |
| 1938 } | 1954 } |
| 1939 | 1955 |
| 1940 void WebMediaPlayerImpl::ReportMemoryUsage() { | 1956 void WebMediaPlayerImpl::ReportMemoryUsage() { |
| 1941 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1957 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1942 | 1958 |
| 1943 // About base::Unretained() usage below: We destroy |demuxer_| on the main | 1959 // About base::Unretained() usage below: We destroy |demuxer_| on the main |
| 1944 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the | 1960 // thread. Before that, however, ~WebMediaPlayerImpl() posts a task to the |
| 1945 // media thread and waits for it to finish. Hence, the GetMemoryUsage() task | 1961 // media thread and waits for it to finish. Hence, the GetMemoryUsage() task |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2011 this, &WebMediaPlayerImpl::OnPause); | 2027 this, &WebMediaPlayerImpl::OnPause); |
| 2012 } | 2028 } |
| 2013 | 2029 |
| 2014 void WebMediaPlayerImpl::CreateWatchTimeReporter() { | 2030 void WebMediaPlayerImpl::CreateWatchTimeReporter() { |
| 2015 // Create the watch time reporter and synchronize its initial state. | 2031 // Create the watch time reporter and synchronize its initial state. |
| 2016 watch_time_reporter_.reset(new WatchTimeReporter( | 2032 watch_time_reporter_.reset(new WatchTimeReporter( |
| 2017 hasAudio(), hasVideo(), !!chunk_demuxer_, is_encrypted_, media_log_, | 2033 hasAudio(), hasVideo(), !!chunk_demuxer_, is_encrypted_, media_log_, |
| 2018 pipeline_metadata_.natural_size, | 2034 pipeline_metadata_.natural_size, |
| 2019 base::Bind(&GetCurrentTimeInternal, this))); | 2035 base::Bind(&GetCurrentTimeInternal, this))); |
| 2020 watch_time_reporter_->OnVolumeChange(volume_); | 2036 watch_time_reporter_->OnVolumeChange(volume_); |
| 2021 if (IsHidden()) | 2037 if (delegate_ && delegate_->IsFrameHidden()) |
| 2022 watch_time_reporter_->OnHidden(); | 2038 watch_time_reporter_->OnHidden(); |
| 2023 else | 2039 else |
| 2024 watch_time_reporter_->OnShown(); | 2040 watch_time_reporter_->OnShown(); |
| 2025 } | 2041 } |
| 2026 | 2042 |
| 2027 bool WebMediaPlayerImpl::IsHidden() const { | 2043 bool WebMediaPlayerImpl::IsHidden() const { |
| 2028 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2044 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 2029 | 2045 |
| 2030 return delegate_ && delegate_->IsHidden(); | 2046 return delegate_ && delegate_->IsFrameHidden() && !delegate_->IsFrameClosed(); |
| 2031 } | 2047 } |
| 2032 | 2048 |
| 2033 bool WebMediaPlayerImpl::DoesOverlaySupportMetadata() const { | 2049 bool WebMediaPlayerImpl::DoesOverlaySupportMetadata() const { |
| 2034 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; | 2050 return pipeline_metadata_.video_rotation == VIDEO_ROTATION_0; |
| 2035 } | 2051 } |
| 2036 | 2052 |
| 2037 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { | 2053 void WebMediaPlayerImpl::ActivateViewportIntersectionMonitoring(bool activate) { |
| 2038 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 2054 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 2039 | 2055 |
| 2040 client_->activateViewportIntersectionMonitoring(activate); | 2056 client_->activateViewportIntersectionMonitoring(activate); |
| 2041 } | 2057 } |
| 2042 | 2058 |
| 2043 } // namespace media | 2059 } // namespace media |
| OLD | NEW |