Index: media/blink/webmediaplayer_impl.cc |
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc |
index 6b2a26050adc6edf35dc7e7b10104d36ec540430..6fad61e4f46617bddf6f012b7098a9a9b8391d41 100644 |
--- a/media/blink/webmediaplayer_impl.cc |
+++ b/media/blink/webmediaplayer_impl.cc |
@@ -154,9 +154,12 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( |
suspending_(false), |
suspended_(false), |
resuming_(false), |
+ pending_suspend_resume_cycle_(false), |
ended_(false), |
pending_seek_(false), |
should_notify_time_changed_(false), |
+ fullscreen_(false), |
+ decoder_requires_restart_for_fullscreen_(false), |
client_(client), |
encrypted_client_(encrypted_client), |
delegate_(delegate), |
@@ -184,7 +187,9 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( |
AsWeakPtr(), |
base::Bind(&IgnoreCdmAttached))), |
is_cdm_attached_(false), |
-#if defined(OS_ANDROID) // WMPI_CAST |
+#if defined(OS_ANDROID) |
+ surface_manager_(nullptr), |
+ // WMPI_CAST |
cast_impl_(this, client_, params.context_3d_cb()), |
#endif |
volume_(1.0), |
@@ -263,6 +268,18 @@ void WebMediaPlayerImpl::load(LoadType load_type, const blink::WebURL& url, |
DoLoad(load_type, url, cors_mode); |
} |
+void WebMediaPlayerImpl::enterFullscreen() { |
+ fullscreen_ = true; |
+ if (decoder_requires_restart_for_fullscreen_) |
+ ScheduleRestart(); |
+} |
+ |
+void WebMediaPlayerImpl::exitedFullscreen() { |
+ fullscreen_ = false; |
+ if (decoder_requires_restart_for_fullscreen_) |
+ ScheduleRestart(); |
+} |
+ |
void WebMediaPlayerImpl::DoLoad(LoadType load_type, |
const blink::WebURL& url, |
CORSMode cors_mode) { |
@@ -978,8 +995,9 @@ void WebMediaPlayerImpl::OnPipelineSuspended(PipelineStatus status) { |
} |
#endif |
- if (pending_resume_) { |
+ if (pending_resume_ || pending_suspend_resume_cycle_) { |
pending_resume_ = false; |
+ pending_suspend_resume_cycle_ = false; |
Resume(); |
return; |
} |
@@ -1245,8 +1263,48 @@ void WebMediaPlayerImpl::Resume() { |
time_changed)); |
} |
-#if defined(OS_ANDROID) // WMPI_CAST |
+void WebMediaPlayerImpl::ScheduleRestart() { |
+ if (!suspended_ || resuming_) { |
+ pending_suspend_resume_cycle_ = true; |
+ ScheduleSuspend(); |
+ } |
+} |
+#if defined(OS_ANDROID) |
+// TODO(watk): Move the SurfaceManager and associated state out of WMPI. |
+void WebMediaPlayerImpl::SetSurfaceManager(SurfaceManager* surface_manager) { |
+ surface_manager_ = surface_manager; |
+} |
+ |
+void WebMediaPlayerImpl::OnSurfaceRequested( |
+ const SurfaceCreatedCB& surface_created_cb) { |
+ DCHECK(main_task_runner_->BelongsToCurrentThread()); |
+ DCHECK(surface_manager_); |
+ |
+ // A null callback indicates that the decoder is going away. |
+ if (surface_created_cb.is_null()) { |
+ decoder_requires_restart_for_fullscreen_ = false; |
+ return; |
+ } |
+ |
+ // If we're getting a surface request it means GVD is initializing, so until |
+ // we get a null surface request, GVD is the active decoder. While that's the |
+ // case we should restart the pipeline on fullscreen transitions so that when |
+ // we create a new GVD it will request a surface again and use the right kind |
+ // of surface for the new fullscreen state. |
+ // TODO(watk): Don't require a pipeline restart to switch surfaces for |
+ // cases where it isn't necessary. |
+ decoder_requires_restart_for_fullscreen_ = true; |
+ if (fullscreen_) { |
+ surface_manager_->CreateFullscreenSurface(pipeline_metadata_.natural_size, |
+ surface_created_cb); |
+ } else { |
+ // Tell the decoder to create its own surface. |
+ surface_created_cb.Run(SurfaceManager::kNoSurfaceID); |
+ } |
+} |
+ |
+// WMPI_CAST |
bool WebMediaPlayerImpl::isRemote() const { |
return cast_impl_.isRemote(); |
} |
@@ -1307,7 +1365,7 @@ gfx::Size WebMediaPlayerImpl::GetCanvasSize() const { |
void WebMediaPlayerImpl::SetDeviceScaleFactor(float scale_factor) { |
cast_impl_.SetDeviceScaleFactor(scale_factor); |
} |
-#endif // defined(OS_ANDROID) // WMPI_CAST |
+#endif // defined(OS_ANDROID) |
void WebMediaPlayerImpl::DataSourceInitialized(bool success) { |
DVLOG(1) << __FUNCTION__; |
@@ -1334,9 +1392,14 @@ void WebMediaPlayerImpl::NotifyDownloading(bool is_downloading) { |
} |
scoped_ptr<Renderer> WebMediaPlayerImpl::CreateRenderer() { |
+ RequestSurfaceCB request_surface_cb; |
+#if defined(OS_ANDROID) |
+ request_surface_cb = |
+ BIND_TO_RENDER_LOOP(&WebMediaPlayerImpl::OnSurfaceRequested); |
+#endif |
return renderer_factory_->CreateRenderer( |
media_task_runner_, worker_task_runner_, audio_source_provider_.get(), |
- compositor_); |
+ compositor_, request_surface_cb); |
} |
void WebMediaPlayerImpl::StartPipeline() { |
@@ -1434,8 +1497,15 @@ void WebMediaPlayerImpl::OnNaturalSizeChanged(gfx::Size size) { |
media_log_->AddEvent( |
media_log_->CreateVideoSizeSetEvent(size.width(), size.height())); |
+ |
+#if defined(OS_ANDROID) |
+ if (fullscreen_ && surface_manager_ && |
+ pipeline_metadata_.natural_size != size) { |
+ surface_manager_->FullscreenVideoSizeChanged(size); |
+ } |
+#endif |
+ |
pipeline_metadata_.natural_size = size; |
- |
client_->sizeChanged(); |
} |