d3d12videosink: Add gamma, primaries and sampling filter properties

Add properties to control conversion methods

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5891>
This commit is contained in:
Seungha Yang 2024-01-06 19:31:01 +09:00 committed by GStreamer Marge Bot
parent 368d8b9252
commit 02563605e8
4 changed files with 296 additions and 7 deletions

View file

@ -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": [

View file

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

View file

@ -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);
}

View file

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