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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7550>
This commit is contained in:
Seungha Yang 2024-09-19 19:31:20 +09:00 committed by GStreamer Marge Bot
parent 9dee102867
commit 71d26ee4f8

View file

@ -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)
{