| 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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 observer_(params->media_observer()), | 253 observer_(params->media_observer()), |
| 254 max_keyframe_distance_to_disable_background_video_( | 254 max_keyframe_distance_to_disable_background_video_( |
| 255 params->max_keyframe_distance_to_disable_background_video()), | 255 params->max_keyframe_distance_to_disable_background_video()), |
| 256 max_keyframe_distance_to_disable_background_video_mse_( | 256 max_keyframe_distance_to_disable_background_video_mse_( |
| 257 params->max_keyframe_distance_to_disable_background_video_mse()), | 257 params->max_keyframe_distance_to_disable_background_video_mse()), |
| 258 enable_instant_source_buffer_gc_( | 258 enable_instant_source_buffer_gc_( |
| 259 params->enable_instant_source_buffer_gc()), | 259 params->enable_instant_source_buffer_gc()), |
| 260 embedded_media_experience_enabled_( | 260 embedded_media_experience_enabled_( |
| 261 params->embedded_media_experience_enabled()), | 261 params->embedded_media_experience_enabled()), |
| 262 request_routing_token_cb_(params->request_routing_token_cb()), | 262 request_routing_token_cb_(params->request_routing_token_cb()), |
| 263 overlay_routing_token_(base::UnguessableToken()) { | 263 overlay_routing_token_(OverlayInfo::RoutingToken()) { |
| 264 DVLOG(1) << __func__; | 264 DVLOG(1) << __func__; |
| 265 DCHECK(!adjust_allocated_memory_cb_.is_null()); | 265 DCHECK(!adjust_allocated_memory_cb_.is_null()); |
| 266 DCHECK(renderer_factory_selector_); | 266 DCHECK(renderer_factory_selector_); |
| 267 DCHECK(client_); | 267 DCHECK(client_); |
| 268 DCHECK(delegate_); | 268 DCHECK(delegate_); |
| 269 | 269 |
| 270 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( | 270 force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 271 switches::kForceVideoOverlays); | 271 switches::kForceVideoOverlays); |
| 272 | 272 |
| 273 if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo)) { | 273 if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo)) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 void WebMediaPlayerImpl::EnableOverlay() { | 359 void WebMediaPlayerImpl::EnableOverlay() { |
| 360 overlay_enabled_ = true; | 360 overlay_enabled_ = true; |
| 361 if (surface_manager_ && overlay_mode_ == OverlayMode::kUseContentVideoView) { | 361 if (surface_manager_ && overlay_mode_ == OverlayMode::kUseContentVideoView) { |
| 362 overlay_surface_id_.reset(); | 362 overlay_surface_id_.reset(); |
| 363 surface_created_cb_.Reset( | 363 surface_created_cb_.Reset( |
| 364 base::Bind(&WebMediaPlayerImpl::OnSurfaceCreated, AsWeakPtr())); | 364 base::Bind(&WebMediaPlayerImpl::OnSurfaceCreated, AsWeakPtr())); |
| 365 surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, | 365 surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, |
| 366 surface_created_cb_.callback()); | 366 surface_created_cb_.callback()); |
| 367 } else if (request_routing_token_cb_ && | 367 } else if (request_routing_token_cb_ && |
| 368 overlay_mode_ == OverlayMode::kUseAndroidOverlay) { | 368 overlay_mode_ == OverlayMode::kUseAndroidOverlay) { |
| 369 overlay_routing_token_.reset(); | 369 overlay_routing_token_is_pending_ = true; |
| 370 token_available_cb_.Reset( | 370 token_available_cb_.Reset( |
| 371 base::Bind(&WebMediaPlayerImpl::OnOverlayRoutingToken, AsWeakPtr())); | 371 base::Bind(&WebMediaPlayerImpl::OnOverlayRoutingToken, AsWeakPtr())); |
| 372 request_routing_token_cb_.Run(token_available_cb_.callback()); | 372 request_routing_token_cb_.Run(token_available_cb_.callback()); |
| 373 } | 373 } |
| 374 | 374 |
| 375 // We have requested (and maybe already have) overlay information. If the | 375 // We have requested (and maybe already have) overlay information. If the |
| 376 // restarted decoder requests overlay information, then we'll defer providing | 376 // restarted decoder requests overlay information, then we'll defer providing |
| 377 // it if it hasn't arrived yet. Otherwise, this would be a race, since we | 377 // it if it hasn't arrived yet. Otherwise, this would be a race, since we |
| 378 // don't know if the request for overlay info or restart will complete first. | 378 // don't know if the request for overlay info or restart will complete first. |
| 379 if (decoder_requires_restart_for_overlay_) | 379 if (decoder_requires_restart_for_overlay_) |
| 380 ScheduleRestart(); | 380 ScheduleRestart(); |
| 381 } | 381 } |
| 382 | 382 |
| 383 void WebMediaPlayerImpl::DisableOverlay() { | 383 void WebMediaPlayerImpl::DisableOverlay() { |
| 384 overlay_enabled_ = false; | 384 overlay_enabled_ = false; |
| 385 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { | 385 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { |
| 386 surface_created_cb_.Cancel(); | 386 surface_created_cb_.Cancel(); |
| 387 overlay_surface_id_ = SurfaceManager::kNoSurfaceID; | 387 overlay_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 388 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { | 388 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { |
| 389 token_available_cb_.Cancel(); | 389 token_available_cb_.Cancel(); |
| 390 overlay_routing_token_ = base::UnguessableToken(); | 390 overlay_routing_token_is_pending_ = false; |
| 391 overlay_routing_token_ = OverlayInfo::RoutingToken(); |
| 391 } | 392 } |
| 392 | 393 |
| 393 if (decoder_requires_restart_for_overlay_) | 394 if (decoder_requires_restart_for_overlay_) |
| 394 ScheduleRestart(); | 395 ScheduleRestart(); |
| 395 else | 396 else |
| 396 MaybeSendOverlayInfoToDecoder(); | 397 MaybeSendOverlayInfoToDecoder(); |
| 397 } | 398 } |
| 398 | 399 |
| 399 void WebMediaPlayerImpl::EnteredFullscreen() { | 400 void WebMediaPlayerImpl::EnteredFullscreen() { |
| 401 overlay_info_.is_fullscreen = true; |
| 402 |
| 400 // |force_video_overlays_| implies that we're already in overlay mode, so take | 403 // |force_video_overlays_| implies that we're already in overlay mode, so take |
| 401 // no action here. Otherwise, switch to an overlay if it's allowed and if | 404 // no action here. Otherwise, switch to an overlay if it's allowed and if |
| 402 // it will display properly. | 405 // it will display properly. |
| 403 if (!force_video_overlays_ && overlay_mode_ != OverlayMode::kNoOverlays && | 406 if (!force_video_overlays_ && overlay_mode_ != OverlayMode::kNoOverlays && |
| 404 DoesOverlaySupportMetadata()) { | 407 DoesOverlaySupportMetadata()) { |
| 405 EnableOverlay(); | 408 EnableOverlay(); |
| 406 } | 409 } |
| 407 if (observer_) | 410 if (observer_) |
| 408 observer_->OnEnteredFullscreen(); | 411 observer_->OnEnteredFullscreen(); |
| 409 | 412 |
| 410 // TODO(liberato): if the decoder provided a callback for fullscreen state, | 413 // We send this only if we can send multiple calls. Otherwise, either (a) |
| 411 // then notify it now. | 414 // we already sent it and we don't have a callback anyway (we reset it when |
| 415 // it's called in restart mode), or (b) we'll send this later when the surface |
| 416 // actually arrives. GVD assumes that the first overlay info will have the |
| 417 // routing information. Note that we set |is_fullscreen_| earlier, so that |
| 418 // if EnableOverlay() can include fullscreen info in case it sends the overlay |
| 419 // info before returning. |
| 420 if (!decoder_requires_restart_for_overlay_) |
| 421 MaybeSendOverlayInfoToDecoder(); |
| 412 } | 422 } |
| 413 | 423 |
| 414 void WebMediaPlayerImpl::ExitedFullscreen() { | 424 void WebMediaPlayerImpl::ExitedFullscreen() { |
| 425 overlay_info_.is_fullscreen = false; |
| 426 |
| 415 // If we're in overlay mode, then exit it unless we're supposed to be in | 427 // If we're in overlay mode, then exit it unless we're supposed to be in |
| 416 // overlay mode all the time. | 428 // overlay mode all the time. |
| 417 if (!force_video_overlays_ && overlay_enabled_) | 429 if (!force_video_overlays_ && overlay_enabled_) |
| 418 DisableOverlay(); | 430 DisableOverlay(); |
| 419 if (observer_) | 431 if (observer_) |
| 420 observer_->OnExitedFullscreen(); | 432 observer_->OnExitedFullscreen(); |
| 421 | 433 |
| 422 // TODO(liberato): if the decoder provided a callback for fullscreen state, | 434 // See EnteredFullscreen for why we do this. |
| 423 // then notify it now. | 435 if (!decoder_requires_restart_for_overlay_) |
| 436 MaybeSendOverlayInfoToDecoder(); |
| 424 } | 437 } |
| 425 | 438 |
| 426 void WebMediaPlayerImpl::BecameDominantVisibleContent(bool isDominant) { | 439 void WebMediaPlayerImpl::BecameDominantVisibleContent(bool isDominant) { |
| 427 if (observer_) | 440 if (observer_) |
| 428 observer_->OnBecameDominantVisibleContent(isDominant); | 441 observer_->OnBecameDominantVisibleContent(isDominant); |
| 429 } | 442 } |
| 430 | 443 |
| 431 void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( | 444 void WebMediaPlayerImpl::SetIsEffectivelyFullscreen( |
| 432 bool isEffectivelyFullscreen) { | 445 bool isEffectivelyFullscreen) { |
| 433 delegate_->SetIsEffectivelyFullscreen(delegate_id_, isEffectivelyFullscreen); | 446 delegate_->SetIsEffectivelyFullscreen(delegate_id_, isEffectivelyFullscreen); |
| (...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1740 | 1753 |
| 1741 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { | 1754 void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) { |
| 1742 DCHECK(overlay_mode_ == OverlayMode::kUseContentVideoView); | 1755 DCHECK(overlay_mode_ == OverlayMode::kUseContentVideoView); |
| 1743 overlay_surface_id_ = surface_id; | 1756 overlay_surface_id_ = surface_id; |
| 1744 MaybeSendOverlayInfoToDecoder(); | 1757 MaybeSendOverlayInfoToDecoder(); |
| 1745 } | 1758 } |
| 1746 | 1759 |
| 1747 void WebMediaPlayerImpl::OnOverlayRoutingToken( | 1760 void WebMediaPlayerImpl::OnOverlayRoutingToken( |
| 1748 const base::UnguessableToken& token) { | 1761 const base::UnguessableToken& token) { |
| 1749 DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay); | 1762 DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay); |
| 1750 overlay_routing_token_ = token; | 1763 // TODO(liberato): |token| should already be a RoutingToken. |
| 1764 overlay_routing_token_is_pending_ = false; |
| 1765 overlay_routing_token_ = OverlayInfo::RoutingToken(token); |
| 1751 MaybeSendOverlayInfoToDecoder(); | 1766 MaybeSendOverlayInfoToDecoder(); |
| 1752 } | 1767 } |
| 1753 | 1768 |
| 1754 void WebMediaPlayerImpl::OnOverlayInfoRequested( | 1769 void WebMediaPlayerImpl::OnOverlayInfoRequested( |
| 1755 bool decoder_requires_restart_for_overlay, | 1770 bool decoder_requires_restart_for_overlay, |
| 1756 const ProvideOverlayInfoCB& provide_overlay_info_cb) { | 1771 const ProvideOverlayInfoCB& provide_overlay_info_cb) { |
| 1757 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1772 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1758 DCHECK(surface_manager_); | 1773 DCHECK(surface_manager_); |
| 1759 | 1774 |
| 1760 // A null callback indicates that the decoder is going away. | 1775 // A null callback indicates that the decoder is going away. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1788 void WebMediaPlayerImpl::MaybeSendOverlayInfoToDecoder() { | 1803 void WebMediaPlayerImpl::MaybeSendOverlayInfoToDecoder() { |
| 1789 // If the decoder didn't request overlay info, then don't send it. | 1804 // If the decoder didn't request overlay info, then don't send it. |
| 1790 if (!provide_overlay_info_cb_) | 1805 if (!provide_overlay_info_cb_) |
| 1791 return; | 1806 return; |
| 1792 | 1807 |
| 1793 // We should send the overlay info as long as we know it. This includes the | 1808 // We should send the overlay info as long as we know it. This includes the |
| 1794 // case where |!overlay_enabled_|, since we want to tell the decoder to avoid | 1809 // case where |!overlay_enabled_|, since we want to tell the decoder to avoid |
| 1795 // using overlays. Assuming that the decoder has requested info, the only | 1810 // using overlays. Assuming that the decoder has requested info, the only |
| 1796 // case in which we don't want to send something is if we've requested the | 1811 // case in which we don't want to send something is if we've requested the |
| 1797 // info but not received it yet. Then, we should wait until we do. | 1812 // info but not received it yet. Then, we should wait until we do. |
| 1813 // |
| 1814 // Initialization requires this; AVDA should start with enough info to make an |
| 1815 // overlay, so that (pre-M) the initial codec is created with the right output |
| 1816 // surface; it can't switch later. |
| 1798 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { | 1817 if (overlay_mode_ == OverlayMode::kUseContentVideoView) { |
| 1799 if (!overlay_surface_id_.has_value()) | 1818 if (!overlay_surface_id_.has_value()) |
| 1800 return; | 1819 return; |
| 1820 |
| 1821 overlay_info_.surface_id = *overlay_surface_id_; |
| 1801 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { | 1822 } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) { |
| 1802 if (!overlay_routing_token_.has_value()) | 1823 if (overlay_routing_token_is_pending_) |
| 1803 return; | 1824 return; |
| 1825 |
| 1826 overlay_info_.routing_token = overlay_routing_token_; |
| 1804 } | 1827 } |
| 1805 | 1828 |
| 1806 // Note that we're guaranteed that both |overlay_surface_id_| and | |
| 1807 // |overlay_routing_token_| have values, since both have values unless there | |
| 1808 // is a request pending. Nobody calls us if a request is pending. | |
| 1809 | |
| 1810 int surface_id = SurfaceManager::kNoSurfaceID; | |
| 1811 if (overlay_surface_id_) | |
| 1812 surface_id = *overlay_surface_id_; | |
| 1813 | |
| 1814 // Since we represent "no token" as a null UnguessableToken, we translate it | |
| 1815 // into an optional here. Alternatively, we could represent it as a | |
| 1816 // base::Optional in |overlay_routing_token_|, but then we'd have a | |
| 1817 // base::Optional<base::Optional<base::UnguessableToken> >. We don't do that | |
| 1818 // because... just because. | |
| 1819 base::Optional<base::UnguessableToken> routing_token; | |
| 1820 if (overlay_routing_token_.has_value() && !overlay_routing_token_->is_empty()) | |
| 1821 routing_token = *overlay_routing_token_; | |
| 1822 | |
| 1823 // If restart is required, the callback is one-shot only. | 1829 // If restart is required, the callback is one-shot only. |
| 1824 if (decoder_requires_restart_for_overlay_) { | 1830 if (decoder_requires_restart_for_overlay_) { |
| 1825 base::ResetAndReturn(&provide_overlay_info_cb_) | 1831 base::ResetAndReturn(&provide_overlay_info_cb_).Run(overlay_info_); |
| 1826 .Run(surface_id, routing_token); | |
| 1827 } else { | 1832 } else { |
| 1828 provide_overlay_info_cb_.Run(surface_id, routing_token); | 1833 provide_overlay_info_cb_.Run(overlay_info_); |
| 1829 } | 1834 } |
| 1830 } | 1835 } |
| 1831 | 1836 |
| 1832 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { | 1837 std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { |
| 1833 DCHECK(main_task_runner_->BelongsToCurrentThread()); | 1838 DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| 1834 | 1839 |
| 1835 // TODO(liberato): Re-evaluate this as AndroidVideoSurfaceChooser gets smarter | 1840 // TODO(liberato): Re-evaluate this as AndroidVideoSurfaceChooser gets smarter |
| 1836 // about turning off overlays. Either we should verify that it is not | 1841 // about turning off overlays. Either we should verify that it is not |
| 1837 // breaking this use-case if it does so, or we should notify it that using | 1842 // breaking this use-case if it does so, or we should notify it that using |
| 1838 // the overlay is required. | 1843 // the overlay is required. |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2538 } | 2543 } |
| 2539 | 2544 |
| 2540 #undef UMA_HISTOGRAM_VIDEO_HEIGHT | 2545 #undef UMA_HISTOGRAM_VIDEO_HEIGHT |
| 2541 | 2546 |
| 2542 void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { | 2547 void WebMediaPlayerImpl::SetTickClockForTest(base::TickClock* tick_clock) { |
| 2543 tick_clock_.reset(tick_clock); | 2548 tick_clock_.reset(tick_clock); |
| 2544 buffered_data_source_host_.SetTickClockForTest(tick_clock); | 2549 buffered_data_source_host_.SetTickClockForTest(tick_clock); |
| 2545 } | 2550 } |
| 2546 | 2551 |
| 2547 } // namespace media | 2552 } // namespace media |
| OLD | NEW |