mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-03 14:08:56 +00:00
d3d11converter: Add support for premultiplied alpha
Adding "src-alpha-mode" and "dest-alpha-mode" properties and performs premultiplied alpha conversion if needed Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4825>
This commit is contained in:
parent
04bcff4dce
commit
15735a4ef3
2 changed files with 130 additions and 1 deletions
|
@ -91,6 +91,27 @@ gst_d3d11_converter_sampler_filter_get_type (void)
|
|||
return filter_type;
|
||||
}
|
||||
|
||||
GType
|
||||
gst_d3d11_converter_alpha_mode_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
static const GEnumValue alpha_mode[] = {
|
||||
{GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED,
|
||||
"GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED", "unspecified"},
|
||||
{GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED,
|
||||
"GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED", "premultiplied"},
|
||||
{GST_D3D11_CONVERTER_ALPHA_MODE_STRAIGHT,
|
||||
"GST_D3D11_CONVERTER_ALPHA_MODE_STRAIGHT", "straight"},
|
||||
{0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
GST_D3D11_CALL_ONCE_BEGIN {
|
||||
type = g_enum_register_static ("GstD3D11ConverterAlphaMode", alpha_mode);
|
||||
} GST_D3D11_CALL_ONCE_END;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
using namespace Microsoft::WRL;
|
||||
/* *INDENT-ON* */
|
||||
|
@ -124,7 +145,9 @@ typedef struct
|
|||
PSColorSpace to_yuv_buf;
|
||||
PSColorSpace XYZ_convert_buf;
|
||||
FLOAT alpha;
|
||||
FLOAT padding[3];
|
||||
DWORD in_premul_alpha;
|
||||
DWORD out_premul_alpha;
|
||||
FLOAT padding;
|
||||
} PSConstBuffer;
|
||||
|
||||
typedef struct
|
||||
|
@ -525,6 +548,8 @@ static const gchar templ_pixel_shader[] =
|
|||
" PSColorSpace toYUVCoeff;\n"
|
||||
" PSColorSpace primariesCoeff;\n"
|
||||
" float AlphaMul;\n"
|
||||
" dword InPremulAlpha;\n"
|
||||
" dword OutPremulAlpha;\n"
|
||||
"};\n"
|
||||
"Texture2D shaderTexture[4] : register(t0);\n"
|
||||
"Texture1D<float> gammaDecLUT: register(t4);\n"
|
||||
|
@ -551,16 +576,40 @@ static const gchar templ_pixel_shader[] =
|
|||
"%s\n"
|
||||
/* XYZ_convert() function */
|
||||
"%s\n"
|
||||
"float4 alpha_premul (float4 sample)\n"
|
||||
"{\n"
|
||||
" float4 premul_tex;\n"
|
||||
" premul_tex.r = sample.r * sample.a;\n"
|
||||
" premul_tex.g = sample.g * sample.a;\n"
|
||||
" premul_tex.b = sample.b * sample.a;\n"
|
||||
" premul_tex.a = sample.a;\n"
|
||||
" return premul_tex;\n"
|
||||
"}\n"
|
||||
"float4 alpha_unpremul (float4 sample)\n"
|
||||
"{\n"
|
||||
" float4 unpremul_tex;\n"
|
||||
" if (sample.a == 0 || sample.a == 1)\n"
|
||||
" return sample;\n"
|
||||
" unpremul_tex.r = saturate (sample.r / sample.a);\n"
|
||||
" unpremul_tex.g = saturate (sample.g / sample.a);\n"
|
||||
" unpremul_tex.b = saturate (sample.b / sample.a);\n"
|
||||
" unpremul_tex.a = sample.a;\n"
|
||||
" return unpremul_tex;\n"
|
||||
"}\n"
|
||||
"PS_OUTPUT main(PS_INPUT input)\n"
|
||||
"{\n"
|
||||
" float4 sample;\n"
|
||||
" sample = sample_texture (input.Texture);\n"
|
||||
" if (InPremulAlpha)\n"
|
||||
" sample = alpha_unpremul (sample);\n"
|
||||
" sample.a = saturate (sample.a * AlphaMul);\n"
|
||||
" sample.xyz = to_rgb (sample.xyz, toRGBCoeff);\n"
|
||||
" sample.xyz = gamma_decode (sample.xyz);\n"
|
||||
" sample.xyz = XYZ_convert (sample.xyz);\n"
|
||||
" sample.xyz = gamma_encode (sample.xyz);\n"
|
||||
" sample.xyz = to_yuv (sample.xyz, toYUVCoeff);\n"
|
||||
" if (OutPremulAlpha)\n"
|
||||
" sample = alpha_premul (sample);\n"
|
||||
" return build_output (sample);\n"
|
||||
"}\n";
|
||||
|
||||
|
@ -620,6 +669,8 @@ enum
|
|||
PROP_DEST_MASTERING_DISPLAY_INFO,
|
||||
PROP_DEST_CONTENT_LIGHT_LEVEL,
|
||||
PROP_VIDEO_DIRECTION,
|
||||
PROP_SRC_ALPHA_MODE,
|
||||
PROP_DEST_ALPHA_MODE,
|
||||
};
|
||||
|
||||
struct _GstD3D11ConverterPrivate
|
||||
|
@ -727,6 +778,8 @@ struct _GstD3D11ConverterPrivate
|
|||
guint blend_sample_mask;
|
||||
gboolean fill_border;
|
||||
guint64 border_color;
|
||||
GstD3D11ConverterAlphaMode src_alpha_mode;
|
||||
GstD3D11ConverterAlphaMode dst_alpha_mode;
|
||||
};
|
||||
|
||||
static void gst_d3d11_converter_set_property (GObject * object, guint prop_id,
|
||||
|
@ -837,6 +890,14 @@ gst_d3d11_converter_class_init (GstD3D11ConverterClass * klass)
|
|||
g_param_spec_enum ("video-direction", "Video Direction",
|
||||
"Video direction", GST_TYPE_VIDEO_ORIENTATION_METHOD,
|
||||
GST_VIDEO_ORIENTATION_IDENTITY, param_flags));
|
||||
g_object_class_install_property (object_class, PROP_SRC_ALPHA_MODE,
|
||||
g_param_spec_enum ("src-alpha-mode", "Src Alpha Mode",
|
||||
"Src alpha mode to use", GST_TYPE_D3D11_CONVERTER_ALPHA_MODE,
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED, param_flags));
|
||||
g_object_class_install_property (object_class, PROP_DEST_ALPHA_MODE,
|
||||
g_param_spec_enum ("dest-alpha-mode", "Dest Alpha Mode",
|
||||
"Dest alpha mode to use", GST_TYPE_D3D11_CONVERTER_ALPHA_MODE,
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED, param_flags));
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (gst_d3d11_converter_debug,
|
||||
"d3d11converter", 0, "d3d11converter");
|
||||
|
@ -847,6 +908,8 @@ gst_d3d11_converter_init (GstD3D11Converter * self)
|
|||
{
|
||||
self->priv = (GstD3D11ConverterPrivate *)
|
||||
gst_d3d11_converter_get_instance_private (self);
|
||||
self->priv->src_alpha_mode = self->priv->dst_alpha_mode =
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1056,6 +1119,38 @@ gst_d3d11_converter_set_property (GObject * object, guint prop_id,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PROP_SRC_ALPHA_MODE:
|
||||
{
|
||||
DWORD prev_premul = priv->const_data.in_premul_alpha;
|
||||
priv->src_alpha_mode = (GstD3D11ConverterAlphaMode)
|
||||
g_value_get_enum (value);
|
||||
if (priv->src_alpha_mode == GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED) {
|
||||
priv->const_data.in_premul_alpha = TRUE;
|
||||
} else {
|
||||
priv->const_data.in_premul_alpha = FALSE;
|
||||
}
|
||||
|
||||
if (prev_premul != priv->const_data.in_premul_alpha) {
|
||||
priv->update_alpha = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_DEST_ALPHA_MODE:
|
||||
{
|
||||
DWORD prev_premul = priv->const_data.out_premul_alpha;
|
||||
priv->dst_alpha_mode = (GstD3D11ConverterAlphaMode)
|
||||
g_value_get_enum (value);
|
||||
if (priv->dst_alpha_mode == GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED) {
|
||||
priv->const_data.out_premul_alpha = TRUE;
|
||||
} else {
|
||||
priv->const_data.out_premul_alpha = FALSE;
|
||||
}
|
||||
|
||||
if (prev_premul != priv->const_data.out_premul_alpha) {
|
||||
priv->update_alpha = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1137,6 +1232,12 @@ gst_d3d11_converter_get_property (GObject * object, guint prop_id,
|
|||
case PROP_VIDEO_DIRECTION:
|
||||
g_value_set_enum (value, priv->video_direction);
|
||||
break;
|
||||
case PROP_SRC_ALPHA_MODE:
|
||||
g_value_set_enum (value, priv->src_alpha_mode);
|
||||
break;
|
||||
case PROP_DEST_ALPHA_MODE:
|
||||
g_value_set_enum (value, priv->dst_alpha_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -4176,6 +4277,13 @@ gst_d3d11_converter_convert_buffer_internal (GstD3D11Converter * self,
|
|||
if ((priv->supported_backend & GST_D3D11_CONVERTER_BACKEND_SHADER) == 0) {
|
||||
/* processor only */
|
||||
use_processor = TRUE;
|
||||
} else if ((priv->src_alpha_mode ==
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED ||
|
||||
priv->dst_alpha_mode ==
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED)
|
||||
&& GST_VIDEO_INFO_HAS_ALPHA (&priv->in_info)) {
|
||||
/* Needs alpha conversion */
|
||||
use_processor = FALSE;
|
||||
} else if (piv_available) {
|
||||
in_dmem = (GstD3D11Memory *) gst_buffer_peek_memory (in_buf, 0);
|
||||
|
||||
|
|
|
@ -101,6 +101,27 @@ 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())
|
||||
|
||||
/**
|
||||
* GstD3D11ConverterAlphaMode:
|
||||
* @GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED: Unspecified alpha mode
|
||||
* @GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED: Premultiplied alpha
|
||||
* @GST_D3D11_CONVERTER_ALPHA_MODE_STRAIGHT: Straight alpha
|
||||
*
|
||||
* Alpha mode. Enum values are idnetical to DXGI_ALPHA_MODE
|
||||
*
|
||||
* Since: 1.24
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_UNSPECIFIED = 0,
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_PREMULTIPLIED = 1,
|
||||
GST_D3D11_CONVERTER_ALPHA_MODE_STRAIGHT = 2,
|
||||
} GstD3D11ConverterAlphaMode;
|
||||
|
||||
GST_D3D11_API
|
||||
GType gst_d3d11_converter_alpha_mode_get_type (void);
|
||||
#define GST_TYPE_D3D11_CONVERTER_ALPHA_MODE (gst_d3d11_converter_alpha_mode_get_type())
|
||||
|
||||
/**
|
||||
* GstD3D11Converter:
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue