From 7b69d1758f77331c2801746cd91b1b6b0db9ecfb Mon Sep 17 00:00:00 2001 From: Alexander Slobodeniuk Date: Thu, 28 Mar 2024 21:59:02 +0100 Subject: [PATCH] d3d11videosink: disconnect signals before releasing the window It might happen that the key event arrives when the d3d11videosink is stopping. In case of GstD3D11WindowWin32 it can raise a navigation event even when the sink is already freed, because the window object's refcount may reach 0 in the window thread. In other words sometimes the GstD3D11WindowWin32 lives few ms more then the GstD3D11VideoSink, because it's freed asynchronously. Part-of: --- .../sys/d3d11/gstd3d11videosink.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp index 3c4e6b56c3..da6a177a2b 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp @@ -958,6 +958,17 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps) return TRUE; } +static void +gst_d3d11_video_sink_release_window (GstD3D11VideoSink * self) +{ + if (self->window == NULL) + return; + + g_signal_handlers_disconnect_by_data (self->window, self); + gst_d3d11_window_unprepare (self->window); + gst_clear_object (&self->window); +} + static GstFlowReturn gst_d3d11_video_sink_update_window (GstD3D11VideoSink * self, GstCaps * caps) { @@ -1087,8 +1098,7 @@ gst_d3d11_video_sink_update_window (GstD3D11VideoSink * self, GstCaps * caps) if (ret == GST_FLOW_FLUSHING) { GstD3D11CSLockGuard lk (&self->lock); GST_WARNING_OBJECT (self, "Couldn't prepare window but we are flushing"); - gst_d3d11_window_unprepare (self->window); - gst_clear_object (&self->window); + gst_d3d11_video_sink_release_window (self); gst_object_unref (window); return GST_FLOW_FLUSHING; @@ -1330,10 +1340,8 @@ gst_d3d11_video_sink_stop (GstBaseSink * sink) gst_clear_object (&self->pool); } - if (self->window) - gst_d3d11_window_unprepare (self->window); + gst_d3d11_video_sink_release_window (self); - gst_clear_object (&self->window); gst_clear_object (&self->device); g_clear_pointer (&self->title, g_free);