diff --git a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json index 6efdb911b0..ed499ee242 100644 --- a/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json +++ b/subprojects/gst-plugins-bad/docs/plugins/gst_plugins_cache.json @@ -11970,6 +11970,104 @@ "type": "gboolean", "writable": true }, + "fov": { + "blurb": "Field of view angle in degrees", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "90", + "max": "3.40282e+38", + "min": "0", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true + }, + "fullscreen": { + "blurb": "Fullscreen mode", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, + "fullscreen-on-alt-enter": { + "blurb": "Enable fullscreen toggle on alt+enter key input", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, + "gamma-mode": { + "blurb": "Gamma conversion mode", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "none (0)", + "mutable": "null", + "readable": true, + "type": "GstVideoGammaMode", + "writable": true + }, + "msaa": { + "blurb": "MSAA (Multi-Sampling Anti-Aliasing) level", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "disabled (0)", + "mutable": "null", + "readable": true, + "type": "GstD3D12MSAAMode", + "writable": true + }, + "ortho": { + "blurb": "Use orthographic projection", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "false", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, + "primaries-mode": { + "blurb": "Primaries conversion mode", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "none (0)", + "mutable": "null", + "readable": true, + "type": "GstVideoPrimariesMode", + "writable": true + }, + "redraw-on-update": { + "blurb": "Immediately apply updated geometry related properties and redraw. If disabled, properties will be applied on the next frame or window resize", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "true", + "mutable": "null", + "readable": true, + "type": "gboolean", + "writable": true + }, "rotate-method": { "blurb": "Rotate method to use", "conditionally-available": false, @@ -11981,6 +12079,88 @@ "readable": true, "type": "GstVideoOrientationMethod", "writable": true + }, + "rotation-x": { + "blurb": "x-axis rotation angle in degrees", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "3.40282e+38", + "min": "-3.40282e+38", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true + }, + "rotation-y": { + "blurb": "y-axis rotation angle in degrees", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "3.40282e+38", + "min": "-3.40282e+38", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true + }, + "rotation-z": { + "blurb": "z-axis rotation angle in degrees", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "0", + "max": "3.40282e+38", + "min": "-3.40282e+38", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true + }, + "sampling-method": { + "blurb": "Sampler filter type to use", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "bilinear (1)", + "mutable": "null", + "readable": true, + "type": "GstD3D12SamplingMethod", + "writable": true + }, + "scale-x": { + "blurb": "Scale multiplier for x-axis", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "1", + "max": "3.40282e+38", + "min": "-3.40282e+38", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true + }, + "scale-y": { + "blurb": "Scale multiplier for y-axis", + "conditionally-available": false, + "construct": false, + "construct-only": false, + "controllable": false, + "default": "1", + "max": "3.40282e+38", + "min": "-3.40282e+38", + "mutable": "null", + "readable": true, + "type": "gfloat", + "writable": true } }, "rank": "none" @@ -12235,6 +12415,31 @@ } ] }, + "GstD3D12MSAAMode": { + "kind": "enum", + "values": [ + { + "desc": "Disabled", + "name": "disabled", + "value": "0" + }, + { + "desc": "2x MSAA", + "name": "2x", + "value": "1" + }, + { + "desc": "4x MSAA", + "name": "4x", + "value": "2" + }, + { + "desc": "8x MSAA", + "name": "8x", + "value": "3" + } + ] + }, "GstD3D12SamplingMethod": { "kind": "enum", "values": [ diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp index 4d65ee9096..13d6e1c621 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12videosink.cpp @@ -46,6 +46,9 @@ enum PROP_ROTATION_Z, PROP_SCALE_X, PROP_SCALE_Y, + PROP_SAMPLING_METHOD, + PROP_GAMMA_MODE, + PROP_PRIMARIES_MODE, }; #define DEFAULT_ADAPTER -1 @@ -60,6 +63,9 @@ enum #define DEFAULT_SCALE 1.0f #define DEFAULT_FOV 90.0f #define DEFAULT_ORTHO FALSE +#define DEFAULT_SAMPLING_METHOD GST_D3D12_SAMPLING_METHOD_BILINEAR +#define DEFAULT_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE +#define DEFAULT_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, @@ -126,6 +132,9 @@ struct GstD3D12VideoSinkPrivate gfloat rotation_z = DEFAULT_ROTATION; gfloat scale_x = DEFAULT_SCALE; gfloat scale_y = DEFAULT_SCALE; + GstVideoGammaMode gamma_mode = DEFAULT_GAMMA_MODE; + GstVideoPrimariesMode primaries_mode = DEFAULT_PRIMARIES_MODE; + GstD3D12SamplingMethod sampling_method = DEFAULT_SAMPLING_METHOD; }; /* *INDENT-ON* */ @@ -293,6 +302,24 @@ gst_d3d12_video_sink_class_init (GstD3D12VideoSinkClass * klass) -G_MAXFLOAT, G_MAXFLOAT, DEFAULT_SCALE, (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + g_object_class_install_property (object_class, PROP_GAMMA_MODE, + g_param_spec_enum ("gamma-mode", "Gamma mode", + "Gamma conversion mode", GST_TYPE_VIDEO_GAMMA_MODE, + DEFAULT_GAMMA_MODE, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_PRIMARIES_MODE, + g_param_spec_enum ("primaries-mode", "Primaries Mode", + "Primaries conversion mode", GST_TYPE_VIDEO_PRIMARIES_MODE, + DEFAULT_PRIMARIES_MODE, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + g_object_class_install_property (object_class, PROP_SAMPLING_METHOD, + g_param_spec_enum ("sampling-method", "Sampling method", + "Sampler filter type to use", GST_TYPE_D3D12_SAMPLING_METHOD, + DEFAULT_SAMPLING_METHOD, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + element_class->set_context = GST_DEBUG_FUNCPTR (gst_d3d12_video_sink_set_context); @@ -318,6 +345,8 @@ gst_d3d12_video_sink_class_init (GstD3D12VideoSinkClass * klass) GST_DEBUG_FUNCPTR (gst_d3d12_video_sink_show_frame); gst_type_mark_as_plugin_api (GST_TYPE_D3D12_MSAA_MODE, (GstPluginAPIFlags) 0); + gst_type_mark_as_plugin_api (GST_TYPE_D3D12_SAMPLING_METHOD, + (GstPluginAPIFlags) 0); } static void @@ -416,6 +445,33 @@ gst_d3d12_videosink_set_property (GObject * object, guint prop_id, priv->scale_y = g_value_get_float (value); gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE); break; + case PROP_GAMMA_MODE: + { + auto gamma_mode = (GstVideoGammaMode) g_value_get_enum (value); + if (priv->gamma_mode != gamma_mode) { + priv->gamma_mode = gamma_mode; + priv->update_window = TRUE; + } + break; + } + case PROP_PRIMARIES_MODE: + { + auto primaries_mode = (GstVideoPrimariesMode) g_value_get_enum (value); + if (priv->primaries_mode != primaries_mode) { + priv->primaries_mode = primaries_mode; + priv->update_window = TRUE; + } + break; + } + case PROP_SAMPLING_METHOD: + { + auto sampling_method = (GstD3D12SamplingMethod) g_value_get_enum (value); + if (priv->sampling_method != sampling_method) { + priv->sampling_method = sampling_method; + priv->update_window = TRUE; + } + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -476,6 +532,15 @@ gst_d3d12_videosink_get_property (GObject * object, guint prop_id, case PROP_SCALE_Y: g_value_set_float (value, priv->scale_y); break; + case PROP_GAMMA_MODE: + g_value_set_enum (value, priv->gamma_mode); + break; + case PROP_PRIMARIES_MODE: + g_value_set_enum (value, priv->primaries_mode); + break; + case PROP_SAMPLING_METHOD: + g_value_set_enum (value, priv->sampling_method); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -737,9 +802,18 @@ gst_d3d12_video_sink_update_window (GstD3D12VideoSink * self) return GST_FLOW_ERROR; } + auto config = gst_structure_new ("convert-config", + GST_D3D12_CONVERTER_OPT_GAMMA_MODE, + GST_TYPE_VIDEO_GAMMA_MODE, priv->gamma_mode, + GST_D3D12_CONVERTER_OPT_PRIMARIES_MODE, + GST_TYPE_VIDEO_PRIMARIES_MODE, priv->primaries_mode, + GST_D3D12_CONVERTER_OPT_SAMPLER_FILTER, + GST_TYPE_D3D12_CONVERTER_SAMPLER_FILTER, + gst_d3d12_sampling_method_to_native (priv->sampling_method), nullptr); + auto ret = gst_d3d12_window_prepare (priv->window, self->device, window_handle, GST_VIDEO_SINK_WIDTH (self), - GST_VIDEO_SINK_HEIGHT (self), priv->caps); + GST_VIDEO_SINK_HEIGHT (self), priv->caps, config); if (ret != GST_FLOW_OK) { if (ret == GST_FLOW_FLUSHING) { GST_WARNING_OBJECT (self, "We are flushing"); @@ -759,7 +833,7 @@ gst_d3d12_video_sink_update_window (GstD3D12VideoSink * self) } priv->pool = gst_d3d12_buffer_pool_new (self->device); - auto config = gst_buffer_pool_get_config (priv->pool); + config = gst_buffer_pool_get_config (priv->pool); gst_buffer_pool_config_set_params (config, priv->caps, priv->info.size, 0, 0); if (!gst_buffer_pool_set_config (priv->pool, config) || diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp index 99bafda108..1647790771 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.cpp @@ -1189,7 +1189,7 @@ gst_d3d12_window_on_resize (GstD3D12Window * self) GstFlowReturn gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, guintptr window_handle, guint display_width, guint display_height, - GstCaps * caps) + GstCaps * caps, GstStructure * config) { auto priv = window->priv; GstVideoInfo in_info; @@ -1222,6 +1222,9 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, auto ret = gst_d3d12_window_prepare_hwnd (window, window_handle); if (ret != GST_FLOW_OK) { GST_WARNING_OBJECT (window, "Couldn't setup window handle"); + if (config) + gst_structure_free (config); + return ret; } @@ -1238,6 +1241,9 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, auto ctx = std::make_unique < DeviceContext > (device); if (!ctx->initialized) { GST_ERROR_OBJECT (window, "Couldn't initialize device context"); + if (config) + gst_structure_free (config); + return GST_FLOW_ERROR; } @@ -1258,6 +1264,9 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, &desc, nullptr, nullptr, &swapchain); if (!gst_d3d12_result (hr, window->device)) { GST_ERROR_OBJECT (window, "Couldn't create swapchain"); + if (config) + gst_structure_free (config); + return GST_FLOW_ERROR; } @@ -1277,6 +1286,8 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, hr = swapchain.As (&ctx->swapchain); if (!gst_d3d12_result (hr, window->device)) { GST_ERROR_OBJECT (window, "IDXGISwapChain4 interface is unavailable"); + if (config) + gst_structure_free (config); return GST_FLOW_ERROR; } @@ -1293,10 +1304,8 @@ gst_d3d12_window_prepare (GstD3D12Window * window, GstD3D12Device * device, gst_clear_object (&priv->ctx->comp); gst_clear_buffer (&priv->ctx->cached_buf); - GstStructure *config = nullptr; if (GST_VIDEO_INFO_HAS_ALPHA (&in_info)) { - config = gst_structure_new ("converter-config", - GST_D3D12_CONVERTER_OPT_DEST_ALPHA_MODE, + gst_structure_set (config, GST_D3D12_CONVERTER_OPT_DEST_ALPHA_MODE, GST_TYPE_D3D12_CONVERTER_ALPHA_MODE, GST_D3D12_CONVERTER_ALPHA_MODE_PREMULTIPLIED, nullptr); } diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h index 2d63d1f155..33683c731b 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12window.h @@ -50,7 +50,8 @@ GstFlowReturn gst_d3d12_window_prepare (GstD3D12Window * window, guintptr window_handle, guint display_width, guint display_height, - GstCaps * caps); + GstCaps * caps, + GstStructure * config); void gst_d3d12_window_unprepare (GstD3D12Window * window);