From 4d6a2dea8917c4d719a23df36fd2eb51264df114 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Mon, 5 Jun 2023 23:44:12 +0900 Subject: [PATCH] d3d11ipcsrc: Stop asynchronously in case of io-mode=import In case of import mode, d3d11ipcsrc does not know when outputted memories will be released. Part-of: --- .../sys/d3d11/gstd3d11ipcclient.cpp | 67 ++++++++++++++++--- .../sys/d3d11/gstd3d11ipcclient.h | 2 + .../gst-plugins-bad/sys/d3d11/plugin.cpp | 11 +++ 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.cpp index 0835a865a2..ea50f47394 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.cpp @@ -37,6 +37,21 @@ using namespace Microsoft::WRL; GST_DEBUG_CATEGORY_STATIC (gst_d3d11_ipc_client_debug); #define GST_CAT_DEFAULT gst_d3d11_ipc_client_debug +static GThreadPool *gc_thread_pool = nullptr; +/* *INDENT-OFF* */ +std::mutex gc_pool_lock; +/* *INDENT-ON* */ + +void +gst_d3d11_ipc_client_deinit (void) +{ + std::lock_guard < std::mutex > lk (gc_pool_lock); + if (gc_thread_pool) { + g_thread_pool_free (gc_thread_pool, FALSE, TRUE); + gc_thread_pool = nullptr; + } +} + GType gst_d3d11_ipc_io_mode_get_type (void) { @@ -998,6 +1013,37 @@ gst_d3d11_ipc_client_get_caps (GstD3D11IpcClient * client) return caps; } +static void +gst_d3d11_ipc_client_stop_async (GstD3D11IpcClient * client, gpointer user_data) +{ + GstD3D11IpcClientPrivate *priv = client->priv; + + GST_DEBUG_OBJECT (client, "Stopping"); + std::unique_lock < std::mutex > lk (priv->lock); + while (!priv->aborted) + priv->cond.wait (lk); + lk.unlock (); + + SetEvent (priv->cancellable); + g_clear_pointer (&priv->loop_thread, g_thread_join); + + GST_DEBUG_OBJECT (client, "Stopped"); + + gst_object_unref (client); +} + +static void +gst_d3d11_ipc_client_push_stop_async (GstD3D11IpcClient * client) +{ + std::lock_guard < std::mutex > lk (gc_pool_lock); + if (!gc_thread_pool) { + gc_thread_pool = g_thread_pool_new ((GFunc) gst_d3d11_ipc_client_stop_async, + nullptr, -1, FALSE, nullptr); + } + + g_thread_pool_push (gc_thread_pool, gst_object_ref (client), nullptr); +} + void gst_d3d11_ipc_client_stop (GstD3D11IpcClient * client) { @@ -1011,18 +1057,23 @@ gst_d3d11_ipc_client_stop (GstD3D11IpcClient * client) priv->shutdown = true; SetEvent (priv->wakeup_event); - std::unique_lock < std::mutex > lk (priv->lock); - while (!priv->aborted) - priv->cond.wait (lk); - lk.unlock (); + if (priv->io_mode == GST_D3D11_IPC_IO_COPY) { + std::unique_lock < std::mutex > lk (priv->lock); + while (!priv->aborted) + priv->cond.wait (lk); + lk.unlock (); - GST_DEBUG_OBJECT (client, "Terminating"); + GST_DEBUG_OBJECT (client, "Terminating"); - SetEvent (priv->cancellable); + SetEvent (priv->cancellable); - g_clear_pointer (&priv->loop_thread, g_thread_join); + g_clear_pointer (&priv->loop_thread, g_thread_join); - GST_DEBUG_OBJECT (client, "Stopped"); + GST_DEBUG_OBJECT (client, "Stopped"); + } else { + /* We don't know when imported memory gets released */ + gst_d3d11_ipc_client_push_stop_async (client); + } } void diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.h b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.h index 79c2274b6f..0470bd16e6 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.h +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11ipcclient.h @@ -38,6 +38,8 @@ GType gst_d3d11_ipc_io_mode_get_type (void); G_DECLARE_FINAL_TYPE (GstD3D11IpcClient, gst_d3d11_ipc_client, GST, D3D11_IPC_CLIENT, GstObject); +void gst_d3d11_ipc_client_deinit (void); + GstD3D11IpcClient * gst_d3d11_ipc_client_new (const std::string & address, GstD3D11Device * device, GstD3D11IpcIOMode io_mode, diff --git a/subprojects/gst-plugins-bad/sys/d3d11/plugin.cpp b/subprojects/gst-plugins-bad/sys/d3d11/plugin.cpp index 89fe8a08e4..429ac69920 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/plugin.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/plugin.cpp @@ -78,6 +78,7 @@ #include "gstd3d11overlay.h" #include "gstd3d11ipcsink.h" #include "gstd3d11ipcsrc.h" +#include "gstd3d11ipcclient.h" #if !GST_D3D11_WINAPI_ONLY_APP #include "gstd3d11screencapturesrc.h" @@ -113,6 +114,12 @@ GST_DEBUG_CATEGORY (gst_d3d11_screen_capture_device_debug); #define GST_CAT_DEFAULT gst_d3d11_debug +static void +plugin_deinit (gpointer data) +{ + gst_d3d11_ipc_client_deinit (); +} + static gboolean plugin_init (GstPlugin * plugin) { @@ -261,6 +268,10 @@ plugin_init (GstPlugin * plugin) } #endif + g_object_set_data_full (G_OBJECT (plugin), + "plugin-d3d11-shutdown", (gpointer) "shutdown-data", + (GDestroyNotify) plugin_deinit); + return TRUE; }