d3d11convert: add "method" property

It allows to select the sampling method, same
as "method" property of videoconvert.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4205>
This commit is contained in:
Aleksandr Slobodeniuk 2023-03-16 22:13:40 +01:00 committed by GStreamer Marge Bot
parent 4c9d4d30cb
commit 1f834eaacb
3 changed files with 188 additions and 4 deletions

View file

@ -69,6 +69,28 @@ gst_d3d11_converter_backend_get_type (void)
return type; return type;
} }
GType
gst_d3d11_converter_sampler_filter_get_type (void)
{
static GType filter_type = 0;
static const GEnumValue filter_types[] = {
{D3D11_FILTER_MIN_MAG_MIP_POINT,
"D3D11_FILTER_MIN_MAG_MIP_POINT", "min-mag-mip-point"},
{D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT,
"D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT", "min-linear-mag-mip-point"},
{D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT,
"D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT", "min-mag-linear-mip-point"},
{0, nullptr, nullptr},
};
GST_D3D11_CALL_ONCE_BEGIN {
filter_type = g_enum_register_static ("GstD3D11ConverterSamplerFilter",
filter_types);
} GST_D3D11_CALL_ONCE_END;
return filter_type;
}
/* *INDENT-OFF* */ /* *INDENT-OFF* */
using namespace Microsoft::WRL; using namespace Microsoft::WRL;
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -1259,7 +1281,8 @@ get_vuya_component (GstVideoFormat format, gchar * y, gchar * u,
static gboolean static gboolean
gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self, gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
const GstVideoInfo * in_info, const GstVideoInfo * out_info) const GstVideoInfo * in_info, const GstVideoInfo * out_info,
D3D11_FILTER sampler_filter)
{ {
GstD3D11ConverterPrivate *priv = self->priv; GstD3D11ConverterPrivate *priv = self->priv;
GstD3D11Device *device = self->device; GstD3D11Device *device = self->device;
@ -1290,7 +1313,7 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
context_handle = gst_d3d11_device_get_device_context_handle (device); context_handle = gst_d3d11_device_get_device_context_handle (device);
/* bilinear filtering */ /* bilinear filtering */
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; sampler_desc.Filter = sampler_filter;
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
@ -3106,6 +3129,7 @@ gst_d3d11_converter_new (GstD3D11Device * device, const GstVideoInfo * in_info,
guint wanted_backend = 0; guint wanted_backend = 0;
gboolean allow_gamma = FALSE; gboolean allow_gamma = FALSE;
gboolean allow_primaries = FALSE; gboolean allow_primaries = FALSE;
D3D11_FILTER sampler_filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
gchar *backend_str; gchar *backend_str;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr); g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr);
@ -3133,6 +3157,8 @@ gst_d3d11_converter_new (GstD3D11Device * device, const GstVideoInfo * in_info,
allow_primaries = TRUE; allow_primaries = TRUE;
} }
gst_structure_get_enum (config, GST_D3D11_CONVERTER_OPT_SAMPLER_FILTER,
GST_TYPE_D3D11_CONVERTER_SAMPLER_FILTER, (int *) &sampler_filter);
gst_structure_free (config); gst_structure_free (config);
} }
@ -3306,8 +3332,10 @@ gst_d3d11_converter_new (GstD3D11Device * device, const GstVideoInfo * in_info,
goto out; goto out;
} }
if (!gst_d3d11_color_convert_setup_shader (self, in_info, out_info)) if (!gst_d3d11_color_convert_setup_shader (self, in_info, out_info,
sampler_filter)) {
goto out; goto out;
}
priv->supported_backend |= GST_D3D11_CONVERTER_BACKEND_SHADER; priv->supported_backend |= GST_D3D11_CONVERTER_BACKEND_SHADER;

View file

@ -81,6 +81,26 @@ GType gst_d3d11_converter_backend_get_type (void);
*/ */
#define GST_D3D11_CONVERTER_OPT_PRIMARIES_MODE "GstD3D11Converter.primaries-mode" #define GST_D3D11_CONVERTER_OPT_PRIMARIES_MODE "GstD3D11Converter.primaries-mode"
/**
* GST_D3D11_CONVERTER_OPT_SAMPLER_FILTER:
*
* #D3D11_FILTER, set sampler filter.
*
* Supported values are:
* @D3D11_FILTER_MIN_MAG_MIP_POINT
* @D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT
* @D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT
*
* Default is #D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT.
*
* Since: 1.24
*/
#define GST_D3D11_CONVERTER_OPT_SAMPLER_FILTER "GstD3D11Converter.sampler-filter"
GST_D3D11_API
GType gst_d3d11_converter_sampler_filter_get_type (void);
#define GST_TYPE_D3D11_CONVERTER_SAMPLER_FILTER (gst_d3d11_converter_sampler_filter_get_type())
/** /**
* GstD3D11Converter: * GstD3D11Converter:
* *

View file

@ -48,10 +48,57 @@ static GstStaticCaps src_template_caps =
GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
GST_D3D11_SRC_FORMATS)); GST_D3D11_SRC_FORMATS));
typedef enum
{
GST_D3D11_SAMPLING_METHOD_NEAREST,
GST_D3D11_SAMPLING_METHOD_BILINEAR,
GST_D3D11_SAMPLING_METHOD_LINEAR_MINIFICATION,
} GstD3D11SamplingMethod;
static const GEnumValue gst_d3d11_sampling_methods[] = {
{GST_D3D11_SAMPLING_METHOD_NEAREST,
"Nearest Neighbour", "nearest-neighbour"},
{GST_D3D11_SAMPLING_METHOD_BILINEAR,
"Bilinear", "bilinear"},
{GST_D3D11_SAMPLING_METHOD_LINEAR_MINIFICATION,
"Linear minification, point magnification", "linear-minification"},
{0, nullptr, nullptr},
};
#define GST_TYPE_D3D11_SAMPLING_METHOD gst_d3d11_sampling_method_get_type()
static GType
gst_d3d11_sampling_method_get_type (void)
{
static GType type = 0;
GST_D3D11_CALL_ONCE_BEGIN {
type = g_enum_register_static ("GstD3D11SamplingMethod",
gst_d3d11_sampling_methods);
} GST_D3D11_CALL_ONCE_END;
return type;
}
static D3D11_FILTER
gst_d3d11_base_convert_sampling_method_to_filter (GstD3D11SamplingMethod method)
{
static const D3D11_FILTER filters[] = {
D3D11_FILTER_MIN_MAG_MIP_POINT, // GST_D3D11_SAMPLING_METHOD_NEAREST
D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT, // GST_D3D11_SAMPLING_METHOD_BILINEAR
D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT, // GST_D3D11_SAMPLING_METHOD_LINEAR_MINIFICATION
};
G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (filters) ==
G_N_ELEMENTS (gst_d3d11_sampling_methods) - 1);
return filters[method];
}
#define DEFAULT_ADD_BORDERS TRUE #define DEFAULT_ADD_BORDERS TRUE
#define DEFAULT_BORDER_COLOR G_GUINT64_CONSTANT(0xffff000000000000) #define DEFAULT_BORDER_COLOR G_GUINT64_CONSTANT(0xffff000000000000)
#define DEFAULT_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE #define DEFAULT_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE
#define DEFAULT_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE #define DEFAULT_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE
#define DEFAULT_SAMPLING_METHOD GST_D3D11_SAMPLING_METHOD_BILINEAR
struct _GstD3D11BaseConvert struct _GstD3D11BaseConvert
{ {
@ -75,6 +122,9 @@ struct _GstD3D11BaseConvert
GstVideoGammaMode gamma_mode; GstVideoGammaMode gamma_mode;
GstVideoPrimariesMode primaries_mode; GstVideoPrimariesMode primaries_mode;
/* sampling method, configured via property */
GstD3D11SamplingMethod sampling_method;
/* orientation */ /* orientation */
/* method configured via property */ /* method configured via property */
GstVideoOrientationMethod method; GstVideoOrientationMethod method;
@ -101,6 +151,18 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstD3D11BaseConvert, gst_d3d11_base_convert,
GST_DEBUG_CATEGORY_INIT (gst_d3d11_convert_debug, "d3d11convert", 0, GST_DEBUG_CATEGORY_INIT (gst_d3d11_convert_debug, "d3d11convert", 0,
"d3d11convert")); "d3d11convert"));
enum
{
PROP_BASE_CONVERT_0,
PROP_BASE_CONVERT_SAMPLING_METHOD,
};
static void
gst_d3d11_base_convert_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void
gst_d3d11_base_convert_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void gst_d3d11_base_convert_dispose (GObject * object); static void gst_d3d11_base_convert_dispose (GObject * object);
static GstCaps *gst_d3d11_base_convert_transform_caps (GstBaseTransform * static GstCaps *gst_d3d11_base_convert_transform_caps (GstBaseTransform *
trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter); trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter);
@ -122,6 +184,9 @@ static GstFlowReturn gst_d3d11_base_convert_transform (GstBaseTransform *
static gboolean gst_d3d11_base_convert_set_info (GstD3D11BaseFilter * filter, static gboolean gst_d3d11_base_convert_set_info (GstD3D11BaseFilter * filter,
GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps, GstCaps * incaps, GstVideoInfo * in_info, GstCaps * outcaps,
GstVideoInfo * out_info); GstVideoInfo * out_info);
static void
gst_d3d11_base_convert_set_sampling_method (GstD3D11BaseConvert * self,
GstD3D11SamplingMethod method);
/* copies the given caps */ /* copies the given caps */
static GstCaps * static GstCaps *
@ -257,8 +322,25 @@ gst_d3d11_base_convert_class_init (GstD3D11BaseConvertClass * klass)
GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass); GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass);
GstCaps *caps; GstCaps *caps;
gobject_class->set_property = gst_d3d11_base_convert_set_property;
gobject_class->get_property = gst_d3d11_base_convert_get_property;
gobject_class->dispose = gst_d3d11_base_convert_dispose; gobject_class->dispose = gst_d3d11_base_convert_dispose;
/**
* GstD3D11BaseConvert:method:
*
* Method used for sampling
*
* Since: 1.24
*/
g_object_class_install_property (gobject_class,
PROP_BASE_CONVERT_SAMPLING_METHOD,
g_param_spec_enum ("method", "Method",
"Method used for sampling",
GST_TYPE_D3D11_SAMPLING_METHOD, DEFAULT_SAMPLING_METHOD,
(GParamFlags) (GST_PARAM_MUTABLE_PLAYING | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)));
caps = gst_d3d11_get_updated_template_caps (&sink_template_caps); caps = gst_d3d11_get_updated_template_caps (&sink_template_caps);
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps)); gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
@ -298,6 +380,7 @@ gst_d3d11_base_convert_init (GstD3D11BaseConvert * self)
self->border_color = DEFAULT_BORDER_COLOR; self->border_color = DEFAULT_BORDER_COLOR;
self->gamma_mode = DEFAULT_GAMMA_MODE; self->gamma_mode = DEFAULT_GAMMA_MODE;
self->primaries_mode = DEFAULT_PRIMARIES_MODE; self->primaries_mode = DEFAULT_PRIMARIES_MODE;
self->sampling_method = DEFAULT_SAMPLING_METHOD;
} }
static void static void
@ -310,6 +393,39 @@ gst_d3d11_base_convert_dispose (GObject * object)
G_OBJECT_CLASS (parent_class)->dispose (object); G_OBJECT_CLASS (parent_class)->dispose (object);
} }
static void
gst_d3d11_base_convert_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstD3D11BaseConvert *base = GST_D3D11_BASE_CONVERT (object);
switch (prop_id) {
case PROP_BASE_CONVERT_SAMPLING_METHOD:
gst_d3d11_base_convert_set_sampling_method (base,
(GstD3D11SamplingMethod) g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_d3d11_base_convert_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstD3D11BaseConvert *base = GST_D3D11_BASE_CONVERT (object);
switch (prop_id) {
case PROP_BASE_CONVERT_SAMPLING_METHOD:
g_value_set_enum (value, base->sampling_method);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GstCaps * static GstCaps *
gst_d3d11_base_convert_transform_caps (GstBaseTransform * gst_d3d11_base_convert_transform_caps (GstBaseTransform *
trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter) trans, GstPadDirection direction, GstCaps * caps, GstCaps * filter)
@ -1541,7 +1657,11 @@ gst_d3d11_base_convert_set_info (GstD3D11BaseFilter * filter,
GST_D3D11_CONVERTER_OPT_GAMMA_MODE, GST_D3D11_CONVERTER_OPT_GAMMA_MODE,
GST_TYPE_VIDEO_GAMMA_MODE, self->gamma_mode, GST_TYPE_VIDEO_GAMMA_MODE, self->gamma_mode,
GST_D3D11_CONVERTER_OPT_PRIMARIES_MODE, GST_D3D11_CONVERTER_OPT_PRIMARIES_MODE,
GST_TYPE_VIDEO_PRIMARIES_MODE, self->primaries_mode, nullptr); GST_TYPE_VIDEO_PRIMARIES_MODE, self->primaries_mode,
GST_D3D11_CONVERTER_OPT_SAMPLER_FILTER,
GST_TYPE_D3D11_CONVERTER_SAMPLER_FILTER,
gst_d3d11_base_convert_sampling_method_to_filter (self->sampling_method),
nullptr);
self->converter = gst_d3d11_converter_new (filter->device, in_info, out_info, self->converter = gst_d3d11_converter_new (filter->device, in_info, out_info,
config); config);
@ -1973,6 +2093,22 @@ gst_d3d11_base_convert_set_primaries_mode (GstD3D11BaseConvert * self,
} }
} }
static void
gst_d3d11_base_convert_set_sampling_method (GstD3D11BaseConvert * self,
GstD3D11SamplingMethod method)
{
GstD3D11SRWLockGuard lk (&self->lock);
GST_DEBUG_OBJECT (self, "Sampling method %s -> %s",
gst_d3d11_sampling_methods[self->sampling_method].value_nick,
gst_d3d11_sampling_methods[method].value_nick);
if (self->sampling_method != method) {
self->sampling_method = method;
gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM_CAST (self));
}
}
/** /**
* SECTION:element-d3d11convert * SECTION:element-d3d11convert
* @title: d3d11convert * @title: d3d11convert