From f89cb98495bb84b80ffbcdcb8d0566df9df7452e Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Wed, 3 Aug 2022 01:47:46 +0900 Subject: [PATCH] d3d11videosink: Add gamma-mode and primaries-mode properties Allows controlling gamma remap and/or chromatic adaptation behavior. Part-of: --- .../sys/d3d11/gstd3d11videosink.cpp | 55 +++++++++++++++++++++- .../gst-plugins-bad/sys/d3d11/gstd3d11window.cpp | 23 +++++++-- .../gst-plugins-bad/sys/d3d11/gstd3d11window.h | 2 + .../sys/d3d11/gstd3d11window_dummy.cpp | 23 ++++++--- 4 files changed, 90 insertions(+), 13 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp index 76389d9..0a0f47e 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11videosink.cpp @@ -61,6 +61,8 @@ enum PROP_FULLSCREEN, PROP_DRAW_ON_SHARED_TEXTURE, PROP_ROTATE_METHOD, + PROP_GAMMA_MODE, + PROP_PRIMARIES_MODE, }; #define DEFAULT_ADAPTER -1 @@ -69,6 +71,8 @@ enum #define DEFAULT_FULLSCREEN_TOGGLE_MODE GST_D3D11_WINDOW_FULLSCREEN_TOGGLE_MODE_NONE #define DEFAULT_FULLSCREEN FALSE #define DEFAULT_DRAW_ON_SHARED_TEXTURE FALSE +#define DEFAULT_GAMMA_MODE GST_VIDEO_GAMMA_MODE_NONE +#define DEFAULT_PRIMARIES_MODE GST_VIDEO_PRIMARIES_MODE_NONE enum { @@ -120,6 +124,8 @@ struct _GstD3D11VideoSink GstD3D11WindowFullscreenToggleMode fullscreen_toggle_mode; gboolean fullscreen; gboolean draw_on_shared_texture; + GstVideoGammaMode gamma_mode; + GstVideoPrimariesMode primaries_mode; /* saved render rectangle until we have a window */ GstVideoRectangle render_rect; @@ -291,6 +297,32 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); /** + * GstD3D11VideoSink:gamma-mode: + * + * Gamma conversion mode + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_GAMMA_MODE, + g_param_spec_enum ("gamma-mode", "Gamma mode", + "Gamma conversion mode", GST_TYPE_VIDEO_GAMMA_MODE, + DEFAULT_GAMMA_MODE, (GParamFlags) (GST_PARAM_MUTABLE_READY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + /** + * GstD3D11VideoSink:primaries-mode: + * + * Primaries conversion mode + * + * Since: 1.22 + */ + g_object_class_install_property (gobject_class, PROP_PRIMARIES_MODE, + g_param_spec_enum ("primaries-mode", "Primaries Mode", + "Primaries conversion mode", GST_TYPE_VIDEO_PRIMARIES_MODE, + DEFAULT_PRIMARIES_MODE, (GParamFlags) (GST_PARAM_MUTABLE_READY | + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); + + /** * GstD3D11VideoSink::begin-draw: * @videosink: the #d3d11videosink * @@ -374,6 +406,8 @@ gst_d3d11_video_sink_init (GstD3D11VideoSink * self) self->fullscreen_toggle_mode = DEFAULT_FULLSCREEN_TOGGLE_MODE; self->fullscreen = DEFAULT_FULLSCREEN; self->draw_on_shared_texture = DEFAULT_DRAW_ON_SHARED_TEXTURE; + self->gamma_mode = DEFAULT_GAMMA_MODE; + self->primaries_mode = DEFAULT_PRIMARIES_MODE; g_rec_mutex_init (&self->lock); } @@ -423,6 +457,12 @@ gst_d3d11_videosink_set_property (GObject * object, guint prop_id, gst_d3d11_video_sink_set_orientation (self, (GstVideoOrientationMethod) g_value_get_enum (value), FALSE); break; + case PROP_GAMMA_MODE: + self->gamma_mode = (GstVideoGammaMode) g_value_get_enum (value); + break; + case PROP_PRIMARIES_MODE: + self->primaries_mode = (GstVideoPrimariesMode) g_value_get_enum (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -463,6 +503,12 @@ gst_d3d11_videosink_get_property (GObject * object, guint prop_id, case PROP_ROTATE_METHOD: g_value_set_enum (value, self->method); break; + case PROP_GAMMA_MODE: + g_value_set_enum (value, self->gamma_mode); + break; + case PROP_PRIMARIES_MODE: + g_value_set_enum (value, self->primaries_mode); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -558,6 +604,7 @@ gst_d3d11_video_sink_update_window (GstD3D11VideoSink * self, GstCaps * caps) gint display_par_n = 1, display_par_d = 1; /* display's PAR */ guint num, den; GError *error = NULL; + GstStructure *config; GST_DEBUG_OBJECT (self, "Updating window with caps %" GST_PTR_FORMAT, caps); @@ -649,8 +696,14 @@ gst_d3d11_video_sink_update_window (GstD3D11VideoSink * self, GstCaps * caps) gst_d3d11_window_set_render_rectangle (self->window, &rect); } + config = gst_structure_new ("convert-config", + GST_D3D11_CONVERTER_OPT_GAMMA_MODE, + GST_TYPE_VIDEO_GAMMA_MODE, self->gamma_mode, + GST_D3D11_CONVERTER_OPT_PRIMARIES_MODE, + GST_TYPE_VIDEO_PRIMARIES_MODE, self->primaries_mode, nullptr); + if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self), - GST_VIDEO_SINK_HEIGHT (self), caps, &error)) { + GST_VIDEO_SINK_HEIGHT (self), caps, config, &error)) { GstMessage *error_msg; GST_D3D11_VIDEO_SINK_UNLOCK (self); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp index bdb7801..1222669 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.cpp @@ -107,7 +107,8 @@ static GstFlowReturn gst_d3d111_window_present (GstD3D11Window * self, static void gst_d3d11_window_on_resize_default (GstD3D11Window * window, guint width, guint height); static gboolean gst_d3d11_window_prepare_default (GstD3D11Window * window, - guint display_width, guint display_height, GstCaps * caps, GError ** error); + guint display_width, guint display_height, GstCaps * caps, + GstStructure * config, GError ** error); static void gst_d3d11_window_class_init (GstD3D11WindowClass * klass) @@ -496,7 +497,8 @@ typedef struct gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width, - guint display_height, GstCaps * caps, GError ** error) + guint display_height, GstCaps * caps, GstStructure * config, + GError ** error) { GstD3D11WindowClass *klass; @@ -508,12 +510,14 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width, GST_DEBUG_OBJECT (window, "Prepare window, display resolution %dx%d, caps %" GST_PTR_FORMAT, display_width, display_height, caps); - return klass->prepare (window, display_width, display_height, caps, error); + return klass->prepare (window, display_width, display_height, caps, config, + error); } static gboolean gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, - guint display_height, GstCaps * caps, GError ** error) + guint display_height, GstCaps * caps, GstStructure * config, + GError ** error) { GstD3D11Device *device = window->device; GstD3D11WindowClass *klass; @@ -549,6 +553,9 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, (GstD3D11Allocator *) gst_allocator_find (GST_D3D11_MEMORY_NAME); if (!window->allocator) { GST_ERROR_OBJECT (window, "Allocator is unavailable"); + if (config) + gst_structure_free (config); + return FALSE; } } @@ -580,6 +587,9 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, GST_ERROR_OBJECT (window, "Cannot determine render format"); g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED, "Cannot determine render format"); + if (config) + gst_structure_free (config); + return FALSE; } @@ -644,6 +654,9 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, GST_ERROR_OBJECT (window, "Cannot create swapchain"); g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED, "Cannot create swapchain"); + if (config) + gst_structure_free (config); + return FALSE; } @@ -726,7 +739,7 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width, &window->render_info); window->converter = gst_d3d11_converter_new (device, - &window->info, &window->render_info, nullptr); + &window->info, &window->render_info, config); if (!window->converter) { GST_ERROR_OBJECT (window, "Cannot create converter"); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h index 3a4bfdc..bc5181f 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window.h @@ -150,6 +150,7 @@ struct _GstD3D11WindowClass guint display_width, guint display_height, GstCaps * caps, + GstStructure * config, GError ** error); void (*unprepare) (GstD3D11Window * window); @@ -184,6 +185,7 @@ gboolean gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width, guint display_height, GstCaps * caps, + GstStructure * config, GError ** error); GstFlowReturn gst_d3d11_window_render (GstD3D11Window * window, diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp index c92ccd0..32a5e69 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11window_dummy.cpp @@ -51,7 +51,8 @@ G_DEFINE_TYPE (GstD3D11WindowDummy, gst_d3d11_window_dummy, static void gst_d3d11_window_dummy_on_resize (GstD3D11Window * window, guint width, guint height); static gboolean gst_d3d11_window_dummy_prepare (GstD3D11Window * window, - guint display_width, guint display_height, GstCaps * caps, GError ** error); + guint display_width, guint display_height, GstCaps * caps, + GstStructure * config, GError ** error); static void gst_d3d11_window_dummy_unprepare (GstD3D11Window * window); static gboolean gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window, @@ -83,15 +84,17 @@ gst_d3d11_window_dummy_init (GstD3D11WindowDummy * self) static gboolean gst_d3d11_window_dummy_prepare (GstD3D11Window * window, - guint display_width, guint display_height, GstCaps * caps, GError ** error) + guint display_width, guint display_height, GstCaps * caps, + GstStructure * config, GError ** error) { - GstStructure *config; - if (!window->allocator) { window->allocator = (GstD3D11Allocator *) gst_allocator_find (GST_D3D11_MEMORY_NAME); if (!window->allocator) { GST_ERROR_OBJECT (window, "Allocator is unavailable"); + if (config) + gst_structure_free (config); + return FALSE; } } @@ -122,9 +125,15 @@ gst_d3d11_window_dummy_prepare (GstD3D11Window * window, window->render_info.colorimetry.transfer = GST_VIDEO_TRANSFER_BT709; window->render_info.colorimetry.range = GST_VIDEO_COLOR_RANGE_0_255; - config = gst_structure_new ("converter-config", - GST_D3D11_CONVERTER_OPT_BACKEND, GST_TYPE_D3D11_CONVERTER_BACKEND, - GST_D3D11_CONVERTER_BACKEND_SHADER, nullptr); + if (config) { + gst_structure_set (config, GST_D3D11_CONVERTER_OPT_BACKEND, + GST_TYPE_D3D11_CONVERTER_BACKEND, GST_D3D11_CONVERTER_BACKEND_SHADER, + nullptr); + } else { + config = gst_structure_new ("converter-config", + GST_D3D11_CONVERTER_OPT_BACKEND, GST_TYPE_D3D11_CONVERTER_BACKEND, + GST_D3D11_CONVERTER_BACKEND_SHADER, nullptr); + } GstD3D11DeviceLockGuard lk (window->device); window->converter = gst_d3d11_converter_new (window->device, &window->info, -- 2.7.4