From 11d4b59b737c1a01435e42582d142990a4815ed7 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 12 Jan 2025 23:22:44 +0900 Subject: [PATCH] d3d12videosink: Add max-mip-level property Add support for automatic mipmap generation depending on viewport size Part-of: --- .../sys/d3d12/gstd3d12videosink.cpp | 25 +++++++++++++- .../sys/d3d12/gstd3d12window.cpp | 34 +++++++++++++++++-- .../sys/d3d12/gstd3d12window.h | 6 ++++ 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp index 742b0590ec..3be1666dcd 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp @@ -113,6 +113,7 @@ enum PROP_SATURATION, PROP_BRIGHTNESS, PROP_CONTRAST, + PROP_MAX_MIP_LEVELS, }; #define DEFAULT_ADAPTER -1 @@ -139,6 +140,7 @@ enum #define DEFAULT_SATURATION 1.0 #define DEFAULT_BRIGHTNESS 0.0 #define DEFAULT_CONTRAST 1.0 +#define DEFAULT_MAX_MIP_LEVELS 1 enum { @@ -567,6 +569,18 @@ gst_d3d12_video_sink_class_init (GstD3D12VideoSinkClass * klass) (GParamFlags) (GST_PARAM_CONTROLLABLE | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** + * GstD3D12VideoSink:max-mip-levels: + * + * Since: 1.26 + */ + g_object_class_install_property (object_class, PROP_MAX_MIP_LEVELS, + g_param_spec_uint ("max-mip-levels", "Max Mip Levels", + "Maximum mip levels of shader resource to create " + "if viewport size is smaller than shader resource " + "(0 = maximum level)", 0, G_MAXUINT16, DEFAULT_MAX_MIP_LEVELS, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + /** * GstD3D12VideoSink::overlay: * @d3d12videosink: the d3d12videosink element that emitted the signal @@ -844,6 +858,10 @@ gst_d3d12_video_sink_set_property (GObject * object, guint prop_id, color_balance_label = "CONTRAST"; } break; + case PROP_MAX_MIP_LEVELS: + gst_d3d12_window_set_mip_levels (priv->window, priv->redraw_on_update, + g_value_get_uint (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -958,6 +976,9 @@ gst_d3d12_video_sink_get_property (GObject * object, guint prop_id, case PROP_CONTRAST: g_value_set_double (value, gst_d3d12_window_get_contrast (priv->window)); break; + case PROP_MAX_MIP_LEVELS: + g_value_set_uint (value, gst_d3d12_window_get_mip_levels (priv->window)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1278,7 +1299,9 @@ gst_d3d12_video_sink_set_buffer (GstD3D12VideoSink * self, GST_D3D12_CONVERTER_ALPHA_MODE_UNSPECIFIED, GST_D3D12_CONVERTER_OPT_COLOR_BALANCE, GST_TYPE_D3D12_CONVERTER_COLOR_BALANCE, - GST_D3D12_CONVERTER_COLOR_BALANCE_ENABLED, nullptr); + GST_D3D12_CONVERTER_COLOR_BALANCE_ENABLED, + GST_D3D12_CONVERTER_OPT_MIP_GEN, GST_TYPE_D3D12_CONVERTER_MIP_GEN, + GST_D3D12_CONVERTER_MIP_GEN_ENABLED, nullptr); ret = gst_d3d12_window_prepare (priv->window, self->device, GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self), priv->caps, diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp index 28ce881d3a..c9c43954f5 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp @@ -146,6 +146,7 @@ struct GstD3D12WindowPrivate gdouble saturation = 1.0; gdouble brightness = 0.0; gdouble contrast = 1.0; + guint mip_levels = 1; /* fullscreen related variables */ std::atomic fullscreen_on_alt_enter = { FALSE }; @@ -528,7 +529,8 @@ gst_d3d12_window_render (GstD3D12Window * self, SwapChainResource * resource, "dest-y", priv->output_rect.y, "dest-width", priv->output_rect.w, "dest-height", priv->output_rect.h, "hue", priv->hue, "saturation", priv->saturation, "brightness", priv->brightness, - "contrast", priv->contrast, nullptr); + "contrast", priv->contrast, "max-mip-levels", priv->mip_levels, + nullptr); if (gst_d3d12_need_transform (priv->rotation_x, priv->rotation_y, priv->rotation_z, priv->scale_x, priv->scale_y)) { @@ -790,7 +792,7 @@ gst_d3d12_window_set_buffer (GstD3D12Window * window, GstBuffer * buffer) auto proxy = priv->proxy.lock (); if (!proxy) { - GST_WARNING_OBJECT (window, "Window was closed"); + GST_DEBUG_OBJECT (window, "Window was closed"); return GST_D3D12_WINDOW_FLOW_CLOSED; } @@ -1133,3 +1135,31 @@ gst_d3d12_window_get_contrast (GstD3D12Window * window) std::lock_guard < std::recursive_mutex > lk (priv->lock); return priv->contrast; } + +void +gst_d3d12_window_set_mip_levels (GstD3D12Window * window, gboolean immediate, + guint value) +{ + auto priv = window->priv; + gboolean updated = FALSE; + + { + std::lock_guard < std::recursive_mutex > lk (priv->lock); + if (priv->mip_levels != value) { + priv->mip_levels = value; + priv->output_updated = TRUE; + updated = TRUE; + } + } + + if (updated && immediate) + gst_d3d12_window_set_buffer (window, nullptr); +} + +guint +gst_d3d12_window_get_mip_levels (GstD3D12Window * window) +{ + auto priv = window->priv; + std::lock_guard < std::recursive_mutex > lk (priv->lock); + return priv->mip_levels; +} diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h index fcb5efe110..efc1b4884e 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h @@ -187,5 +187,11 @@ gboolean gst_d3d12_window_set_contrast (GstD3D12Window * window, gdouble gst_d3d12_window_get_contrast (GstD3D12Window * window); +void gst_d3d12_window_set_mip_levels (GstD3D12Window * window, + gboolean immediate, + guint value); + +guint gst_d3d12_window_get_mip_levels (GstD3D12Window * window); + G_END_DECLS