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

Unified Diff: media/blink/webmediaplayer_impl.cc

Issue 2849043002: Send AndroidOverlay routing token from WMPI to AVDA. (Closed)
Patch Set: maybe fixed macos Created 3 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: media/blink/webmediaplayer_impl.cc
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 51517e1e16ef8834daadc95a27da963d5afa30db..80eea95751001f0353d089230a3a784095cb2592 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -249,7 +249,9 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
enable_instant_source_buffer_gc_(
params->enable_instant_source_buffer_gc()),
embedded_media_experience_enabled_(
- params->embedded_media_experience_enabled()) {
+ params->embedded_media_experience_enabled()),
+ request_routing_token_cb_(params->request_routing_token_cb()),
+ overlay_routing_token_(base::UnguessableToken()) {
DVLOG(1) << __func__;
DCHECK(!adjust_allocated_memory_cb_.is_null());
DCHECK(renderer_factory_selector_);
@@ -259,8 +261,14 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(
force_video_overlays_ = base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kForceVideoOverlays);
- enable_fullscreen_video_overlays_ =
- base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo);
+ if (base::FeatureList::IsEnabled(media::kOverlayFullscreenVideo)) {
+ bool use_android_overlay =
+ base::FeatureList::IsEnabled(media::kUseAndroidOverlay);
+ overlay_mode_ = use_android_overlay ? OverlayMode::kUseAndroidOverlay
+ : OverlayMode::kUseContentVideoView;
+ } else {
+ overlay_mode_ = OverlayMode::kNoOverlays;
+ }
delegate_id_ = delegate_->AddObserver(this);
delegate_->SetIdle(delegate_id_, true);
@@ -341,39 +349,57 @@ bool WebMediaPlayerImpl::SupportsOverlayFullscreenVideo() {
void WebMediaPlayerImpl::EnableOverlay() {
overlay_enabled_ = true;
- if (surface_manager_) {
+ if (surface_manager_ && overlay_mode_ == OverlayMode::kUseContentVideoView) {
overlay_surface_id_.reset();
surface_created_cb_.Reset(
base::Bind(&WebMediaPlayerImpl::OnSurfaceCreated, AsWeakPtr()));
surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size,
surface_created_cb_.callback());
+ } else if (!request_routing_token_cb_.is_null() &&
tguilbert 2017/05/08 23:10:29 NIT: can you remove the is_null (and the negation)
liberato (no reviews please) 2017/05/09 16:55:37 Done.
+ overlay_mode_ == OverlayMode::kUseAndroidOverlay) {
+ overlay_routing_token_.reset();
+ token_available_cb_.Reset(
+ base::Bind(&WebMediaPlayerImpl::OnOverlayRoutingToken, AsWeakPtr()));
+ request_routing_token_cb_.Run(token_available_cb_.callback());
}
+ // We have requested (and maybe already have) overlay information. If the
+ // restarted decoder requests overlay information, then we'll defer providing
+ // it if it hasn't arrived yet. Otherwise, this would be a race, since we
+ // don't know if the request for overlay info or restart will complete first.
if (decoder_requires_restart_for_overlay_)
ScheduleRestart();
}
void WebMediaPlayerImpl::DisableOverlay() {
overlay_enabled_ = false;
- surface_created_cb_.Cancel();
- overlay_surface_id_ = SurfaceManager::kNoSurfaceID;
+ if (overlay_mode_ == OverlayMode::kUseContentVideoView) {
+ surface_created_cb_.Cancel();
+ overlay_surface_id_ = SurfaceManager::kNoSurfaceID;
+ } else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay) {
+ token_available_cb_.Cancel();
+ overlay_routing_token_ = base::UnguessableToken();
+ }
if (decoder_requires_restart_for_overlay_)
ScheduleRestart();
- else if (!set_surface_cb_.is_null())
- set_surface_cb_.Run(*overlay_surface_id_);
+ else
+ SendOverlayInfoToDecoder();
}
void WebMediaPlayerImpl::EnteredFullscreen() {
// |force_video_overlays_| implies that we're already in overlay mode, so take
// no action here. Otherwise, switch to an overlay if it's allowed and if
// it will display properly.
- if (!force_video_overlays_ && enable_fullscreen_video_overlays_ &&
+ if (!force_video_overlays_ && overlay_mode_ != OverlayMode::kNoOverlays &&
DoesOverlaySupportMetadata()) {
EnableOverlay();
}
if (observer_)
observer_->OnEnteredFullscreen();
+
+ // TODO(liberato): if the decoder provided a callback for fullscreen state,
+ // then notify it now.
}
void WebMediaPlayerImpl::ExitedFullscreen() {
@@ -383,6 +409,9 @@ void WebMediaPlayerImpl::ExitedFullscreen() {
DisableOverlay();
if (observer_)
observer_->OnExitedFullscreen();
+
+ // TODO(liberato): if the decoder provided a callback for fullscreen state,
+ // then notify it now.
}
void WebMediaPlayerImpl::BecameDominantVisibleContent(bool isDominant) {
@@ -1442,8 +1471,10 @@ void WebMediaPlayerImpl::OnVideoNaturalSizeChange(const gfx::Size& size) {
if (!watch_time_reporter_->IsSizeLargeEnoughToReportWatchTime())
CreateWatchTimeReporter();
- if (overlay_enabled_ && surface_manager_)
+ if (overlay_enabled_ && surface_manager_ &&
+ overlay_mode_ == OverlayMode::kUseContentVideoView) {
surface_manager_->NaturalSizeChanged(rotated_size);
+ }
client_->SizeChanged();
@@ -1683,26 +1714,28 @@ void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) {
}
void WebMediaPlayerImpl::OnSurfaceCreated(int surface_id) {
+ DCHECK(overlay_mode_ == OverlayMode::kUseContentVideoView);
overlay_surface_id_ = surface_id;
- if (!set_surface_cb_.is_null()) {
- // If restart is required, the callback is one-shot only.
- if (decoder_requires_restart_for_overlay_)
- base::ResetAndReturn(&set_surface_cb_).Run(surface_id);
- else
- set_surface_cb_.Run(surface_id);
- }
+ SendOverlayInfoToDecoder();
+}
+
+void WebMediaPlayerImpl::OnOverlayRoutingToken(
+ const base::UnguessableToken& token) {
+ DCHECK(overlay_mode_ == OverlayMode::kUseAndroidOverlay);
+ overlay_routing_token_ = token;
+ SendOverlayInfoToDecoder();
}
-void WebMediaPlayerImpl::OnSurfaceRequested(
+void WebMediaPlayerImpl::OnOverlayInfoRequested(
bool decoder_requires_restart_for_overlay,
- const SurfaceCreatedCB& set_surface_cb) {
+ const ProvideOverlayInfoCB& provide_overlay_info_cb) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
DCHECK(surface_manager_);
// A null callback indicates that the decoder is going away.
- if (set_surface_cb.is_null()) {
+ if (provide_overlay_info_cb.is_null()) {
decoder_requires_restart_for_overlay_ = false;
- set_surface_cb_.Reset();
+ provide_overlay_info_cb_.Reset();
return;
}
@@ -1714,30 +1747,80 @@ void WebMediaPlayerImpl::OnSurfaceRequested(
// surfaces otherwise. If false, we simply need to tell the decoder about the
// new surface and it will handle things seamlessly.
decoder_requires_restart_for_overlay_ = decoder_requires_restart_for_overlay;
- set_surface_cb_ = set_surface_cb;
+ provide_overlay_info_cb_ = provide_overlay_info_cb;
// If we're waiting for the surface to arrive, OnSurfaceCreated() will be
- // called later when it arrives; so do nothing for now.
- if (!overlay_surface_id_)
+ // called later when it arrives; so do nothing for now. For AndroidOverlay,
+ // if we're waiting for the token then... OnOverlayRoutingToken()...
+ // We do this so that a request for a surface will block if we're in the
+ // process of getting one. Otherwise, on pre-M, the decoder would be stuck
+ // without an overlay if the restart that happens on entering fullscreen
+ // succeeds before we have the overlay info. Post-M, we could send what we
+ // have unconditionally. When the info arrives, it will be sent.
+ if (overlay_enabled_ && !HaveOverlayInfo())
return;
- OnSurfaceCreated(*overlay_surface_id_);
+ // Either overlays are not enabled, or they're enabled and we have info for
+ // them. Send it.
+ SendOverlayInfoToDecoder();
+}
+
+bool WebMediaPlayerImpl::HaveOverlayInfo() {
+ if (overlay_mode_ == OverlayMode::kUseContentVideoView)
+ return overlay_surface_id_.has_value();
+ else if (overlay_mode_ == OverlayMode::kUseAndroidOverlay)
+ return !overlay_routing_token_.has_value();
+
+ return false;
+}
+
+void WebMediaPlayerImpl::SendOverlayInfoToDecoder() {
+ if (provide_overlay_info_cb_.is_null())
tguilbert 2017/05/08 23:10:29 NIT: remove is_null and add negation?
liberato (no reviews please) 2017/05/09 16:55:37 Done.
+ return;
+
+ // Note that it's up to our caller to guarantee that the info we're sending
+ // matches whether we want the client to use overlays.
+
+ // Note that we're guaranteed that both |overlay_surface_id_| and
+ // |overlay_routing_token_| have values, since both have values unless there
+ // is a request pending. Nobody calls us if a request is pending.
+
+ // Since we represent "no token" as a null UnguessableToken, we translate it
+ // into an optional here. Alternatively, we could represent it as a
+ // base::Optional in |overlay_routing_token_|, but then we'd have a
+ // base::Optional<base::Optional<base::UnguessableToken> >. We don't do that
+ // because... just because.
+ base::Optional<base::UnguessableToken> routing_token;
+ if (overlay_routing_token_.has_value() && !overlay_routing_token_->is_empty())
+ routing_token = *overlay_routing_token_;
+
+ // If restart is required, the callback is one-shot only.
+ if (decoder_requires_restart_for_overlay_) {
+ base::ResetAndReturn(&provide_overlay_info_cb_)
+ .Run(*overlay_surface_id_, routing_token);
+ } else {
+ provide_overlay_info_cb_.Run(*overlay_surface_id_, routing_token);
+ }
}
std::unique_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
+ // TODO(liberato): Re-evaluate this as AndroidVideoSurfaceChooser gets smarter
+ // about turning off overlays. Either we should verify that it is not
+ // breaking this use-case if it does so, or we should notify it that using
+ // the overlay is required.
if (force_video_overlays_)
EnableOverlay();
- RequestSurfaceCB request_surface_cb;
+ RequestOverlayInfoCB request_overlay_info_cb;
#if defined(OS_ANDROID)
- request_surface_cb = BindToCurrentLoop(
- base::Bind(&WebMediaPlayerImpl::OnSurfaceRequested, AsWeakPtr()));
+ request_overlay_info_cb = BindToCurrentLoop(
+ base::Bind(&WebMediaPlayerImpl::OnOverlayInfoRequested, AsWeakPtr()));
#endif
return renderer_factory_selector_->GetCurrentFactory()->CreateRenderer(
media_task_runner_, worker_task_runner_, audio_source_provider_.get(),
- compositor_, request_surface_cb);
+ compositor_, request_overlay_info_cb);
}
void WebMediaPlayerImpl::StartPipeline() {

Powered by Google App Engine
This is Rietveld 408576698