summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
diff options
context:
space:
mode:
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.cc56
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