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 | 56 |
1 files changed, 46 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 6d035b2e55d..523ad73012d 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc @@ -366,8 +366,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); @@ -376,14 +377,31 @@ 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_) + 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>(); @@ -418,7 +436,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( if (!web_stream_.IsNull()) web_stream_.AddObserver(this); - 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_); @@ -441,7 +459,7 @@ WebMediaPlayer::LoadTiming WebMediaPlayerMS::Load( frame_deliverer_.reset(new 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_, @@ -740,7 +758,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(); @@ -751,6 +781,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_); } @@ -1217,8 +1252,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 |