From 71d26ee4f81e63fc5a428fd73944665a0ca844a0 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 19 Sep 2024 19:31:20 +0900 Subject: [PATCH] d3d12swapchainsink: Add auto-resize mode Automatically resize swapchain backbuffer to be identical to stream resolution if user calls resize() signal with zero resolution Part-of: --- .../sys/d3d12/gstd3d12swapchainsink.cpp | 63 ++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12swapchainsink.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12swapchainsink.cpp index 04020be096..ceec02c3f7 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12swapchainsink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12swapchainsink.cpp @@ -179,6 +179,7 @@ struct GstD3D12SwapChainSinkPrivate D3D12_BOX prev_crop_rect = { }; FLOAT border_color_val[4]; GstVideoRectangle viewport = { }; + gboolean auto_resize = FALSE; gint adapter = DEFAULT_ADAPTER; gint force_aspect_ratio = DEFAULT_FORCE_ASPECT_RATIO; @@ -220,6 +221,9 @@ static GstFlowReturn gst_d3d12_swapchain_sink_show_frame (GstVideoSink * sink, GstBuffer * buf); static void gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self, guint width, guint height); +static void +gst_d3d12_swapchain_sink_resize_internal (GstD3D12SwapChainSink * self, + guint width, guint height); #define gst_d3d12_swapchain_sink_parent_class parent_class G_DEFINE_TYPE (GstD3D12SwapChainSink, gst_d3d12_swapchain_sink, @@ -359,7 +363,8 @@ gst_d3d12_swapchain_sink_set_property (GObject * object, guint prop_id, auto val = g_value_get_boolean (value); if (val != priv->force_aspect_ratio) { priv->force_aspect_ratio = val; - gst_d3d12_swapchain_sink_resize (self, priv->width, priv->height); + gst_d3d12_swapchain_sink_resize_internal (self, + priv->width, priv->height); } break; } @@ -385,7 +390,8 @@ gst_d3d12_swapchain_sink_set_property (GObject * object, guint prop_id, auto msaa = (GstD3D12MSAAMode) g_value_get_enum (value); if (priv->msaa_mode != msaa) { priv->msaa_mode = msaa; - gst_d3d12_swapchain_sink_resize (self, priv->width, priv->height); + gst_d3d12_swapchain_sink_resize_internal (self, + priv->width, priv->height); } break; } @@ -904,6 +910,11 @@ gst_d3d12_swapchain_sink_set_buffer (GstD3D12SwapChainSink * self, need_render = true; update_converter = true; priv->caps_updated = false; + if (priv->auto_resize) { + gst_clear_buffer (&priv->cached_buf); + gst_d3d12_swapchain_sink_resize_internal (self, + GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self)); + } } else { need_render = false; update_converter = false; @@ -1007,21 +1018,11 @@ gst_d3d12_swapchain_sink_set_buffer (GstD3D12SwapChainSink * self, } static void -gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self, guint width, - guint height) +gst_d3d12_swapchain_sink_resize_internal (GstD3D12SwapChainSink * self, + guint width, guint height) { auto priv = self->priv; - if (width == 0 || width > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) { - GST_WARNING_OBJECT (self, "Invalid width value %u", width); - return; - } - - if (height == 0 || height > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) { - GST_WARNING_OBJECT (self, "Invalid height value %u", height); - return; - } - std::lock_guard < std::recursive_mutex > lk (priv->lock); if (!gst_d3d12_swapchain_sink_resize_unlocked (self, width, height)) { GST_ERROR_OBJECT (self, "Couldn't resize swapchain"); @@ -1040,6 +1041,40 @@ gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self, guint width, } } +static void +gst_d3d12_swapchain_sink_resize (GstD3D12SwapChainSink * self, guint width, + guint height) +{ + auto priv = self->priv; + + std::lock_guard < std::recursive_mutex > lk (priv->lock); + if (width == 0 && height == 0) { + GST_DEBUG_OBJECT (self, "Enable auto resize"); + priv->auto_resize = TRUE; + if (GST_VIDEO_SINK_WIDTH (self) > 0 && GST_VIDEO_SINK_HEIGHT (self) > 0) { + width = GST_VIDEO_SINK_WIDTH (self); + height = GST_VIDEO_SINK_HEIGHT (self); + } else { + GST_DEBUG_OBJECT (self, "Caps is not configured yet"); + return; + } + } else { + if (width == 0 || width > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) { + GST_WARNING_OBJECT (self, "Invalid width value %u", width); + return; + } + + if (height == 0 || height > D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION) { + GST_WARNING_OBJECT (self, "Invalid height value %u", height); + return; + } + + priv->auto_resize = FALSE; + } + + gst_d3d12_swapchain_sink_resize_internal (self, width, height); +} + static gboolean gst_d3d12_swapchain_sink_start (GstBaseSink * sink) {