d3d11videosink: Add "emit-present" property

Controls the decision for "present" signal use, and
allows delayed "present" signal handler install via the property

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3176>
This commit is contained in:
Seungha Yang 2022-10-14 00:17:52 +09:00 committed by GStreamer Marge Bot
parent f6898303a0
commit 573a0489f6
2 changed files with 27 additions and 12 deletions

View file

@ -64,6 +64,7 @@ enum
PROP_GAMMA_MODE, PROP_GAMMA_MODE,
PROP_PRIMARIES_MODE, PROP_PRIMARIES_MODE,
PROP_DISPLAY_FORMAT, PROP_DISPLAY_FORMAT,
PROP_EMIT_PRESENT,
}; };
#define DEFAULT_ADAPTER -1 #define DEFAULT_ADAPTER -1
@ -75,6 +76,7 @@ enum
#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_DISPLAY_FORMAT DXGI_FORMAT_UNKNOWN #define DEFAULT_DISPLAY_FORMAT DXGI_FORMAT_UNKNOWN
#define DEFAULT_EMIT_PRESENT FALSE
#define GST_TYPE_D3D11_VIDEO_SINK_DISPLAY_FORMAT (gst_d3d11_video_sink_display_format_type()) #define GST_TYPE_D3D11_VIDEO_SINK_DISPLAY_FORMAT (gst_d3d11_video_sink_display_format_type())
static GType static GType
@ -155,6 +157,7 @@ struct _GstD3D11VideoSink
GstVideoGammaMode gamma_mode; GstVideoGammaMode gamma_mode;
GstVideoPrimariesMode primaries_mode; GstVideoPrimariesMode primaries_mode;
DXGI_FORMAT display_format; DXGI_FORMAT display_format;
gboolean emit_present;
/* saved render rectangle until we have a window */ /* saved render rectangle until we have a window */
GstVideoRectangle render_rect; GstVideoRectangle render_rect;
@ -352,6 +355,19 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass)
DEFAULT_DISPLAY_FORMAT, (GParamFlags) (G_PARAM_READWRITE | DEFAULT_DISPLAY_FORMAT, (GParamFlags) (G_PARAM_READWRITE |
GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS))); GST_PARAM_MUTABLE_READY | G_PARAM_STATIC_STRINGS)));
/**
* GstD3D11VideoSink:emit-present:
*
* Emits "present" signal
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_EMIT_PRESENT,
g_param_spec_boolean ("emit-present", "Emit present",
"Emits present signal", DEFAULT_EMIT_PRESENT,
(GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
G_PARAM_STATIC_STRINGS)));
/** /**
* GstD3D11VideoSink::begin-draw: * GstD3D11VideoSink::begin-draw:
* @videosink: the #d3d11videosink * @videosink: the #d3d11videosink
@ -407,10 +423,6 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass)
* client should perform GPU operation from the thread where this signal * client should perform GPU operation from the thread where this signal
* emitted. * emitted.
* *
* If a client wants to listen this signal, the client must connect this
* signal before the first present. Otherwise this signal will not be
* emitted.
*
* Since: 1.22 * Since: 1.22
*/ */
gst_d3d11_video_sink_signals[SIGNAL_PRESENT] = gst_d3d11_video_sink_signals[SIGNAL_PRESENT] =
@ -466,6 +478,7 @@ gst_d3d11_video_sink_init (GstD3D11VideoSink * self)
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->display_format = DEFAULT_DISPLAY_FORMAT; self->display_format = DEFAULT_DISPLAY_FORMAT;
self->emit_present = DEFAULT_EMIT_PRESENT;
InitializeCriticalSection (&self->lock); InitializeCriticalSection (&self->lock);
} }
@ -524,6 +537,9 @@ gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
case PROP_DISPLAY_FORMAT: case PROP_DISPLAY_FORMAT:
self->display_format = (DXGI_FORMAT) g_value_get_enum (value); self->display_format = (DXGI_FORMAT) g_value_get_enum (value);
break; break;
case PROP_EMIT_PRESENT:
self->emit_present = g_value_get_boolean (value);
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;
@ -572,6 +588,9 @@ gst_d3d11_videosink_get_property (GObject * object, guint prop_id,
case PROP_DISPLAY_FORMAT: case PROP_DISPLAY_FORMAT:
g_value_set_enum (value, self->display_format); g_value_set_enum (value, self->display_format);
break; break;
case PROP_EMIT_PRESENT:
g_value_set_boolean (value, self->emit_present);
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;
@ -869,7 +888,6 @@ static gboolean
gst_d3d11_video_sink_prepare_window (GstD3D11VideoSink * self) gst_d3d11_video_sink_prepare_window (GstD3D11VideoSink * self)
{ {
GstD3D11WindowNativeType window_type = GST_D3D11_WINDOW_NATIVE_TYPE_HWND; GstD3D11WindowNativeType window_type = GST_D3D11_WINDOW_NATIVE_TYPE_HWND;
gboolean emit_present = FALSE;
if (self->window) if (self->window)
return TRUE; return TRUE;
@ -933,18 +951,12 @@ done:
return FALSE; return FALSE;
} }
/* Emits present signal only if signal is connected for performance reason */
if (g_signal_has_handler_pending (self,
gst_d3d11_video_sink_signals[SIGNAL_PRESENT], 0, FALSE)) {
emit_present = TRUE;
}
g_object_set (self->window, g_object_set (self->window,
"force-aspect-ratio", self->force_aspect_ratio, "force-aspect-ratio", self->force_aspect_ratio,
"fullscreen-toggle-mode", self->fullscreen_toggle_mode, "fullscreen-toggle-mode", self->fullscreen_toggle_mode,
"fullscreen", self->fullscreen, "fullscreen", self->fullscreen,
"enable-navigation-events", self->enable_navigation_events, "enable-navigation-events", self->enable_navigation_events,
"emit-present", emit_present, nullptr); "emit-present", self->emit_present, nullptr);
gst_d3d11_window_set_orientation (self->window, self->selected_method); gst_d3d11_window_set_orientation (self->window, self->selected_method);

View file

@ -616,6 +616,9 @@ main (gint argc, gchar ** argv)
context.sink = gst_element_factory_make ("d3d11videosink", nullptr); context.sink = gst_element_factory_make ("d3d11videosink", nullptr);
g_assert (context.sink); g_assert (context.sink);
/* Enables present signal */
g_object_set (context.sink, "emit-present", TRUE, nullptr);
/* D2D <-> DXGI interop requires BGRA format */ /* D2D <-> DXGI interop requires BGRA format */
g_object_set (context.sink, "display-format", DXGI_FORMAT_B8G8R8A8_UNORM, g_object_set (context.sink, "display-format", DXGI_FORMAT_B8G8R8A8_UNORM,
nullptr); nullptr);