d3d11window: Add unprepare method to clear internal resource
authorSeungha Yang <seungha@centricular.com>
Tue, 26 May 2020 16:52:59 +0000 (01:52 +0900)
committerSeungha Yang <seungha@centricular.com>
Tue, 26 May 2020 19:59:50 +0000 (04:59 +0900)
GObject::dispose method can be called multiple times. As win32 d3d11window
has an internal thread and because GObject::dispose method could be called from the
thread, it might cause problems such as trying to join self-thread

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1299>

sys/d3d11/gstd3d11videosink.c
sys/d3d11/gstd3d11window.cpp
sys/d3d11/gstd3d11window.h
sys/d3d11/gstd3d11window_corewindow.cpp
sys/d3d11/gstd3d11window_swapchainpanel.cpp
sys/d3d11/gstd3d11window_win32.cpp

index 95ce206..2cf4611 100644 (file)
@@ -594,6 +594,9 @@ gst_d3d11_video_sink_stop (GstBaseSink * sink)
     self->fallback_pool = NULL;
   }
 
+  if (self->window)
+    gst_d3d11_window_unprepare (self->window);
+
   gst_clear_object (&self->device);
   gst_clear_object (&self->window);
 
index e6756a1..d9c66ba 100644 (file)
@@ -999,6 +999,19 @@ gst_d3d11_window_unlock_stop (GstD3D11Window * window)
   return ret;
 }
 
+void
+gst_d3d11_window_unprepare (GstD3D11Window * window)
+{
+  GstD3D11WindowClass *klass;
+
+  g_return_if_fail (GST_IS_D3D11_WINDOW (window));
+
+  klass = GST_D3D11_WINDOW_GET_CLASS (window);
+
+  if (klass->unprepare)
+    klass->unprepare (window);
+}
+
 GstD3D11WindowNativeType
 gst_d3d11_window_get_native_type_from_handle (guintptr handle)
 {
index 6817dce..6ca6024 100644 (file)
@@ -132,6 +132,8 @@ struct _GstD3D11WindowClass
   void          (*on_resize)              (GstD3D11Window * window,
                                            guint width,
                                            guint height);
+
+  void          (*unprepare)              (GstD3D11Window * window);
 };
 
 GType         gst_d3d11_window_get_type             (void);
@@ -157,6 +159,8 @@ gboolean      gst_d3d11_window_unlock               (GstD3D11Window * window);
 
 gboolean      gst_d3d11_window_unlock_stop          (GstD3D11Window * window);
 
+void          gst_d3d11_window_unprepare            (GstD3D11Window * window);
+
 void          gst_d3d11_window_on_key_event         (GstD3D11Window * window,
                                                      const gchar * event,
                                                      const gchar * key);
index 0bf8394..2ee62d9 100644 (file)
@@ -98,6 +98,8 @@ gst_d3d11_window_core_window_on_resize (GstD3D11Window * window,
     guint width, guint height);
 static void
 gst_d3d11_window_core_window_on_resize_sync (GstD3D11Window * window);
+static void
+gst_d3d11_window_core_window_unprepare (GstD3D11Window * window);
 
 static float
 get_logical_dpi (void)
@@ -259,6 +261,8 @@ gst_d3d11_window_core_window_class_init (GstD3D11WindowCoreWindowClass * klass)
       GST_DEBUG_FUNCPTR (gst_d3d11_window_core_window_unlock_stop);
   window_class->on_resize =
       GST_DEBUG_FUNCPTR (gst_d3d11_window_core_window_on_resize);
+  window_class->unprepare =
+      GST_DEBUG_FUNCPTR (gst_d3d11_window_core_window_unprepare);
 }
 
 static void
@@ -333,7 +337,15 @@ error:
 static void
 gst_d3d11_window_core_window_dispose (GObject * object)
 {
-  GstD3D11WindowCoreWindow *self = GST_D3D11_WINDOW_CORE_WINDOW (object);
+  gst_d3d11_window_core_window_unprepare (GST_D3D11_WINDOW (object));
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_d3d11_window_core_window_unprepare (GstD3D11Window * window)
+{
+  GstD3D11WindowCoreWindow *self = GST_D3D11_WINDOW_CORE_WINDOW (window);
   CoreWindowWinRTStorage *storage = self->storage;
 
   if (storage) {
@@ -356,8 +368,6 @@ gst_d3d11_window_core_window_dispose (GObject * object)
   }
 
   self->storage = NULL;
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static gboolean
index f3c3a0e..8c99e08 100644 (file)
@@ -96,6 +96,9 @@ gst_d3d11_window_swap_chain_panel_on_resize (GstD3D11Window * window,
 static void
 gst_d3d11_window_swap_chain_panel_on_resize_sync (GstD3D11Window *
     window);
+static void
+gst_d3d11_window_swap_chain_panel_unprepare (GstD3D11Window * window);
+
 class PanelResizeHandler
     : public RuntimeClass<RuntimeClassFlags<ClassicCom>,
         Xaml::ISizeChangedEventHandler>
@@ -224,6 +227,8 @@ gst_d3d11_window_swap_chain_panel_class_init (GstD3D11WindowSwapChainPanelClass
       GST_DEBUG_FUNCPTR (gst_d3d11_window_swap_chain_panel_unlock_stop);
   window_class->on_resize =
       GST_DEBUG_FUNCPTR (gst_d3d11_window_swap_chain_panel_on_resize);
+  window_class->unprepare =
+      GST_DEBUG_FUNCPTR (gst_d3d11_window_swap_chain_panel_unprepare);
 }
 
 static void
@@ -304,8 +309,16 @@ error:
 static void
 gst_d3d11_window_swap_chain_panel_dispose (GObject * object)
 {
+  gst_d3d11_window_swap_chain_panel_unprepare (GST_D3D11_WINDOW (object));
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_d3d11_window_swap_chain_panel_unprepare (GstD3D11Window * window)
+{
   GstD3D11WindowSwapChainPanel *self =
-      GST_D3D11_WINDOW_SWAP_CHAIN_PANEL (object);
+      GST_D3D11_WINDOW_SWAP_CHAIN_PANEL (window);
   SwapChainPanelWinRTStorage *storage = self->storage;
 
   if (storage) {
@@ -329,8 +342,6 @@ gst_d3d11_window_swap_chain_panel_dispose (GObject * object)
   }
 
   self->storage = NULL;
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static gboolean
index 762b921..3c0de12 100644 (file)
@@ -118,6 +118,7 @@ gst_d3d11_window_win32_set_window_handle (GstD3D11WindowWin32 * self,
 static void
 gst_d3d11_window_win32_on_resize (GstD3D11Window * window,
     guint width, guint height);
+static void gst_d3d11_window_win32_unprepare (GstD3D11Window * window);
 
 static void
 gst_d3d11_window_win32_class_init (GstD3D11WindowWin32Class * klass)
@@ -139,6 +140,8 @@ gst_d3d11_window_win32_class_init (GstD3D11WindowWin32Class * klass)
   window_class->present = GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_present);
   window_class->on_resize =
       GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_on_resize);
+  window_class->unprepare =
+      GST_DEBUG_FUNCPTR (gst_d3d11_window_win32_unprepare);
 }
 
 static void
@@ -171,11 +174,19 @@ gst_d3d11_window_win32_constructed (GObject * object)
 static void
 gst_d3d11_window_win32_dispose (GObject * object)
 {
-  GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (object);
+  gst_d3d11_window_win32_unprepare (GST_D3D11_WINDOW (object));
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+gst_d3d11_window_win32_unprepare (GstD3D11Window * window)
+{
+  GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window);
 
   gst_d3d11_window_win32_release_external_handle (self);
 
-  if (self->loop) {
+   if (self->loop) {
     g_main_loop_quit (self->loop);
   }
 
@@ -193,8 +204,6 @@ gst_d3d11_window_win32_dispose (GObject * object)
     g_main_context_unref (self->main_context);
     self->main_context = NULL;
   }
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void