diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc index 4d4d7e98871..dc6f264835b 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc @@ -390,8 +390,9 @@ WebMediaPlayerMS::~WebMediaPlayerMS() { SendLogMessage( String::Format("%s() [delegate_id=%d]", __func__, delegate_id_)); - if (!web_stream_.IsNull()) + if (!web_stream_.IsNull()) { web_stream_.RemoveObserver(this); + } // Destruct compositor resources in the proper order. get_client()->SetCcLayer(nullptr); @@ -400,14 +401,35 @@ WebMediaPlayerMS::~WebMediaPlayerMS() { video_layer_->StopUsingProvider(); } - if (frame_deliverer_) - io_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release()); + if (frame_deliverer_) { + io_task_runner_->DeleteSoon(FROM_HERE, std::move(frame_deliverer_)); + } - if (video_frame_provider_) + if (video_frame_provider_) { video_frame_provider_->Stop(); + } - if (audio_renderer_) + // This must be destroyed before `compositor_` since it will grab a couple of + // final metrics during destruction. + watch_time_reporter_.reset(); + + if (compositor_) { + // `compositor_` receives frames on `io_task_runner_` from + // `frame_deliverer_` and operates on the `compositor_task_runner_`, so + // must trampoline through both to ensure a safe destruction. + PostCrossThreadTask( + *io_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce( + [](scoped_refptr<base::SingleThreadTaskRunner> task_runner, + std::unique_ptr<WebMediaPlayerMSCompositor> compositor) { + task_runner->DeleteSoon(FROM_HERE, std::move(compositor)); + }, + compositor_task_runner_, std::move(compositor_))); + } + + if (audio_renderer_) { audio_renderer_->Stop(); + } media_log_->AddEvent<media::MediaLogEvent::kWebMediaPlayerDestroyed>(); @@ -448,7 +470,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( watch_time_reporter_.reset(); - compositor_ = base::MakeRefCounted<WebMediaPlayerMSCompositor>( + compositor_ = std::make_unique<WebMediaPlayerMSCompositor>( compositor_task_runner_, io_task_runner_, web_stream_, std::move(submitter_), surface_layer_mode_, weak_this_); @@ -471,7 +493,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( frame_deliverer_ = std::make_unique<WebMediaPlayerMS::FrameDeliverer>( weak_this_, CrossThreadBindRepeating(&WebMediaPlayerMSCompositor::EnqueueFrame, - compositor_), + CrossThreadUnretained(compositor_.get())), media_task_runner_, worker_task_runner_, gpu_factories_); video_frame_provider_ = renderer_factory_->GetVideoRenderer( web_stream_, @@ -814,7 +836,19 @@ void WebMediaPlayerMS::Pause() { video_frame_provider_->Pause(); compositor_->StopRendering(); - compositor_->ReplaceCurrentFrameWithACopy(); + + // Bounce this call off of video task runner to since there might still be + // frames passed on video task runner. + PostCrossThreadTask( + *io_task_runner_, FROM_HERE, + WTF::CrossThreadBindOnce( + [](scoped_refptr<base::SingleThreadTaskRunner> task_runner, + WTF::CrossThreadOnceClosure copy_cb) { + PostCrossThreadTask(*task_runner, FROM_HERE, std::move(copy_cb)); + }, + main_render_task_runner_, + WTF::CrossThreadBindOnce( + &WebMediaPlayerMS::ReplaceCurrentFrameWithACopy, weak_this_))); if (audio_renderer_) audio_renderer_->Pause(); @@ -829,6 +863,11 @@ void WebMediaPlayerMS::Pause() { paused_ = true; } +void WebMediaPlayerMS::ReplaceCurrentFrameWithACopy() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + compositor_->ReplaceCurrentFrameWithACopy(); +} + void WebMediaPlayerMS::Seek(double seconds) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } @@ -1165,8 +1204,9 @@ void WebMediaPlayerMS::ActivateSurfaceLayerForVideo() { PostCrossThreadTask( *compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::EnableSubmission, - compositor_, bridge_->GetSurfaceId(), - video_transformation_, IsInPictureInPicture())); + CrossThreadUnretained(compositor_.get()), + bridge_->GetSurfaceId(), video_transformation_, + IsInPictureInPicture())); // If the element is already in Picture-in-Picture mode, it means that it // was set in this mode prior to this load, with a different |