diff options
4 files changed, 66 insertions, 65 deletions
diff --git a/chromium/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/chromium/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h index 49955674568..7bca5852839 100644 --- a/chromium/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h +++ b/chromium/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h @@ -208,6 +208,8 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS static const gfx::Size kUseGpuMemoryBufferVideoFramesMinResolution; #endif // BUILDFLAG(IS_WIN) + void ReplaceCurrentFrameWithACopy(); + bool IsInPictureInPicture() const; // Switch to SurfaceLayer, either initially or from VideoLayer. @@ -311,7 +313,7 @@ class BLINK_MODULES_EXPORT WebMediaPlayerMS // Used for DCHECKs to ensure methods calls executed in the correct thread. THREAD_CHECKER(thread_checker_); - scoped_refptr<WebMediaPlayerMSCompositor> compositor_; + std::unique_ptr<WebMediaPlayerMSCompositor> compositor_; const WebString initial_audio_output_device_id_; 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 diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc index 7ac02b2b986..9d627d986f5 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.cc @@ -195,18 +195,18 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor( dropped_frame_count_(0), stopped_(true), render_started_(!stopped_) { + weak_this_ = weak_ptr_factory_.GetWeakPtr(); if (surface_layer_mode != WebMediaPlayer::SurfaceLayerMode::kNever) { submitter_ = std::move(submitter); PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::InitializeSubmitter, - weak_ptr_factory_.GetWeakPtr())); + weak_this_)); update_submission_state_callback_ = base::BindPostTask( video_frame_compositor_task_runner_, ConvertToBaseRepeatingCallback(CrossThreadBindRepeating( - &WebMediaPlayerMSCompositor::SetIsSurfaceVisible, - weak_ptr_factory_.GetWeakPtr()))); + &WebMediaPlayerMSCompositor::SetIsSurfaceVisible, weak_this_))); } HeapVector<Member<MediaStreamComponent>> video_components; @@ -234,27 +234,12 @@ WebMediaPlayerMSCompositor::WebMediaPlayerMSCompositor( } WebMediaPlayerMSCompositor::~WebMediaPlayerMSCompositor() { - // Ensured by destructor traits. DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); if (video_frame_provider_client_) { video_frame_provider_client_->StopUsingProvider(); } } -// static -void WebMediaPlayerMSCompositorTraits::Destruct( - const WebMediaPlayerMSCompositor* compositor) { - if (!compositor->video_frame_compositor_task_runner_ - ->BelongsToCurrentThread()) { - PostCrossThreadTask( - *compositor->video_frame_compositor_task_runner_, FROM_HERE, - CrossThreadBindOnce(&WebMediaPlayerMSCompositorTraits::Destruct, - CrossThreadUnretained(compositor))); - return; - } - delete compositor; -} - void WebMediaPlayerMSCompositor::InitializeSubmitter() { DCHECK(video_frame_compositor_task_runner_->BelongsToCurrentThread()); submitter_->Initialize(this, /*is_media_stream=*/true); @@ -300,7 +285,7 @@ void WebMediaPlayerMSCompositor::SetForceBeginFrames(bool enable) { PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::SetForceBeginFrames, - weak_ptr_factory_.GetWeakPtr(), enable)); + weak_this_, enable)); return; } @@ -582,7 +567,7 @@ void WebMediaPlayerMSCompositor::StartRendering() { PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StartRenderingInternal, - WrapRefCounted(this))); + weak_this_)); } void WebMediaPlayerMSCompositor::StopRendering() { @@ -590,18 +575,7 @@ void WebMediaPlayerMSCompositor::StopRendering() { PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::StopRenderingInternal, - WrapRefCounted(this))); -} - -void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - // Bounce this call off of IO thread to since there might still be frames - // passed on IO thread. - io_task_runner_->PostTask( - FROM_HERE, - media::BindToCurrentLoop(WTF::Bind( - &WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal, - WrapRefCounted(this)))); + weak_this_)); } bool WebMediaPlayerMSCompositor::MapTimestampsToRenderTimeTicks( @@ -671,7 +645,7 @@ void WebMediaPlayerMSCompositor::RenderWithoutAlgorithm( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce( &WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor, - WrapRefCounted(this), std::move(frame), is_copy)); + weak_this_, std::move(frame), is_copy)); } void WebMediaPlayerMSCompositor::RenderWithoutAlgorithmOnCompositor( @@ -770,9 +744,8 @@ void WebMediaPlayerMSCompositor::SetCurrentFrame( PostCrossThreadTask( *video_frame_compositor_task_runner_, FROM_HERE, CrossThreadBindOnce(&WebMediaPlayerMSCompositor::CheckForFrameChanges, - WrapRefCounted(this), is_first_frame, - has_frame_size_changed, std::move(new_transform), - std::move(new_opacity))); + weak_this_, is_first_frame, has_frame_size_changed, + std::move(new_transform), std::move(new_opacity))); } void WebMediaPlayerMSCompositor::CheckForFrameChanges( @@ -839,7 +812,7 @@ void WebMediaPlayerMSCompositor::StopRenderingInternal() { video_frame_provider_client_->StopRendering(); } -void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopyInternal() { +void WebMediaPlayerMSCompositor::ReplaceCurrentFrameWithACopy() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); scoped_refptr<media::VideoFrame> current_frame_ref; { diff --git a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h index a2d8761d561..5a133edda51 100644 --- a/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h +++ b/chromium/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms_compositor.h @@ -24,7 +24,6 @@ #include "third_party/blink/renderer/modules/mediastream/video_renderer_algorithm_wrapper.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" -#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" namespace base { class SingleThreadTaskRunner; @@ -46,7 +45,6 @@ class SurfaceId; namespace blink { class MediaStreamDescriptor; class WebMediaPlayerMS; -struct WebMediaPlayerMSCompositorTraits; // This class is designed to handle the work load on compositor thread for // WebMediaPlayerMS. It will be instantiated on the main thread, but destroyed @@ -58,9 +56,7 @@ struct WebMediaPlayerMSCompositorTraits; // Otherwise, WebMediaPlayerMSCompositor will simply store the most recent // frame, and submit it whenever asked by the compositor. class MODULES_EXPORT WebMediaPlayerMSCompositor - : public cc::VideoFrameProvider, - public WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor, - WebMediaPlayerMSCompositorTraits> { + : public cc::VideoFrameProvider { public: using OnNewFramePresentedCB = base::OnceClosure; @@ -71,6 +67,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor std::unique_ptr<WebVideoFrameSubmitter> submitter, WebMediaPlayer::SurfaceLayerMode surface_layer_mode, const base::WeakPtr<WebMediaPlayerMS>& player); + ~WebMediaPlayerMSCompositor() override; WebMediaPlayerMSCompositor(const WebMediaPlayerMSCompositor&) = delete; WebMediaPlayerMSCompositor& operator=(const WebMediaPlayerMSCompositor&) = @@ -137,10 +134,7 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor void SetForceBeginFrames(bool enable); private: - friend class WTF::ThreadSafeRefCounted<WebMediaPlayerMSCompositor, - WebMediaPlayerMSCompositorTraits>; friend class WebMediaPlayerMSTest; - friend struct WebMediaPlayerMSCompositorTraits; // Struct used to keep information about frames pending in // |rendering_frame_buffer_|. @@ -151,8 +145,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor bool is_copy; }; - ~WebMediaPlayerMSCompositor() override; - // Ran on the |video_frame_compositor_task_runner_| to initialize // |submitter_| void InitializeSubmitter(); @@ -198,7 +190,6 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor void StartRenderingInternal(); void StopRenderingInternal(); - void ReplaceCurrentFrameWithACopyInternal(); void SetAlgorithmEnabledForTesting(bool algorithm_enabled); void RecordFrameDisplayedStats(base::TimeTicks frame_displayed_time); @@ -302,15 +293,10 @@ class MODULES_EXPORT WebMediaPlayerMSCompositor // |dropped_frame_count_|, and |render_started_|. base::Lock current_frame_lock_; + base::WeakPtr<WebMediaPlayerMSCompositor> weak_this_; base::WeakPtrFactory<WebMediaPlayerMSCompositor> weak_ptr_factory_{this}; }; -struct WebMediaPlayerMSCompositorTraits { - // Ensure destruction occurs on main thread so that "Web" and other resources - // are destroyed on the correct thread. - static void Destruct(const WebMediaPlayerMSCompositor* player); -}; - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_WEBMEDIAPLAYER_MS_COMPOSITOR_H_ |