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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 observer_(params->media_observer()), | 244 observer_(params->media_observer()), |
| 245 max_keyframe_distance_to_disable_background_video_( | 245 max_keyframe_distance_to_disable_background_video_( |
| 246 params->max_keyframe_distance_to_disable_background_video()), | 246 params->max_keyframe_distance_to_disable_background_video()), |
| 247 max_keyframe_distance_to_disable_background_video_mse_( | 247 max_keyframe_distance_to_disable_background_video_mse_( |
| 248 params->max_keyframe_distance_to_disable_background_video_mse()), | 248 params->max_keyframe_distance_to_disable_background_video_mse()), |
| 249 enable_instant_source_buffer_gc_( | 249 enable_instant_source_buffer_gc_( |
| 250 params->enable_instant_source_buffer_gc()), | 250 params->enable_instant_source_buffer_gc()), |
| 251 embedded_media_experience_enabled_( | 251 embedded_media_experience_enabled_( |
| 252 params->embedded_media_experience_enabled()), | 252 params->embedded_media_experience_enabled()), |
| 253 request_routing_token_cb_(params->request_routing_token_cb()), | 253 request_routing_token_cb_(params->request_routing_token_cb()), |
| 254 overlay_routing_token_(base::UnguessableToken()) { | 254 overlay_routing_token_( |
| 255 OverlayInfo::RoutingToken(base::UnguessableToken())) { | |
|
watk
2017/05/25 18:09:36
Shouldn't this be a nullopt RoutingToken? I don't
liberato (no reviews please)
2017/05/25 21:26:56
it should be ort_(RoutingToken()), which means "we
| |
| 255 DVLOG(1) << __func__; | 256 DVLOG(1) << __func__; |
| 256 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 257 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 257 DCHECK(renderer_factory_selector_); | 258 DCHECK(renderer_factory_selector_); |
| 258 DCHECK(client_); | 259 DCHECK(client_); |
| 259 DCHECK(delegate_); | 260 DCHECK(delegate_); |
| 260 | 261 |
| 261 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 262 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 262 switches::kForceVideoOverlays); | 263 switches::kForceVideoOverlays); |
| 263 | 264 |
| 264 if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo)) { | 265 if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo)) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 ScheduleRestart(); | 372 ScheduleRestart(); |
| 372 } | 373 } |
| 373 | 374 |
| 374 void WebMediaPlayerImpl::DisableOverlay() { | 375 void WebMediaPlayerImpl::DisableOverlay() { |
| 375 overlay_enabled_ = false; | 376 overlay_enabled_ = false; |
| 376 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { | 377 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { |
| 377 surface_created_cb_.Cancel(); | 378 surface_created_cb_.Cancel(); |
| 378 overlay_surface_id_ = SurfaceManager::kNoSurfaceID; | 379 overlay_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 379 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { | 380 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { |
| 380 token_available_cb_.Cancel(); | 381 token_available_cb_.Cancel(); |
| 381 overlay_routing_token_ = base::UnguessableToken(); | 382 overlay_routing_token_ = |
| 383 OverlayInfo::RoutingToken(base::UnguessableToken()); | |
| 382 } | 384 } |
| 383 | 385 |
| 384 if (decoder_requires_restart_for_overlay_) | 386 if (decoder_requires_restart_for_overlay_) |
| 385 ScheduleRestart(); | 387 ScheduleRestart(); |
| 386 else | 388 else |
| 387 MaybeSendOverlayInfoToDecoder(); | 389 MaybeSendOverlayInfoToDecoder(true); |
| 388 } | 390 } |
| 389 | 391 |
| 390 void WebMediaPlayerImpl::EnteredFullscreen() { | 392 void WebMediaPlayerImpl::EnteredFullscreen() { |
| 391 // |force_video_overlays_| implies that we're already in overlay mode, so take | 393 // |force_video_overlays_| implies that we're already in overlay mode, so take |
| 392 // no action here. Otherwise, switch to an overlay if it's allowed and if | 394 // no action here. Otherwise, switch to an overlay if it's allowed and if |
| 393 // it will display properly. | 395 // it will display properly. |
| 396 is_fullscreen_ = true; | |
| 397 | |
| 394 if (!force_video_overlays_ && overlay_mode_ != OverlayMode::kNoOverlays && | 398 if (!force_video_overlays_ && overlay_mode_ != OverlayMode::kNoOverlays && |
| 395 DoesOverlaySupportMetadata()) { | 399 DoesOverlaySupportMetadata()) { |
| 396 EnableOverlay(); | 400 EnableOverlay(); |
| 397 } | 401 } |
| 398 if (observer_) | 402 if (observer_) |
| 399 observer_->OnEnteredFullscreen(); | 403 observer_->OnEnteredFullscreen(); |
| 400 | 404 |
| 401 // TODO(liberato): if the decoder provided a callback for fullscreen state, | 405 // We send this only if we can send multiple calls. Otherwise, either (a) |
| 402 // then notify it now. | 406 // we already sent it and we don't have a callback anyway (we reset it when |
| 407 // it's called in restart mode), or (b) we'll send this later when the surface | |
| 408 // actually arrives. GVD assumes that the first overlay info will have the | |
| 409 // routing information. Note that we set |is_fullscreen_| earlier, so that | |
| 410 // if EnableOverlay() can include fullscreen info in case it sends the overlay | |
| 411 // info before returning. | |
| 412 if (!decoder_requires_restart_for_overlay_) | |
| 413 MaybeSendOverlayInfoToDecoder(false); | |
| 403 } | 414 } |
| 404 | 415 |
| 405 void WebMediaPlayerImpl::ExitedFullscreen() { | 416 void WebMediaPlayerImpl::ExitedFullscreen() { |
| 406 // If we're in overlay mode, then exit it unless we're supposed to be in | 417 // If we're in overlay mode, then exit it unless we're supposed to be in |
| 407 // overlay mode all the time. | 418 // overlay mode all the time. |
|
watk
2017/05/25 18:09:36
Can you move this comment back to the if statement
liberato (no reviews please)
2017/05/25 21:26:56
Done.
| |
| 419 is_fullscreen_ = false; | |
| 420 | |
| 408 if (!force_video_overlays_ && overlay_enabled_) | 421 if (!force_video_overlays_ && overlay_enabled_) |
| 409 DisableOverlay(); | 422 DisableOverlay(); |
| 410 if (observer_) | 423 if (observer_) |
| 411 observer_->OnExitedFullscreen(); | 424 observer_->OnExitedFullscreen(); |
| 412 | 425 |
| 413 // TODO(liberato): if the decoder provided a callback for fullscreen state, | 426 // See EnteredFullscreen for why we do this. |
| 414 // then notify it now. | 427 if (!decoder_requires_restart_for_overlay_) |
| 428 MaybeSendOverlayInfoToDecoder(false); | |
| 415 } | 429 } |
| 416 | 430 |
| 417 void WebMediaPlayerImpl::BecameDominantVisibleContent(bool isDominant) { | 431 void WebMediaPlayerImpl::BecameDominantVisibleContent(bool isDominant) { |
| 418 if (observer_) | 432 if (observer_) |
| 419 observer_->OnBecameDominantVisibleContent(isDominant); | 433 observer_->OnBecameDominantVisibleContent(isDominant); |
| 420 } | 434 } |
| 421 | 435 |
| 422 void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( | 436 void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( |
| 423 bool isEffectivelyFullscreen) { | 437 bool isEffectivelyFullscreen) { |
| 424 delegate_->SetIsEffectivelyFullscreen(delegate_id_, isEffectivelyFullscreen); | 438 delegate_->SetIsEffectivelyFullscreen(delegate_id_, isEffectivelyFullscreen); |
| (...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1711 if (ready_state_ == ReadyState::kReadyStateHaveFutureData && !is_downloading) | 1725 if (ready_state_ == ReadyState::kReadyStateHaveFutureData && !is_downloading) |
| 1712 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); | 1726 SetReadyState(WebMediaPlayer::kReadyStateHaveEnoughData); |
| 1713 media_log_->AddEvent( | 1727 media_log_->AddEvent( |
| 1714 media_log_->CreateBooleanEvent(MediaLogEvent::NETWORK_ACTIVITY_SET, | 1728 media_log_->CreateBooleanEvent(MediaLogEvent::NETWORK_ACTIVITY_SET, |
| 1715 "is_downloading_data", is_downloading)); | 1729 "is_downloading_data", is_downloading)); |
| 1716 } | 1730 } |
| 1717 | 1731 |
| 1718 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { | 1732 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { |
| 1719 DCHECK(overlay_mode_ == OverlayMode::kUseContentVideoView); | 1733 DCHECK(overlay_mode_ == OverlayMode::kUseContentVideoView); |
| 1720 overlay_surface_id_ = surface_id; | 1734 overlay_surface_id_ = surface_id; |
| 1721 MaybeSendOverlayInfoToDecoder(); | 1735 MaybeSendOverlayInfoToDecoder(true); |
| 1722 } | 1736 } |
| 1723 | 1737 |
| 1724 void WebMediaPlayerImpl::OnOverlayRoutingToken( | 1738 void WebMediaPlayerImpl::OnOverlayRoutingToken( |
| 1725 const base::UnguessableToken& token) { | 1739 const base::UnguessableToken& token) { |
| 1726 DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay); | 1740 DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay); |
| 1727 overlay_routing_token_ = token; | 1741 // TODO(liberato): |token| should already be a RoutingToken. |
| 1728 MaybeSendOverlayInfoToDecoder(); | 1742 overlay_routing_token_ = OverlayInfo::RoutingToken(token); |
| 1743 MaybeSendOverlayInfoToDecoder(true); | |
| 1729 } | 1744 } |
| 1730 | 1745 |
| 1731 void WebMediaPlayerImpl::OnOverlayInfoRequested( | 1746 void WebMediaPlayerImpl::OnOverlayInfoRequested( |
| 1732 bool decoder_requires_restart_for_overlay, | 1747 bool decoder_requires_restart_for_overlay, |
| 1733 const ProvideOverlayInfoCB& provide_overlay_info_cb) { | 1748 const ProvideOverlayInfoCB& provide_overlay_info_cb) { |
| 1734 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1749 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1735 DCHECK(surface_manager_); | 1750 DCHECK(surface_manager_); |
| 1736 | 1751 |
| 1737 // A null callback indicates that the decoder is going away. | 1752 // A null callback indicates that the decoder is going away. |
| 1738 if (provide_overlay_info_cb.is_null()) { | 1753 if (provide_overlay_info_cb.is_null()) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1752 provide_overlay_info_cb_ = provide_overlay_info_cb; | 1767 provide_overlay_info_cb_ = provide_overlay_info_cb; |
| 1753 | 1768 |
| 1754 // If we're waiting for the surface to arrive, OnSurfaceCreated() will be | 1769 // If we're waiting for the surface to arrive, OnSurfaceCreated() will be |
| 1755 // called later when it arrives; so do nothing for now. For AndroidOverlay, | 1770 // called later when it arrives; so do nothing for now. For AndroidOverlay, |
| 1756 // if we're waiting for the token then... OnOverlayRoutingToken()... | 1771 // if we're waiting for the token then... OnOverlayRoutingToken()... |
| 1757 // We do this so that a request for a surface will block if we're in the | 1772 // We do this so that a request for a surface will block if we're in the |
| 1758 // process of getting one. Otherwise, on pre-M, the decoder would be stuck | 1773 // process of getting one. Otherwise, on pre-M, the decoder would be stuck |
| 1759 // without an overlay if the restart that happens on entering fullscreen | 1774 // without an overlay if the restart that happens on entering fullscreen |
| 1760 // succeeds before we have the overlay info. Post-M, we could send what we | 1775 // succeeds before we have the overlay info. Post-M, we could send what we |
| 1761 // have unconditionally. When the info arrives, it will be sent. | 1776 // have unconditionally. When the info arrives, it will be sent. |
| 1762 MaybeSendOverlayInfoToDecoder(); | 1777 MaybeSendOverlayInfoToDecoder(true); |
| 1763 } | 1778 } |
| 1764 | 1779 |
| 1765 void WebMediaPlayerImpl::MaybeSendOverlayInfoToDecoder() { | 1780 void WebMediaPlayerImpl::MaybeSendOverlayInfoToDecoder(bool send_factory_info) { |
| 1766 // If the decoder didn't request overlay info, then don't send it. | 1781 // If the decoder didn't request overlay info, then don't send it. |
| 1767 if (!provide_overlay_info_cb_) | 1782 if (!provide_overlay_info_cb_) |
| 1768 return; | 1783 return; |
| 1769 | 1784 |
| 1785 OverlayInfo overlay_info; | |
| 1786 | |
| 1770 // We should send the overlay info as long as we know it. This includes the | 1787 // We should send the overlay info as long as we know it. This includes the |
| 1771 // case where |!overlay_enabled_|, since we want to tell the decoder to avoid | 1788 // case where |!overlay_enabled_|, since we want to tell the decoder to avoid |
| 1772 // using overlays. Assuming that the decoder has requested info, the only | 1789 // using overlays. Assuming that the decoder has requested info, the only |
| 1773 // case in which we don't want to send something is if we've requested the | 1790 // case in which we don't want to send something is if we've requested the |
| 1774 // info but not received it yet. Then, we should wait until we do. | 1791 // info but not received it yet. Then, we should wait until we do. |
| 1792 // | |
| 1793 // Note that we exit early even if |!send_factory_info|; if we have a callback | |
| 1794 // pending, then we wait, so that we can send all of it at once. | |
| 1795 // Initialization requires this; AVDA should start with the factory info. In | |
| 1796 // non-init cases, it would probably be fine. | |
| 1775 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { | 1797 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { |
| 1776 if (!overlay_surface_id_.has_value()) | 1798 if (!overlay_surface_id_.has_value()) |
| 1777 return; | 1799 return; |
| 1800 | |
| 1801 if (send_factory_info) | |
| 1802 overlay_info.surface_id = *overlay_surface_id_; | |
| 1778 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { | 1803 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { |
| 1779 if (!overlay_routing_token_.has_value()) | 1804 if (!overlay_routing_token_.has_value()) |
| 1780 return; | 1805 return; |
| 1806 | |
| 1807 if (send_factory_info) | |
| 1808 overlay_info.routing_token = *overlay_routing_token_; | |
| 1781 } | 1809 } |
| 1782 | 1810 |
| 1783 // Note that we're guaranteed that both |overlay_surface_id_| and | 1811 overlay_info.is_fullscreen = is_fullscreen_; |
| 1784 // |overlay_routing_token_| have values, since both have values unless there | |
| 1785 // is a request pending. Nobody calls us if a request is pending. | |
| 1786 | |
| 1787 int surface_id = SurfaceManager::kNoSurfaceID; | |
| 1788 if (overlay_surface_id_) | |
| 1789 surface_id = *overlay_surface_id_; | |
| 1790 | |
| 1791 // Since we represent "no token" as a null UnguessableToken, we translate it | |
| 1792 // into an optional here. Alternatively, we could represent it as a | |
| 1793 // base::Optional in |overlay_routing_token_|, but then we'd have a | |
| 1794 // base::Optional<base::Optional<base::UnguessableToken> >. We don't do that | |
| 1795 // because... just because. | |
| 1796 base::Optional<base::UnguessableToken> routing_token; | |
| 1797 if (overlay_routing_token_.has_value() && !overlay_routing_token_->is_empty()) | |
| 1798 routing_token = *overlay_routing_token_; | |
| 1799 | 1812 |
| 1800 // If restart is required, the callback is one-shot only. | 1813 // If restart is required, the callback is one-shot only. |
| 1801 if (decoder_requires_restart_for_overlay_) { | 1814 if (decoder_requires_restart_for_overlay_) { |
| 1802 base::ResetAndReturn(&provide_overlay_info_cb_) | 1815 base::ResetAndReturn(&provide_overlay_info_cb_).Run(overlay_info); |
| 1803 .Run(surface_id, routing_token); | |
| 1804 } else { | 1816 } else { |
| 1805 provide_overlay_info_cb_.Run(surface_id, routing_token); | 1817 provide_overlay_info_cb_.Run(overlay_info); |
| 1806 } | 1818 } |
| 1807 } | 1819 } |
| 1808 | 1820 |
| 1809 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { | 1821 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { |
| 1810 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1822 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1811 | 1823 |
| 1812 // TODO(liberato): Re-evaluate this as AndroidVideoSurfaceChooser gets smarter | 1824 // TODO(liberato): Re-evaluate this as AndroidVideoSurfaceChooser gets smarter |
| 1813 // about turning off overlays. Either we should verify that it is not | 1825 // about turning off overlays. Either we should verify that it is not |
| 1814 // breaking this use-case if it does so, or we should notify it that using | 1826 // breaking this use-case if it does so, or we should notify it that using |
| 1815 // the overlay is required. | 1827 // the overlay is required. |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2511 } | 2523 } |
| 2512 | 2524 |
| 2513 #undef UMA_HISTOGRAM_VIDEO_HEIGHT | 2525 #undef UMA_HISTOGRAM_VIDEO_HEIGHT |
| 2514 | 2526 |
| 2515 void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { | 2527 void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { |
| 2516 tick_clock_.reset(tick_clock); | 2528 tick_clock_.reset(tick_clock); |
| 2517 buffered_data_source_host_.SetTickClockForTest(tick_clock); | 2529 buffered_data_source_host_.SetTickClockForTest(tick_clock); |
| 2518 } | 2530 } |
| 2519 | 2531 |
| 2520 } // namespace media | 2532 } // namespace media |
| OLD | NEW |