mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 11:11:08 +00:00
d3d12videosink: Add support for GstColorBalance interface
... and adding hue, saturation, brightness, and contrast properties Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7817>
This commit is contained in:
parent
f94c84c828
commit
dc414415a5
4 changed files with 478 additions and 112 deletions
|
@ -2127,7 +2127,8 @@ gst_d3d12_convert_class_init (GstD3D12ConvertClass * klass)
|
||||||
gst_element_class_set_static_metadata (element_class,
|
gst_element_class_set_static_metadata (element_class,
|
||||||
"Direct3D12 Converter",
|
"Direct3D12 Converter",
|
||||||
"Filter/Converter/Scaler/Effect/Video/Hardware",
|
"Filter/Converter/Scaler/Effect/Video/Hardware",
|
||||||
"Performs resizing, colorspace conversion, cropping and flipping/rotating using Direct3D12",
|
"Performs resizing, colorspace conversion, cropping, flipping/rotating "
|
||||||
|
"and adjusts hue/saturation/brightness/contrast using Direct3D12",
|
||||||
"Seungha Yang <seungha@centricular.com>");
|
"Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d12_convert_sink_event);
|
trans_class->sink_event = GST_DEBUG_FUNCPTR (gst_d3d12_convert_sink_event);
|
||||||
|
@ -2275,8 +2276,8 @@ gst_d3d12_color_convert_class_init (GstD3D12ColorConvertClass * klass)
|
||||||
gst_element_class_set_static_metadata (element_class,
|
gst_element_class_set_static_metadata (element_class,
|
||||||
"Direct3D12 Colorspace Converter",
|
"Direct3D12 Colorspace Converter",
|
||||||
"Filter/Converter/Video/Hardware",
|
"Filter/Converter/Video/Hardware",
|
||||||
"Color conversion using Direct3D12",
|
"Converts colorspace and adjusts hue/saturation/brightness/contrast "
|
||||||
"Seungha Yang <seungha@centricular.com>");
|
"using Direct3D12", "Seungha Yang <seungha@centricular.com>");
|
||||||
|
|
||||||
trans_class->transform_caps =
|
trans_class->transform_caps =
|
||||||
GST_DEBUG_FUNCPTR (gst_d3d12_color_convert_transform_caps);
|
GST_DEBUG_FUNCPTR (gst_d3d12_color_convert_transform_caps);
|
||||||
|
|
|
@ -109,6 +109,10 @@ enum
|
||||||
PROP_ERROR_ON_CLOSED,
|
PROP_ERROR_ON_CLOSED,
|
||||||
PROP_EXTERNAL_WINDOW_ONLY,
|
PROP_EXTERNAL_WINDOW_ONLY,
|
||||||
PROP_DIRECT_SWAPCHAIN,
|
PROP_DIRECT_SWAPCHAIN,
|
||||||
|
PROP_HUE,
|
||||||
|
PROP_SATURATION,
|
||||||
|
PROP_BRIGHTNESS,
|
||||||
|
PROP_CONTRAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_ADAPTER -1
|
#define DEFAULT_ADAPTER -1
|
||||||
|
@ -131,6 +135,10 @@ enum
|
||||||
#define DEFAULT_ERROR_ON_CLOSED TRUE
|
#define DEFAULT_ERROR_ON_CLOSED TRUE
|
||||||
#define DEFAULT_EXTERNAL_WINDOW_ONLY FALSE
|
#define DEFAULT_EXTERNAL_WINDOW_ONLY FALSE
|
||||||
#define DEFAULT_DIRECT_SWAPCHAIN FALSE
|
#define DEFAULT_DIRECT_SWAPCHAIN FALSE
|
||||||
|
#define DEFAULT_HUE 0.0
|
||||||
|
#define DEFAULT_SATURATION 1.0
|
||||||
|
#define DEFAULT_BRIGHTNESS 0.0
|
||||||
|
#define DEFAULT_CONTRAST 1.0
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -162,8 +170,21 @@ struct GstD3D12VideoSinkPrivate
|
||||||
{
|
{
|
||||||
GstD3D12VideoSinkPrivate ()
|
GstD3D12VideoSinkPrivate ()
|
||||||
{
|
{
|
||||||
|
const gchar *channels[4] = { "HUE", "SATURATION",
|
||||||
|
"BRIGHTNESS", "CONTRAST"
|
||||||
|
};
|
||||||
window = gst_d3d12_window_new ();
|
window = gst_d3d12_window_new ();
|
||||||
convert_config = gst_structure_new_empty ("convert-config");
|
convert_config = gst_structure_new_empty ("convert-config");
|
||||||
|
color_balance_channels = nullptr;
|
||||||
|
for (guint i = 0; i < G_N_ELEMENTS (channels); i++) {
|
||||||
|
auto ch = (GstColorBalanceChannel *)
|
||||||
|
g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, nullptr);
|
||||||
|
ch->label = g_strdup (channels[i]);
|
||||||
|
ch->min_value = -1000;
|
||||||
|
ch->max_value = 1000;
|
||||||
|
|
||||||
|
color_balance_channels = g_list_append (color_balance_channels, ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~GstD3D12VideoSinkPrivate ()
|
~GstD3D12VideoSinkPrivate ()
|
||||||
|
@ -175,6 +196,14 @@ struct GstD3D12VideoSinkPrivate
|
||||||
gst_buffer_pool_set_active (pool, FALSE);
|
gst_buffer_pool_set_active (pool, FALSE);
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto iter = color_balance_channels;
|
||||||
|
while (iter) {
|
||||||
|
g_object_unref (iter->data);
|
||||||
|
iter = iter->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (color_balance_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstD3D12Window *window;
|
GstD3D12Window *window;
|
||||||
|
@ -192,6 +221,9 @@ struct GstD3D12VideoSinkPrivate
|
||||||
gboolean warn_closed_window = FALSE;
|
gboolean warn_closed_window = FALSE;
|
||||||
gboolean window_open_called = FALSE;
|
gboolean window_open_called = FALSE;
|
||||||
|
|
||||||
|
GList *color_balance_channels = nullptr;
|
||||||
|
std::atomic<bool> sync_in_progress = { false };
|
||||||
|
|
||||||
std::recursive_mutex lock;
|
std::recursive_mutex lock;
|
||||||
/* properties */
|
/* properties */
|
||||||
std::atomic<gint> adapter = { DEFAULT_ADAPTER };
|
std::atomic<gint> adapter = { DEFAULT_ADAPTER };
|
||||||
|
@ -219,6 +251,10 @@ struct GstD3D12VideoSinkPrivate
|
||||||
std::atomic<gboolean> error_on_closed = { DEFAULT_ERROR_ON_CLOSED };
|
std::atomic<gboolean> error_on_closed = { DEFAULT_ERROR_ON_CLOSED };
|
||||||
gboolean external_only = DEFAULT_EXTERNAL_WINDOW_ONLY;
|
gboolean external_only = DEFAULT_EXTERNAL_WINDOW_ONLY;
|
||||||
std::atomic<gboolean> direct_swapchain = { DEFAULT_DIRECT_SWAPCHAIN };
|
std::atomic<gboolean> direct_swapchain = { DEFAULT_DIRECT_SWAPCHAIN };
|
||||||
|
gdouble hue = DEFAULT_HUE;
|
||||||
|
gdouble saturation = DEFAULT_SATURATION;
|
||||||
|
gdouble brightness = DEFAULT_BRIGHTNESS;
|
||||||
|
gdouble contrast = DEFAULT_CONTRAST;
|
||||||
};
|
};
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
@ -276,6 +312,8 @@ static void
|
||||||
gst_d3d12_video_sink_video_overlay_init (GstVideoOverlayInterface * iface);
|
gst_d3d12_video_sink_video_overlay_init (GstVideoOverlayInterface * iface);
|
||||||
static void
|
static void
|
||||||
gst_d3d12_video_sink_navigation_init (GstNavigationInterface * iface);
|
gst_d3d12_video_sink_navigation_init (GstNavigationInterface * iface);
|
||||||
|
static void
|
||||||
|
gst_d3d12_video_sink_color_balance_init (GstColorBalanceInterface * iface);
|
||||||
|
|
||||||
#define gst_d3d12_video_sink_parent_class parent_class
|
#define gst_d3d12_video_sink_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstD3D12VideoSink, gst_d3d12_video_sink,
|
G_DEFINE_TYPE_WITH_CODE (GstD3D12VideoSink, gst_d3d12_video_sink,
|
||||||
|
@ -284,6 +322,8 @@ G_DEFINE_TYPE_WITH_CODE (GstD3D12VideoSink, gst_d3d12_video_sink,
|
||||||
gst_d3d12_video_sink_video_overlay_init);
|
gst_d3d12_video_sink_video_overlay_init);
|
||||||
G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
|
G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION,
|
||||||
gst_d3d12_video_sink_navigation_init);
|
gst_d3d12_video_sink_navigation_init);
|
||||||
|
G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
|
||||||
|
gst_d3d12_video_sink_color_balance_init);
|
||||||
GST_DEBUG_CATEGORY_INIT (gst_d3d12_video_sink_debug,
|
GST_DEBUG_CATEGORY_INIT (gst_d3d12_video_sink_debug,
|
||||||
"d3d12videosink", 0, "d3d12videosink"));
|
"d3d12videosink", 0, "d3d12videosink"));
|
||||||
|
|
||||||
|
@ -484,6 +524,49 @@ gst_d3d12_video_sink_class_init (GstD3D12VideoSinkClass * klass)
|
||||||
DEFAULT_DIRECT_SWAPCHAIN,
|
DEFAULT_DIRECT_SWAPCHAIN,
|
||||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstD3D12VideoSink:hue:
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_HUE,
|
||||||
|
g_param_spec_double ("hue", "Hue", "hue", -1.0, 1.0, DEFAULT_HUE,
|
||||||
|
(GParamFlags) (GST_PARAM_CONTROLLABLE |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstD3D12VideoSink:saturation:
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_SATURATION,
|
||||||
|
g_param_spec_double ("saturation", "Saturation", "saturation", 0.0, 2.0,
|
||||||
|
DEFAULT_SATURATION,
|
||||||
|
(GParamFlags) (GST_PARAM_CONTROLLABLE |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstD3D12VideoSink:brightness:
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_BRIGHTNESS,
|
||||||
|
g_param_spec_double ("brightness", "Brightness", "brightness", -1.0, 1.0,
|
||||||
|
DEFAULT_BRIGHTNESS,
|
||||||
|
(GParamFlags) (GST_PARAM_CONTROLLABLE |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstD3D12VideoSink:contrast:
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
g_object_class_install_property (object_class, PROP_CONTRAST,
|
||||||
|
g_param_spec_double ("contrast", "Contrast", "contrast", 0.0, 2.0,
|
||||||
|
DEFAULT_CONTRAST,
|
||||||
|
(GParamFlags) (GST_PARAM_CONTROLLABLE |
|
||||||
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstD3D12VideoSink::overlay:
|
* GstD3D12VideoSink::overlay:
|
||||||
* @d3d12videosink: the d3d12videosink element that emitted the signal
|
* @d3d12videosink: the d3d12videosink element that emitted the signal
|
||||||
|
@ -615,118 +698,165 @@ gst_d3d12_video_sink_set_property (GObject * object, guint prop_id,
|
||||||
{
|
{
|
||||||
auto self = GST_D3D12_VIDEO_SINK (object);
|
auto self = GST_D3D12_VIDEO_SINK (object);
|
||||||
auto priv = self->priv;
|
auto priv = self->priv;
|
||||||
|
const gchar *color_balance_label = nullptr;
|
||||||
|
|
||||||
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
{
|
||||||
switch (prop_id) {
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
case PROP_ADAPTER:
|
switch (prop_id) {
|
||||||
priv->adapter = g_value_get_int (value);
|
case PROP_ADAPTER:
|
||||||
break;
|
priv->adapter = g_value_get_int (value);
|
||||||
case PROP_FORCE_ASPECT_RATIO:
|
break;
|
||||||
priv->force_aspect_ratio = g_value_get_boolean (value);
|
case PROP_FORCE_ASPECT_RATIO:
|
||||||
gst_d3d12_window_set_force_aspect_ratio (priv->window,
|
priv->force_aspect_ratio = g_value_get_boolean (value);
|
||||||
priv->force_aspect_ratio);
|
gst_d3d12_window_set_force_aspect_ratio (priv->window,
|
||||||
break;
|
priv->force_aspect_ratio);
|
||||||
case PROP_ENABLE_NAVIGATION_EVENTS:
|
break;
|
||||||
priv->enable_navigation = g_value_get_boolean (value);
|
case PROP_ENABLE_NAVIGATION_EVENTS:
|
||||||
gst_d3d12_window_set_enable_navigation_events (priv->window,
|
priv->enable_navigation = g_value_get_boolean (value);
|
||||||
priv->enable_navigation);
|
gst_d3d12_window_set_enable_navigation_events (priv->window,
|
||||||
break;
|
priv->enable_navigation);
|
||||||
case PROP_ROTATE_METHOD:
|
break;
|
||||||
gst_d3d12_video_sink_set_orientation (self,
|
case PROP_ROTATE_METHOD:
|
||||||
(GstVideoOrientationMethod) g_value_get_enum (value), FALSE);
|
gst_d3d12_video_sink_set_orientation (self,
|
||||||
break;
|
(GstVideoOrientationMethod) g_value_get_enum (value), FALSE);
|
||||||
case PROP_FULLSCREEN_ON_ALT_ENTER:
|
break;
|
||||||
priv->fullscreen_on_alt_enter = g_value_get_boolean (value);
|
case PROP_FULLSCREEN_ON_ALT_ENTER:
|
||||||
gst_d3d12_window_enable_fullscreen_on_alt_enter (priv->window,
|
priv->fullscreen_on_alt_enter = g_value_get_boolean (value);
|
||||||
priv->fullscreen_on_alt_enter);
|
gst_d3d12_window_enable_fullscreen_on_alt_enter (priv->window,
|
||||||
break;
|
priv->fullscreen_on_alt_enter);
|
||||||
case PROP_FULLSCREEN:
|
break;
|
||||||
priv->fullscreen = g_value_get_boolean (value);
|
case PROP_FULLSCREEN:
|
||||||
gst_d3d12_window_set_fullscreen (priv->window, priv->fullscreen);
|
priv->fullscreen = g_value_get_boolean (value);
|
||||||
break;
|
gst_d3d12_window_set_fullscreen (priv->window, priv->fullscreen);
|
||||||
case PROP_MSAA:
|
break;
|
||||||
priv->msaa = (GstD3D12MSAAMode) g_value_get_enum (value);
|
case PROP_MSAA:
|
||||||
gst_d3d12_window_set_msaa (priv->window, priv->msaa);
|
priv->msaa = (GstD3D12MSAAMode) g_value_get_enum (value);
|
||||||
break;
|
gst_d3d12_window_set_msaa (priv->window, priv->msaa);
|
||||||
case PROP_REDRAW_ON_UPDATE:
|
break;
|
||||||
priv->redraw_on_update = g_value_get_boolean (value);
|
case PROP_REDRAW_ON_UPDATE:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->redraw_on_update = g_value_get_boolean (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_FOV:
|
break;
|
||||||
priv->fov = g_value_get_float (value);
|
case PROP_FOV:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->fov = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_ORTHO:
|
break;
|
||||||
priv->ortho = g_value_get_boolean (value);
|
case PROP_ORTHO:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->ortho = g_value_get_boolean (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_ROTATION_X:
|
break;
|
||||||
priv->rotation_x = g_value_get_float (value);
|
case PROP_ROTATION_X:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->rotation_x = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_ROTATION_Y:
|
break;
|
||||||
priv->rotation_y = g_value_get_float (value);
|
case PROP_ROTATION_Y:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->rotation_y = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_ROTATION_Z:
|
break;
|
||||||
priv->rotation_z = g_value_get_float (value);
|
case PROP_ROTATION_Z:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->rotation_z = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_SCALE_X:
|
break;
|
||||||
priv->scale_x = g_value_get_float (value);
|
case PROP_SCALE_X:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->scale_x = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_SCALE_Y:
|
break;
|
||||||
priv->scale_y = g_value_get_float (value);
|
case PROP_SCALE_Y:
|
||||||
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
priv->scale_y = g_value_get_float (value);
|
||||||
break;
|
gst_d3d12_video_sink_set_orientation (self, priv->orientation, FALSE);
|
||||||
case PROP_GAMMA_MODE:
|
break;
|
||||||
{
|
case PROP_GAMMA_MODE:
|
||||||
auto gamma_mode = (GstVideoGammaMode) g_value_get_enum (value);
|
{
|
||||||
if (priv->gamma_mode != gamma_mode) {
|
auto gamma_mode = (GstVideoGammaMode) g_value_get_enum (value);
|
||||||
priv->gamma_mode = gamma_mode;
|
if (priv->gamma_mode != gamma_mode) {
|
||||||
priv->update_window = TRUE;
|
priv->gamma_mode = gamma_mode;
|
||||||
|
priv->update_window = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case PROP_PRIMARIES_MODE:
|
||||||
}
|
{
|
||||||
case PROP_PRIMARIES_MODE:
|
auto primaries_mode = (GstVideoPrimariesMode) g_value_get_enum (value);
|
||||||
{
|
if (priv->primaries_mode != primaries_mode) {
|
||||||
auto primaries_mode = (GstVideoPrimariesMode) g_value_get_enum (value);
|
priv->primaries_mode = primaries_mode;
|
||||||
if (priv->primaries_mode != primaries_mode) {
|
priv->update_window = TRUE;
|
||||||
priv->primaries_mode = primaries_mode;
|
}
|
||||||
priv->update_window = TRUE;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case PROP_SAMPLING_METHOD:
|
||||||
}
|
{
|
||||||
case PROP_SAMPLING_METHOD:
|
auto sampling_method =
|
||||||
{
|
(GstD3D12SamplingMethod) g_value_get_enum (value);
|
||||||
auto sampling_method = (GstD3D12SamplingMethod) g_value_get_enum (value);
|
if (priv->sampling_method != sampling_method) {
|
||||||
if (priv->sampling_method != sampling_method) {
|
priv->sampling_method = sampling_method;
|
||||||
priv->sampling_method = sampling_method;
|
priv->update_window = TRUE;
|
||||||
priv->update_window = TRUE;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case PROP_OVERLAY_MODE:
|
||||||
|
priv->overlay_mode =
|
||||||
|
(GstD3D12WindowOverlayMode) g_value_get_flags (value);
|
||||||
|
gst_d3d12_window_set_overlay_mode (priv->window, priv->overlay_mode);
|
||||||
|
break;
|
||||||
|
case PROP_DISPLAY_FORMAT:
|
||||||
|
priv->display_format = (DXGI_FORMAT) g_value_get_enum (value);
|
||||||
|
break;
|
||||||
|
case PROP_ERROR_ON_CLOSED:
|
||||||
|
priv->error_on_closed = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_EXTERNAL_WINDOW_ONLY:
|
||||||
|
priv->external_only = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_DIRECT_SWAPCHAIN:
|
||||||
|
priv->direct_swapchain = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
case PROP_HUE:
|
||||||
|
if (gst_d3d12_window_set_hue (priv->window,
|
||||||
|
priv->sync_in_progress ? FALSE : priv->redraw_on_update,
|
||||||
|
g_value_get_double (value))) {
|
||||||
|
color_balance_label = "HUE";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_SATURATION:
|
||||||
|
if (gst_d3d12_window_set_saturation (priv->window,
|
||||||
|
priv->sync_in_progress ? FALSE : priv->redraw_on_update,
|
||||||
|
g_value_get_double (value))) {
|
||||||
|
color_balance_label = "SATURATION";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_BRIGHTNESS:
|
||||||
|
if (gst_d3d12_window_set_brightness (priv->window,
|
||||||
|
priv->sync_in_progress ? FALSE : priv->redraw_on_update,
|
||||||
|
g_value_get_double (value))) {
|
||||||
|
color_balance_label = "BRIGHTNESS";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_CONTRAST:
|
||||||
|
if (gst_d3d12_window_set_contrast (priv->window,
|
||||||
|
priv->sync_in_progress ? FALSE : priv->redraw_on_update,
|
||||||
|
g_value_get_double (value))) {
|
||||||
|
color_balance_label = "CONTRAST";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color_balance_label) {
|
||||||
|
GList *iter = priv->color_balance_channels;
|
||||||
|
while (iter) {
|
||||||
|
auto ch = (GstColorBalanceChannel *) iter->data;
|
||||||
|
if (g_ascii_strcasecmp (ch->label, color_balance_label) == 0) {
|
||||||
|
auto iface = GST_COLOR_BALANCE (self);
|
||||||
|
gst_color_balance_value_changed (iface, ch,
|
||||||
|
gst_color_balance_get_value (iface, ch));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = g_list_next (iter);
|
||||||
}
|
}
|
||||||
case PROP_OVERLAY_MODE:
|
|
||||||
priv->overlay_mode =
|
|
||||||
(GstD3D12WindowOverlayMode) g_value_get_flags (value);
|
|
||||||
gst_d3d12_window_set_overlay_mode (priv->window, priv->overlay_mode);
|
|
||||||
break;
|
|
||||||
case PROP_DISPLAY_FORMAT:
|
|
||||||
priv->display_format = (DXGI_FORMAT) g_value_get_enum (value);
|
|
||||||
break;
|
|
||||||
case PROP_ERROR_ON_CLOSED:
|
|
||||||
priv->error_on_closed = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
case PROP_EXTERNAL_WINDOW_ONLY:
|
|
||||||
priv->external_only = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
case PROP_DIRECT_SWAPCHAIN:
|
|
||||||
priv->direct_swapchain = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,6 +938,20 @@ gst_d3d12_video_sink_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_DIRECT_SWAPCHAIN:
|
case PROP_DIRECT_SWAPCHAIN:
|
||||||
g_value_set_boolean (value, priv->direct_swapchain);
|
g_value_set_boolean (value, priv->direct_swapchain);
|
||||||
break;
|
break;
|
||||||
|
case PROP_HUE:
|
||||||
|
g_value_set_double (value, gst_d3d12_window_get_hue (priv->window));
|
||||||
|
break;
|
||||||
|
case PROP_SATURATION:
|
||||||
|
g_value_set_double (value,
|
||||||
|
gst_d3d12_window_get_saturation (priv->window));
|
||||||
|
break;
|
||||||
|
case PROP_BRIGHTNESS:
|
||||||
|
g_value_set_double (value,
|
||||||
|
gst_d3d12_window_get_brightness (priv->window));
|
||||||
|
break;
|
||||||
|
case PROP_CONTRAST:
|
||||||
|
g_value_set_double (value, gst_d3d12_window_get_contrast (priv->window));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1125,7 +1269,10 @@ gst_d3d12_video_sink_set_buffer (GstD3D12VideoSink * self,
|
||||||
GST_TYPE_D3D12_CONVERTER_ALPHA_MODE,
|
GST_TYPE_D3D12_CONVERTER_ALPHA_MODE,
|
||||||
GST_VIDEO_INFO_HAS_ALPHA (&priv->info) ?
|
GST_VIDEO_INFO_HAS_ALPHA (&priv->info) ?
|
||||||
GST_D3D12_CONVERTER_ALPHA_MODE_PREMULTIPLIED :
|
GST_D3D12_CONVERTER_ALPHA_MODE_PREMULTIPLIED :
|
||||||
GST_D3D12_CONVERTER_ALPHA_MODE_UNSPECIFIED, nullptr);
|
GST_D3D12_CONVERTER_ALPHA_MODE_UNSPECIFIED,
|
||||||
|
GST_D3D12_CONVERTER_OPT_COLOR_BALANCE,
|
||||||
|
GST_TYPE_D3D12_CONVERTER_COLOR_BALANCE,
|
||||||
|
GST_D3D12_CONVERTER_COLOR_BALANCE_ENABLED, nullptr);
|
||||||
|
|
||||||
ret = gst_d3d12_window_prepare (priv->window, self->device,
|
ret = gst_d3d12_window_prepare (priv->window, self->device,
|
||||||
GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self), priv->caps,
|
GST_VIDEO_SINK_WIDTH (self), GST_VIDEO_SINK_HEIGHT (self), priv->caps,
|
||||||
|
@ -1477,6 +1624,7 @@ gst_d3d12_video_sink_prepare (GstBaseSink * sink, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
auto self = GST_D3D12_VIDEO_SINK (sink);
|
auto self = GST_D3D12_VIDEO_SINK (sink);
|
||||||
auto priv = self->priv;
|
auto priv = self->priv;
|
||||||
|
auto pts = GST_BUFFER_PTS (buffer);
|
||||||
|
|
||||||
auto ret = gst_d3d12_video_sink_check_device_update (self, buffer);
|
auto ret = gst_d3d12_video_sink_check_device_update (self, buffer);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
|
@ -1486,6 +1634,16 @@ gst_d3d12_video_sink_prepare (GstBaseSink * sink, GstBuffer * buffer)
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (pts)) {
|
||||||
|
auto stream_time = gst_segment_to_stream_time (&sink->segment,
|
||||||
|
GST_FORMAT_TIME, pts);
|
||||||
|
if (GST_CLOCK_TIME_IS_VALID (stream_time)) {
|
||||||
|
priv->sync_in_progress = true;
|
||||||
|
gst_object_sync_values (GST_OBJECT (self), stream_time);
|
||||||
|
priv->sync_in_progress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = gst_d3d12_video_sink_set_buffer (self, buffer, TRUE);
|
ret = gst_d3d12_video_sink_set_buffer (self, buffer, TRUE);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1633,6 +1791,93 @@ gst_d3d12_video_sink_navigation_init (GstNavigationInterface * iface)
|
||||||
iface->send_event_simple = gst_d3d12_video_sink_navigation_send_event;
|
iface->send_event_simple = gst_d3d12_video_sink_navigation_send_event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const GList *
|
||||||
|
gst_d3d12_video_sink_color_balance_list_channels (GstColorBalance * iface)
|
||||||
|
{
|
||||||
|
auto self = GST_D3D12_VIDEO_SINK (iface);
|
||||||
|
auto priv = self->priv;
|
||||||
|
|
||||||
|
return priv->color_balance_channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_d3d12_video_sink_color_balance_set_value (GstColorBalance * iface,
|
||||||
|
GstColorBalanceChannel * channel, gint value)
|
||||||
|
{
|
||||||
|
auto self = GST_D3D12_VIDEO_SINK (iface);
|
||||||
|
auto priv = self->priv;
|
||||||
|
|
||||||
|
gdouble new_val;
|
||||||
|
gboolean changed = FALSE;
|
||||||
|
|
||||||
|
g_return_if_fail (channel->label);
|
||||||
|
|
||||||
|
if (!g_ascii_strcasecmp (channel->label, "HUE")) {
|
||||||
|
new_val = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
|
||||||
|
changed = gst_d3d12_window_set_hue (priv->window, priv->redraw_on_update,
|
||||||
|
new_val);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
|
||||||
|
new_val = (value + 1000.0) * 2.0 / 2000.0;
|
||||||
|
changed = gst_d3d12_window_set_saturation (priv->window,
|
||||||
|
priv->redraw_on_update, new_val);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
|
||||||
|
new_val = (value + 1000.0) * 2.0 / 2000.0 - 1.0;
|
||||||
|
changed = gst_d3d12_window_set_brightness (priv->window,
|
||||||
|
priv->redraw_on_update, new_val);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
|
||||||
|
new_val = (value + 1000.0) * 2.0 / 2000.0;
|
||||||
|
changed = gst_d3d12_window_set_contrast (priv->window,
|
||||||
|
priv->redraw_on_update, new_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
gst_color_balance_value_changed (iface, channel,
|
||||||
|
gst_color_balance_get_value (iface, channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
gst_d3d12_video_sink_color_balance_get_value (GstColorBalance * iface,
|
||||||
|
GstColorBalanceChannel * channel)
|
||||||
|
{
|
||||||
|
auto self = GST_D3D12_VIDEO_SINK (iface);
|
||||||
|
auto priv = self->priv;
|
||||||
|
gint value = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (channel->label, 0);
|
||||||
|
|
||||||
|
if (!g_ascii_strcasecmp (channel->label, "HUE")) {
|
||||||
|
auto hue = gst_d3d12_window_get_hue (priv->window);
|
||||||
|
value = static_cast < gint > ((hue + 1) * 2000.0 / 2.0 - 1000.0);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "SATURATION")) {
|
||||||
|
auto saturation = gst_d3d12_window_get_saturation (priv->window);
|
||||||
|
value = static_cast < gint > (saturation * 2000.0 / 2.0 - 1000.0);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "BRIGHTNESS")) {
|
||||||
|
auto brightness = gst_d3d12_window_get_saturation (priv->window);
|
||||||
|
value = static_cast < gint > ((brightness + 1) * 2000.0 / 2.0 - 1000.0);
|
||||||
|
} else if (!g_ascii_strcasecmp (channel->label, "CONTRAST")) {
|
||||||
|
auto contrast = gst_d3d12_window_get_contrast (priv->window);
|
||||||
|
value = static_cast < gint > (contrast * 2000.0 / 2.0 - 1000.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstColorBalanceType
|
||||||
|
gst_d3d12_video_sink_color_balance_get_balance_type (GstColorBalance * iface)
|
||||||
|
{
|
||||||
|
return GST_COLOR_BALANCE_HARDWARE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_d3d12_video_sink_color_balance_init (GstColorBalanceInterface * iface)
|
||||||
|
{
|
||||||
|
iface->list_channels = gst_d3d12_video_sink_color_balance_list_channels;
|
||||||
|
iface->set_value = gst_d3d12_video_sink_color_balance_set_value;
|
||||||
|
iface->get_value = gst_d3d12_video_sink_color_balance_get_value;
|
||||||
|
iface->get_balance_type = gst_d3d12_video_sink_color_balance_get_balance_type;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_d3d12_video_sink_on_overlay (GstD3D12Window * window,
|
gst_d3d12_video_sink_on_overlay (GstD3D12Window * window,
|
||||||
gpointer command_queue, gpointer resource12, gpointer device11on12,
|
gpointer command_queue, gpointer resource12, gpointer device11on12,
|
||||||
|
|
|
@ -114,6 +114,10 @@ struct GstD3D12WindowPrivate
|
||||||
gfloat rotation_z = 0;
|
gfloat rotation_z = 0;
|
||||||
gfloat scale_x = 1.0f;
|
gfloat scale_x = 1.0f;
|
||||||
gfloat scale_y = 1.0f;
|
gfloat scale_y = 1.0f;
|
||||||
|
gdouble hue = 0.0;
|
||||||
|
gdouble saturation = 1.0;
|
||||||
|
gdouble brightness = 0.0;
|
||||||
|
gdouble contrast = 1.0;
|
||||||
|
|
||||||
/* fullscreen related variables */
|
/* fullscreen related variables */
|
||||||
std::atomic<gboolean> fullscreen_on_alt_enter = { FALSE };
|
std::atomic<gboolean> fullscreen_on_alt_enter = { FALSE };
|
||||||
|
@ -494,7 +498,9 @@ gst_d3d12_window_render (GstD3D12Window * self, SwapChainResource * resource,
|
||||||
|
|
||||||
g_object_set (resource->conv, "dest-x", priv->output_rect.x,
|
g_object_set (resource->conv, "dest-x", priv->output_rect.x,
|
||||||
"dest-y", priv->output_rect.y, "dest-width", priv->output_rect.w,
|
"dest-y", priv->output_rect.y, "dest-width", priv->output_rect.w,
|
||||||
"dest-height", priv->output_rect.h, nullptr);
|
"dest-height", priv->output_rect.h, "hue", priv->hue,
|
||||||
|
"saturation", priv->saturation, "brightness", priv->brightness,
|
||||||
|
"contrast", priv->contrast, nullptr);
|
||||||
|
|
||||||
if (gst_d3d12_need_transform (priv->rotation_x, priv->rotation_y,
|
if (gst_d3d12_need_transform (priv->rotation_x, priv->rotation_y,
|
||||||
priv->rotation_z, priv->scale_x, priv->scale_y)) {
|
priv->rotation_z, priv->scale_x, priv->scale_y)) {
|
||||||
|
@ -1009,3 +1015,93 @@ gst_d3d12_window_get_mouse_pos_info (GstD3D12Window * window,
|
||||||
input_height = priv->input_info.height;
|
input_height = priv->input_info.height;
|
||||||
orientation = priv->orientation;
|
orientation = priv->orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_d3d12_window_update_color_balance (GstD3D12Window * self,
|
||||||
|
gboolean immediate, gdouble * prev, gdouble value)
|
||||||
|
{
|
||||||
|
auto priv = self->priv;
|
||||||
|
gboolean updated = FALSE;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
|
if (*prev != value) {
|
||||||
|
*prev = value;
|
||||||
|
priv->output_updated = TRUE;
|
||||||
|
updated = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated && immediate)
|
||||||
|
gst_d3d12_window_set_buffer (self, nullptr);
|
||||||
|
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d12_window_set_hue (GstD3D12Window * window, gboolean immediate,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
return gst_d3d12_window_update_color_balance (window,
|
||||||
|
immediate, &priv->hue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gst_d3d12_window_get_hue (GstD3D12Window * window)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
|
return priv->hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d12_window_set_saturation (GstD3D12Window * window, gboolean immediate,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
return gst_d3d12_window_update_color_balance (window,
|
||||||
|
immediate, &priv->saturation, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gst_d3d12_window_get_saturation (GstD3D12Window * window)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
|
return priv->saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d12_window_set_brightness (GstD3D12Window * window, gboolean immediate,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
return gst_d3d12_window_update_color_balance (window,
|
||||||
|
immediate, &priv->brightness, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gst_d3d12_window_get_brightness (GstD3D12Window * window)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
|
return priv->brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d12_window_set_contrast (GstD3D12Window * window, gboolean immediate,
|
||||||
|
gdouble value)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
return gst_d3d12_window_update_color_balance (window,
|
||||||
|
immediate, &priv->contrast, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
gdouble
|
||||||
|
gst_d3d12_window_get_contrast (GstD3D12Window * window)
|
||||||
|
{
|
||||||
|
auto priv = window->priv;
|
||||||
|
std::lock_guard < std::recursive_mutex > lk (priv->lock);
|
||||||
|
return priv->contrast;
|
||||||
|
}
|
||||||
|
|
|
@ -163,5 +163,29 @@ void gst_d3d12_window_get_mouse_pos_info (GstD3D12Window * window,
|
||||||
int & input_height,
|
int & input_height,
|
||||||
GstVideoOrientationMethod & orientation);
|
GstVideoOrientationMethod & orientation);
|
||||||
|
|
||||||
|
gboolean gst_d3d12_window_set_hue (GstD3D12Window * window,
|
||||||
|
gboolean immediate,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
|
gdouble gst_d3d12_window_get_hue (GstD3D12Window * window);
|
||||||
|
|
||||||
|
gboolean gst_d3d12_window_set_saturation (GstD3D12Window * window,
|
||||||
|
gboolean immediate,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
|
gdouble gst_d3d12_window_get_saturation (GstD3D12Window * window);
|
||||||
|
|
||||||
|
gboolean gst_d3d12_window_set_brightness (GstD3D12Window * window,
|
||||||
|
gboolean immediate,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
|
gdouble gst_d3d12_window_get_brightness (GstD3D12Window * window);
|
||||||
|
|
||||||
|
gboolean gst_d3d12_window_set_contrast (GstD3D12Window * window,
|
||||||
|
gboolean immediate,
|
||||||
|
gdouble value);
|
||||||
|
|
||||||
|
gdouble gst_d3d12_window_get_contrast (GstD3D12Window * window);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue