From 094bfbedfc6e428cdb8a4ddfea039925ec5c375e Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sat, 17 Apr 2021 20:37:13 +0900 Subject: [PATCH] d3d11: Remove d3d11videosink wrapper bin Drop d3d11videosink wrapper bin and handle texture upload in d3d11videosink. Part-of: --- sys/d3d11/gstd3d11videosink.cpp | 228 +++++++---------- sys/d3d11/gstd3d11videosink.h | 21 -- sys/d3d11/gstd3d11videosinkbin.cpp | 507 ------------------------------------- sys/d3d11/gstd3d11videosinkbin.h | 57 ----- sys/d3d11/meson.build | 1 - sys/d3d11/plugin.c | 6 +- 6 files changed, 88 insertions(+), 732 deletions(-) delete mode 100644 sys/d3d11/gstd3d11videosinkbin.cpp delete mode 100644 sys/d3d11/gstd3d11videosinkbin.h diff --git a/sys/d3d11/gstd3d11videosink.cpp b/sys/d3d11/gstd3d11videosink.cpp index 57cc106..a608ba5 100644 --- a/sys/d3d11/gstd3d11videosink.cpp +++ b/sys/d3d11/gstd3d11videosink.cpp @@ -19,18 +19,16 @@ */ /** - * SECTION:element-d3d11videosinkelement - * @title: d3d11videosinkelement + * SECTION:element-d3d11videosink + * @title: d3d11videosink * - * Direct3D11 based video render element. This element allows only Direct3D11 - * textures as a input. Use #d3d11videosink instead which is a convenient - * wrapper of #d3d11videosinkelement with #d3d11upload. + * Direct3D11 based video render element * * ## Example launch line * ``` - * gst-launch-1.0 videotestsrc ! d3d11upload ! d3d11videosinkelement + * gst-launch-1.0 videotestsrc ! d3d11upload ! d3d11videosink * ``` - * This pipeline will display test video stream on screen via d3d11videosinkelement + * This pipeline will display test video stream on screen via d3d11videosink * * Since: 1.18 * @@ -91,6 +89,11 @@ static GstStaticCaps pad_template_caps = GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_SINK_FORMATS) ";" + GST_VIDEO_CAPS_MAKE (GST_D3D11_SINK_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, GST_D3D11_SINK_FORMATS)); GST_DEBUG_CATEGORY (d3d11_video_sink_debug); @@ -121,13 +124,10 @@ struct _GstD3D11VideoSink gboolean pending_render_rect; GstBufferPool *fallback_pool; - gboolean can_convert; gboolean have_video_processor; gboolean processor_in_use; /* For drawing on user texture */ - GstD3D11VideoSinkCallbacks callbacks; - gpointer user_data; gboolean drawing; GstBuffer *current_buffer; GRecMutex draw_lock; @@ -230,8 +230,8 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) * GstD3D11VideoSink:draw-on-shared-texture: * * Instruct the sink to draw on a shared texture provided by user. - * User must watch #d3d11videosinkelement::begin-draw signal and should call - * #d3d11videosinkelement::draw method on the #d3d11videosinkelement::begin-draw + * User must watch #d3d11videosink::begin-draw signal and should call + * #d3d11videosink::draw method on the #d3d11videosink::begin-draw * signal handler. * * Currently supported formats for user texture are: @@ -257,11 +257,11 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) /** * GstD3D11VideoSink::begin-draw: - * @videosink: the #d3d11videosinkelement + * @videosink: the #d3d11videosink * * Emitted when sink has a texture to draw. Application needs to invoke - * #d3d11videosinkelement::draw action signal before returning from - * #d3d11videosinkelement::begin-draw signal handler. + * #d3d11videosink::draw action signal before returning from + * #d3d11videosink::begin-draw signal handler. * * Since: 1.20 */ @@ -272,7 +272,7 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) /** * GstD3D11VideoSink::draw: - * @videosink: the #d3d11videosinkelement + * @videosink: the #d3d11videosink * @shard_handle: a pointer to HANDLE * @texture_misc_flags: a D3D11_RESOURCE_MISC_FLAG value * @acquire_key: a key value used for IDXGIKeyedMutex::AcquireSync @@ -446,93 +446,42 @@ gst_d3d11_video_sink_set_context (GstElement * element, GstContext * context) } static GstCaps * -gst_d3d11_video_sink_get_supported_caps (GstD3D11VideoSink * self, - D3D11_FORMAT_SUPPORT flags) +gst_d3d11_video_sink_get_caps (GstBaseSink * sink, GstCaps * filter) { - GstD3D11Device *device; - ID3D11Device *d3d11_device; - HRESULT hr; - guint i; - GValue v_list = G_VALUE_INIT; - GstCaps *supported_caps; - static const GstVideoFormat format_list[] = { - GST_VIDEO_FORMAT_BGRA, - GST_VIDEO_FORMAT_RGBA, - GST_VIDEO_FORMAT_RGB10A2_LE, - GST_VIDEO_FORMAT_VUYA, - GST_VIDEO_FORMAT_NV12, - GST_VIDEO_FORMAT_P010_10LE, - GST_VIDEO_FORMAT_P016_LE, - GST_VIDEO_FORMAT_I420, - GST_VIDEO_FORMAT_I420_10LE, - }; - - device = self->device; - - d3d11_device = gst_d3d11_device_get_device_handle (device); - g_value_init (&v_list, GST_TYPE_LIST); - - for (i = 0; i < G_N_ELEMENTS (format_list); i++) { - UINT format_support = 0; - GstVideoFormat format; - const GstD3D11Format *d3d11_format; - - d3d11_format = gst_d3d11_device_format_from_gst (device, format_list[i]); - if (!d3d11_format || d3d11_format->dxgi_format == DXGI_FORMAT_UNKNOWN) - continue; - - format = d3d11_format->format; - hr = d3d11_device->CheckFormatSupport (d3d11_format->dxgi_format, - &format_support); - - if (SUCCEEDED (hr) && ((format_support & flags) == flags)) { - GValue v_str = G_VALUE_INIT; - g_value_init (&v_str, G_TYPE_STRING); - - GST_LOG_OBJECT (self, "d3d11 device can support %s with flags 0x%x", - gst_video_format_to_string (format), flags); - g_value_set_string (&v_str, gst_video_format_to_string (format)); - gst_value_list_append_and_take_value (&v_list, &v_str); - } - } + GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); + GstCaps *caps = NULL; - supported_caps = gst_caps_new_simple ("video/x-raw", - "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL); - gst_caps_set_value (supported_caps, "format", &v_list); - g_value_unset (&v_list); + caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); - gst_caps_set_features_simple (supported_caps, - gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)); + if (self->device) { + gboolean is_hardware = FALSE; - return supported_caps; -} + g_object_get (self->device, "hardware", &is_hardware, NULL); -static GstCaps * -gst_d3d11_video_sink_get_caps (GstBaseSink * sink, GstCaps * filter) -{ - GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); - GstCaps *caps = NULL; + /* In case of WARP device, conversion via shader would be inefficient than + * upstream videoconvert. Allow native formats in this case */ + if (!is_hardware) { + GValue format_list = G_VALUE_INIT; + GValue format = G_VALUE_INIT; - if (self->device && !self->can_convert) { - GstCaps *overlaycaps; - GstCapsFeatures *features; + g_value_init (&format_list, GST_TYPE_LIST); + g_value_init (&format, G_TYPE_STRING); - caps = gst_d3d11_video_sink_get_supported_caps (self, - (D3D11_FORMAT_SUPPORT) (D3D11_FORMAT_SUPPORT_TEXTURE2D | - D3D11_FORMAT_SUPPORT_DISPLAY)); - overlaycaps = gst_caps_copy (caps); - features = gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, NULL); - gst_caps_set_features_simple (overlaycaps, features); - gst_caps_append (caps, overlaycaps); - } + g_value_set_string (&format, "RGBA"); + gst_value_list_append_and_take_value (&format_list, &format); - if (!caps) - caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink)); + format = G_VALUE_INIT; + g_value_init (&format, G_TYPE_STRING); + g_value_set_string (&format, "BGRA"); + gst_value_list_append_and_take_value (&format_list, &format); - if (caps && filter) { + caps = gst_caps_make_writable (caps); + gst_caps_set_value (caps, "format", &format_list); + g_value_unset (&format_list); + } + } + + if (filter) { GstCaps *isect; isect = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); @@ -735,7 +684,6 @@ static gboolean gst_d3d11_video_sink_start (GstBaseSink * sink) { GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink); - gboolean is_hardware = TRUE; GST_DEBUG_OBJECT (self, "Start"); @@ -745,15 +693,6 @@ gst_d3d11_video_sink_start (GstBaseSink * sink) return FALSE; } - g_object_get (self->device, "hardware", &is_hardware, NULL); - - if (!is_hardware) { - GST_WARNING_OBJECT (self, "D3D11 device is running on software emulation"); - self->can_convert = FALSE; - } else { - self->can_convert = TRUE; - } - return TRUE; } @@ -886,22 +825,54 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query) size = info.size; if (need_pool) { - GstD3D11AllocationParams *d3d11_params; + GstCapsFeatures *features; + GstStructure *config; + gboolean is_d3d11 = false; + + features = gst_caps_get_features (caps, 0); + if (features + && gst_caps_features_contains (features, + GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY)) { + GST_DEBUG_OBJECT (self, "upstream support d3d11 memory"); + pool = gst_d3d11_buffer_pool_new (self->device); + is_d3d11 = true; + } else { + pool = gst_video_buffer_pool_new (); + } - GST_DEBUG_OBJECT (self, "create new pool"); + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_META); - d3d11_params = gst_d3d11_allocation_params_new (self->device, &info, - (GstD3D11AllocationFlags) 0, D3D11_BIND_SHADER_RESOURCE); - pool = gst_d3d11_buffer_pool_new_with_options (self->device, caps, - d3d11_params, 2, 0); - gst_d3d11_allocation_params_free (d3d11_params); + /* d3d11 pool does not support video alignment */ + if (!is_d3d11) { + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); + } + + size = GST_VIDEO_INFO_SIZE (&info); + if (is_d3d11) { + GstD3D11AllocationParams *d3d11_params; + + d3d11_params = + gst_d3d11_allocation_params_new (self->device, + &info, (GstD3D11AllocationFlags) 0, D3D11_BIND_SHADER_RESOURCE); + + gst_buffer_pool_config_set_d3d11_allocation_params (config, d3d11_params); + gst_d3d11_allocation_params_free (d3d11_params); + } + + gst_buffer_pool_config_set_params (config, caps, (guint) size, 2, 0); + + if (!gst_buffer_pool_set_config (pool, config)) { + GST_ERROR_OBJECT (pool, "Couldn't set config"); + gst_object_unref (pool); - if (!pool) { - GST_ERROR_OBJECT (self, "Failed to create buffer pool"); return FALSE; } - size = GST_D3D11_BUFFER_POOL (pool)->buffer_size; + if (is_d3d11) + size = GST_D3D11_BUFFER_POOL (pool)->buffer_size; } /* We need at least 2 buffers because we hold on to the last one for redrawing @@ -1130,12 +1101,8 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf) GST_LOG_OBJECT (self, "Begin drawing"); /* Application should call draw method on this callback */ - if (self->callbacks.begin_draw) { - self->callbacks.begin_draw (self, self->user_data); - } else { - g_signal_emit (self, gst_d3d11_video_sink_signals[SIGNAL_BEGIN_DRAW], 0, - NULL); - } + g_signal_emit (self, gst_d3d11_video_sink_signals[SIGNAL_BEGIN_DRAW], 0, + NULL); GST_LOG_OBJECT (self, "End drawing"); self->drawing = FALSE; @@ -1320,24 +1287,3 @@ gst_d3d11_video_sink_draw_action (GstD3D11VideoSink * self, return ret == GST_FLOW_OK; } - -void -gst_d3d11_video_sink_set_callbacks (GstD3D11VideoSink * videosink, - GstD3D11VideoSinkCallbacks * callbacks, gpointer user_data) -{ - g_return_if_fail (GST_IS_D3D11_VIDEO_SINK (videosink)); - - videosink->callbacks = *callbacks; - videosink->user_data = user_data; -} - -gboolean -gst_d3d11_video_sink_draw (GstD3D11VideoSink * videosink, - gpointer shared_handle, guint texture_misc_flags, guint64 acquire_key, - guint64 release_key) -{ - g_return_val_if_fail (GST_IS_D3D11_VIDEO_SINK (videosink), FALSE); - - return gst_d3d11_video_sink_draw_action (videosink, shared_handle, - texture_misc_flags, acquire_key, release_key); -} diff --git a/sys/d3d11/gstd3d11videosink.h b/sys/d3d11/gstd3d11videosink.h index f28652a..f67b3af 100644 --- a/sys/d3d11/gstd3d11videosink.h +++ b/sys/d3d11/gstd3d11videosink.h @@ -40,14 +40,6 @@ G_BEGIN_DECLS typedef struct _GstD3D11VideoSink GstD3D11VideoSink; typedef struct _GstD3D11VideoSinkClass GstD3D11VideoSinkClass; - -typedef struct -{ - void (*begin_draw) (GstD3D11VideoSink * videosink, - gpointer user_data); - -} GstD3D11VideoSinkCallbacks; - struct _GstD3D11VideoSinkClass { GstVideoSinkClass parent_class; @@ -65,19 +57,6 @@ struct _GstD3D11VideoSinkClass GType gst_d3d11_video_sink_get_type (void); -/* Internal methods, called by d3d11videosinkbin */ -void -gst_d3d11_video_sink_set_callbacks (GstD3D11VideoSink * videosink, - GstD3D11VideoSinkCallbacks * callbacks, - gpointer user_data); - -gboolean -gst_d3d11_video_sink_draw (GstD3D11VideoSink * videosink, - gpointer shared_handle, - guint texture_misc_flags, - guint64 acquire_key, - guint64 release_key); - G_END_DECLS #endif /* __GST_D3D11_VIDEO_SINK_H__ */ diff --git a/sys/d3d11/gstd3d11videosinkbin.cpp b/sys/d3d11/gstd3d11videosinkbin.cpp deleted file mode 100644 index fa7f507..0000000 --- a/sys/d3d11/gstd3d11videosinkbin.cpp +++ /dev/null @@ -1,507 +0,0 @@ -/* GStreamer - * Copyright (C) 2019 Seungha Yang - * Copyright (C) 2020 Seungha Yang - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-d3d11videosink - * @title: d3d11videosink - * - * Direct3D11 based video render element - * - * ## Example launch line - * ``` - * gst-launch-1.0 videotestsrc ! d3d11videosink - * ``` - * This pipeline will display test video stream on screen via #d3d11videosink - * - * Since: 1.18 - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include "gstd3d11videosink.h" -#include "gstd3d11videosinkbin.h" -#include "gstd3d11pluginutils.h" - -enum -{ - PROP_0, - /* basesink */ - PROP_SYNC, - PROP_MAX_LATENESS, - PROP_QOS, - PROP_ASYNC, - PROP_TS_OFFSET, - PROP_ENABLE_LAST_SAMPLE, - PROP_LAST_SAMPLE, - PROP_BLOCKSIZE, - PROP_RENDER_DELAY, - PROP_THROTTLE_TIME, - PROP_MAX_BITRATE, - PROP_PROCESSING_DEADLINE, - PROP_STATS, - /* videosink */ - PROP_SHOW_PREROLL_FRAME, - /* d3d11videosink */ - PROP_ADAPTER, - PROP_FORCE_ASPECT_RATIO, - PROP_ENABLE_NAVIGATION_EVENTS, - PROP_FULLSCREEN_TOGGLE_MODE, - PROP_FULLSCREEN, - PROP_RENDER_STATS, - PROP_DRAW_ON_SHARED_TEXTURE, -}; - -/* basesink */ -#define DEFAULT_SYNC TRUE -#define DEFAULT_MAX_LATENESS -1 -#define DEFAULT_QOS FALSE -#define DEFAULT_ASYNC TRUE -#define DEFAULT_TS_OFFSET 0 -#define DEFAULT_BLOCKSIZE 4096 -#define DEFAULT_RENDER_DELAY 0 -#define DEFAULT_ENABLE_LAST_SAMPLE TRUE -#define DEFAULT_THROTTLE_TIME 0 -#define DEFAULT_MAX_BITRATE 0 -#define DEFAULT_DROP_OUT_OF_SEGMENT TRUE -#define DEFAULT_PROCESSING_DEADLINE (20 * GST_MSECOND) - -/* videosink */ -#define DEFAULT_SHOW_PREROLL_FRAME TRUE - -/* d3d11videosink */ -#define DEFAULT_ADAPTER -1 -#define DEFAULT_FORCE_ASPECT_RATIO TRUE -#define DEFAULT_ENABLE_NAVIGATION_EVENTS TRUE -#define DEFAULT_FULLSCREEN_TOGGLE_MODE GST_D3D11_WINDOW_FULLSCREEN_TOGGLE_MODE_NONE -#define DEFAULT_FULLSCREEN FALSE -#define DEFAULT_RENDER_STATS FALSE -#define DEFAULT_DRAW_ON_SHARED_TEXTURE FALSE - -enum -{ - /* signals */ - SIGNAL_BEGIN_DRAW, - - /* actions */ - SIGNAL_DRAW, - - LAST_SIGNAL -}; - -static guint gst_d3d11_video_sink_bin_signals[LAST_SIGNAL] = { 0, }; - -static GstStaticCaps pad_template_caps = - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SINK_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_SINK_FORMATS) ";" - GST_VIDEO_CAPS_MAKE (GST_D3D11_SINK_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_SINK_FORMATS)); - -GST_DEBUG_CATEGORY (d3d11_video_sink_bin_debug); -#define GST_CAT_DEFAULT d3d11_video_sink_bin_debug - -struct _GstD3D11VideoSinkBin -{ - GstBin parent; - - GstPad *sinkpad; - - GstElement *upload; - GstElement *sink; -}; - -static void gst_d3d11_video_sink_bin_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec); -static void gst_d3d11_video_sink_bin_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec); - -static void -gst_d3d11_video_sink_bin_video_overlay_init (GstVideoOverlayInterface * iface); -static void -gst_d3d11_video_sink_bin_navigation_init (GstNavigationInterface * iface); -static void gst_d311_video_sink_bin_on_begin_draw (GstD3D11VideoSink * sink, - gpointer self); -static gboolean -gst_d3d11_video_sink_bin_draw_action (GstD3D11VideoSinkBin * self, - gpointer shared_handle, guint texture_misc_flags, guint64 acquire_key, - guint64 release_key); - -#define gst_d3d11_video_sink_bin_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (GstD3D11VideoSinkBin, gst_d3d11_video_sink_bin, - GST_TYPE_BIN, - G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, - gst_d3d11_video_sink_bin_video_overlay_init); - G_IMPLEMENT_INTERFACE (GST_TYPE_NAVIGATION, - gst_d3d11_video_sink_bin_navigation_init); - GST_DEBUG_CATEGORY_INIT (d3d11_video_sink_bin_debug, - "d3d11videosink", 0, "Direct3D11 Video Sink")); - -static void -gst_d3d11_video_sink_bin_class_init (GstD3D11VideoSinkBinClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - GstCaps *caps; - - gobject_class->set_property = gst_d3d11_video_sink_bin_set_property; - gobject_class->get_property = gst_d3d11_video_sink_bin_get_property; - - /* basesink */ - g_object_class_install_property (gobject_class, PROP_SYNC, - g_param_spec_boolean ("sync", "Sync", "Sync on the clock", DEFAULT_SYNC, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_MAX_LATENESS, - g_param_spec_int64 ("max-lateness", "Max Lateness", - "Maximum number of nanoseconds that a buffer can be late before it " - "is dropped (-1 unlimited)", -1, G_MAXINT64, DEFAULT_MAX_LATENESS, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_QOS, - g_param_spec_boolean ("qos", "Qos", - "Generate Quality-of-Service events upstream", DEFAULT_QOS, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_ASYNC, - g_param_spec_boolean ("async", "Async", - "Go asynchronously to PAUSED", DEFAULT_ASYNC, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_TS_OFFSET, - g_param_spec_int64 ("ts-offset", "TS Offset", - "Timestamp offset in nanoseconds", G_MININT64, G_MAXINT64, - DEFAULT_TS_OFFSET, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_ENABLE_LAST_SAMPLE, - g_param_spec_boolean ("enable-last-sample", "Enable Last Buffer", - "Enable the last-sample property", DEFAULT_ENABLE_LAST_SAMPLE, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_LAST_SAMPLE, - g_param_spec_boxed ("last-sample", "Last Sample", - "The last sample received in the sink", GST_TYPE_SAMPLE, - (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_BLOCKSIZE, - g_param_spec_uint ("blocksize", "Block size", - "Size in bytes to pull per buffer (0 = default)", 0, G_MAXUINT, - DEFAULT_BLOCKSIZE, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_RENDER_DELAY, - g_param_spec_uint64 ("render-delay", "Render Delay", - "Additional render delay of the sink in nanoseconds", 0, G_MAXUINT64, - DEFAULT_RENDER_DELAY, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_THROTTLE_TIME, - g_param_spec_uint64 ("throttle-time", "Throttle time", - "The time to keep between rendered buffers (0 = disabled)", 0, - G_MAXUINT64, DEFAULT_THROTTLE_TIME, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_MAX_BITRATE, - g_param_spec_uint64 ("max-bitrate", "Max Bitrate", - "The maximum bits per second to render (0 = disabled)", 0, - G_MAXUINT64, DEFAULT_MAX_BITRATE, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_PROCESSING_DEADLINE, - g_param_spec_uint64 ("processing-deadline", "Processing deadline", - "Maximum processing deadline in nanoseconds", 0, G_MAXUINT64, - DEFAULT_PROCESSING_DEADLINE, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_STATS, - g_param_spec_boxed ("stats", "Statistics", - "Sink Statistics", GST_TYPE_STRUCTURE, - (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); - - /* videosink */ - g_object_class_install_property (gobject_class, PROP_SHOW_PREROLL_FRAME, - g_param_spec_boolean ("show-preroll-frame", "Show preroll frame", - "Whether to render video frames during preroll", - DEFAULT_SHOW_PREROLL_FRAME, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT | - G_PARAM_STATIC_STRINGS))); - - /* d3d11videosink */ - g_object_class_install_property (gobject_class, PROP_ADAPTER, - g_param_spec_int ("adapter", "Adapter", - "Adapter index for creating device (-1 for default)", - -1, G_MAXINT32, DEFAULT_ADAPTER, - (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY | - G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_FORCE_ASPECT_RATIO, - g_param_spec_boolean ("force-aspect-ratio", - "Force aspect ratio", - "When enabled, scaling will respect original aspect ratio", - DEFAULT_FORCE_ASPECT_RATIO, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_ENABLE_NAVIGATION_EVENTS, - g_param_spec_boolean ("enable-navigation-events", - "Enable navigation events", - "When enabled, navigation events are sent upstream", - DEFAULT_ENABLE_NAVIGATION_EVENTS, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_FULLSCREEN_TOGGLE_MODE, - g_param_spec_flags ("fullscreen-toggle-mode", - "Full screen toggle mode", - "Full screen toggle mode used to trigger fullscreen mode change", - GST_D3D11_WINDOW_TOGGLE_MODE_GET_TYPE, DEFAULT_FULLSCREEN_TOGGLE_MODE, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - g_object_class_install_property (gobject_class, PROP_FULLSCREEN, - g_param_spec_boolean ("fullscreen", - "fullscreen", - "Ignored when \"fullscreen-toggle-mode\" does not include \"property\"", - DEFAULT_FULLSCREEN, - (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); - - /** - * GstD3D11VideoSinkBin:draw-on-shared-texture: - * - * Instruct the sink to draw on a shared texture provided by user. - * User must watch #d3d11videosink::begin-draw signal and should call - * #d3d11videosink::draw method on the #d3d11videosink::begin-draw - * signal handler. - * - * Currently supported formats for user texture are: - * - DXGI_FORMAT_R8G8B8A8_UNORM - * - DXGI_FORMAT_B8G8R8A8_UNORM - * - DXGI_FORMAT_R10G10B10A2_UNORM - * - * Since: 1.20 - */ - g_object_class_install_property (gobject_class, PROP_DRAW_ON_SHARED_TEXTURE, - g_param_spec_boolean ("draw-on-shared-texture", - "Draw on shared texture", - "Draw on user provided shared texture instead of window. " - "When enabled, user can pass application's own texture to sink " - "by using \"draw\" action signal on \"begin-draw\" signal handler, " - "so that sink can draw video data on application's texture. " - "Supported texture formats for user texture are " - "DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, and " - "DXGI_FORMAT_R10G10B10A2_UNORM.", - DEFAULT_DRAW_ON_SHARED_TEXTURE, - (GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY | - G_PARAM_STATIC_STRINGS))); - - /** - * GstD3D11VideoSinkBin::begin-draw: - * @videosink: the #d3d11videosink - * - * Emitted when sink has a texture to draw. Application needs to invoke - * #d3d11videosink::draw action signal before returning from - * #d3d11videosink::begin-draw signal handler. - * - * Since: 1.20 - */ - gst_d3d11_video_sink_bin_signals[SIGNAL_BEGIN_DRAW] = - g_signal_new ("begin-draw", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstD3D11VideoSinkBinClass, begin_draw), - NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE); - - /** - * GstD3D11VideoSinkBin::draw: - * @videosink: the #d3d11videosink - * @shard_handle: a pointer to HANDLE - * @texture_misc_flags: a D3D11_RESOURCE_MISC_FLAG value - * @acquire_key: a key value used for IDXGIKeyedMutex::AcquireSync - * @release_key: a key value used for IDXGIKeyedMutex::ReleaseSync - * - * Draws on a shared texture. @shard_handle must be a valid pointer to - * a HANDLE which was obtained via IDXGIResource::GetSharedHandle or - * IDXGIResource1::CreateSharedHandle. - * - * If the texture was created with D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX flag, - * caller must specify valid @acquire_key and @release_key. - * Otherwise (i.e., created with D3D11_RESOURCE_MISC_SHARED flag), - * @acquire_key and @release_key will be ignored. - * - * Since: 1.20 - */ - gst_d3d11_video_sink_bin_signals[SIGNAL_DRAW] = - g_signal_new ("draw", G_TYPE_FROM_CLASS (klass), - (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), - G_STRUCT_OFFSET (GstD3D11VideoSinkBinClass, draw), NULL, NULL, NULL, - G_TYPE_BOOLEAN, 4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT64, - G_TYPE_UINT64); - - klass->draw = gst_d3d11_video_sink_bin_draw_action; - - gst_element_class_set_static_metadata (element_class, - "Direct3D11 video sink bin", "Sink/Video", - "A Direct3D11 based videosink bin", - "Seungha Yang "); - - caps = gst_d3d11_get_updated_template_caps (&pad_template_caps); - gst_element_class_add_pad_template (element_class, - gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps)); - gst_caps_unref (caps); -} - -static void -gst_d3d11_video_sink_bin_init (GstD3D11VideoSinkBin * self) -{ - GstPad *pad; - GstD3D11VideoSinkCallbacks callbacks; - - self->upload = gst_element_factory_make ("d3d11upload", NULL); - if (!self->upload) { - GST_ERROR_OBJECT (self, "d3d11upload unavailable"); - return; - } - - self->sink = gst_element_factory_make ("d3d11videosinkelement", NULL); - if (!self->sink) { - gst_clear_object (&self->upload); - GST_ERROR_OBJECT (self, "d3d11videosinkelement unavailable"); - return; - } - - callbacks.begin_draw = gst_d311_video_sink_bin_on_begin_draw; - gst_d3d11_video_sink_set_callbacks (GST_D3D11_VIDEO_SINK (self->sink), - &callbacks, self); - - gst_bin_add_many (GST_BIN (self), self->upload, self->sink, NULL); - - gst_element_link_many (self->upload, self->sink, NULL); - - pad = gst_element_get_static_pad (self->upload, "sink"); - - self->sinkpad = gst_ghost_pad_new ("sink", pad); - gst_element_add_pad (GST_ELEMENT_CAST (self), self->sinkpad); - gst_object_unref (pad); -} - -static void -gst_d3d11_video_sink_bin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (object); - GParamSpec *sink_pspec; - - sink_pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (self->sink), - pspec->name); - - if (sink_pspec && G_PARAM_SPEC_TYPE (sink_pspec) == G_PARAM_SPEC_TYPE (pspec)) { - g_object_set_property (G_OBJECT (self->sink), pspec->name, value); - } else { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -gst_d3d11_video_sink_bin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (object); - - g_object_get_property (G_OBJECT (self->sink), pspec->name, value); -} - -static void -gst_d311_video_sink_bin_on_begin_draw (GstD3D11VideoSink * sink, gpointer self) -{ - g_signal_emit (self, gst_d3d11_video_sink_bin_signals[SIGNAL_BEGIN_DRAW], 0, - NULL); -} - -static gboolean -gst_d3d11_video_sink_bin_draw_action (GstD3D11VideoSinkBin * self, - gpointer shared_handle, guint texture_misc_flags, guint64 acquire_key, - guint64 release_key) -{ - if (!self->sink) { - GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, - ("D3D11VideoSink element wasn't configured"), (NULL)); - return FALSE; - } - - return gst_d3d11_video_sink_draw (GST_D3D11_VIDEO_SINK (self->sink), - shared_handle, texture_misc_flags, acquire_key, release_key); -} - -/* VideoOverlay interface */ -static void -gst_d3d11_video_sink_bin_set_window_handle (GstVideoOverlay * overlay, - guintptr window_id) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (overlay); - - gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (self->sink), - window_id); -} - -static void -gst_d3d11_video_sink_bin_set_render_rectangle (GstVideoOverlay * overlay, - gint x, gint y, gint width, gint height) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (overlay); - - gst_video_overlay_set_render_rectangle (GST_VIDEO_OVERLAY (self->sink), - x, y, width, height); -} - -static void -gst_d3d11_video_sink_bin_expose (GstVideoOverlay * overlay) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (overlay); - - gst_video_overlay_expose (GST_VIDEO_OVERLAY (self->sink)); -} - -static void -gst_d3d11_video_sink_bin_handle_events (GstVideoOverlay * overlay, - gboolean handle_events) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (overlay); - - gst_video_overlay_handle_events (GST_VIDEO_OVERLAY (self->sink), - handle_events); -} - -static void -gst_d3d11_video_sink_bin_video_overlay_init (GstVideoOverlayInterface * iface) -{ - iface->set_window_handle = gst_d3d11_video_sink_bin_set_window_handle; - iface->set_render_rectangle = gst_d3d11_video_sink_bin_set_render_rectangle; - iface->expose = gst_d3d11_video_sink_bin_expose; - iface->handle_events = gst_d3d11_video_sink_bin_handle_events; -} - -/* Navigation interface */ -static void -gst_d3d11_video_sink_bin_navigation_send_event (GstNavigation * navigation, - GstStructure * structure) -{ - GstD3D11VideoSinkBin *self = GST_D3D11_VIDEO_SINK_BIN (navigation); - - gst_navigation_send_event (GST_NAVIGATION (self->sink), structure); -} - -static void -gst_d3d11_video_sink_bin_navigation_init (GstNavigationInterface * iface) -{ - iface->send_event = gst_d3d11_video_sink_bin_navigation_send_event; -} diff --git a/sys/d3d11/gstd3d11videosinkbin.h b/sys/d3d11/gstd3d11videosinkbin.h deleted file mode 100644 index 0cdb19f..0000000 --- a/sys/d3d11/gstd3d11videosinkbin.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GStreamer - * Copyright (C) 2019 Seungha Yang - * Copyright (C) 2020 Seungha Yang - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_D3D11_VIDEO_SINK_BIN_H__ -#define __GST_D3D11_VIDEO_SINK_BIN_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_D3D11_VIDEO_SINK_BIN (gst_d3d11_video_sink_bin_get_type()) -#define GST_D3D11_VIDEO_SINK_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_D3D11_VIDEO_SINK_BIN, GstD3D11VideoSinkBin)) -#define GST_D3D11_VIDEO_SINK_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_D3D11_VIDEO_SINK_BIN, GstD3D11VideoSinkBinClass)) -#define GST_IS_D3D11_VIDEO_SINK_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_D3D11_VIDEO_SINK_BIN)) -#define GST_IS_D3D11_VIDEO_SINK_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_D3D11_VIDEO_SINK_BIN)) -#define GST_D3D11_VIDEO_SINK_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_D3D11_VIDEO_SINK_BIN, GstD3D11VideoSinkBinClass)) - -typedef struct _GstD3D11VideoSinkBin GstD3D11VideoSinkBin; -typedef struct _GstD3D11VideoSinkBinClass GstD3D11VideoSinkBinClass; - -struct _GstD3D11VideoSinkBinClass -{ - GstBinClass parent_class; - - /* signals */ - void (*begin_draw) (GstD3D11VideoSinkBin * videosink); - - /* actions */ - gboolean (*draw) (GstD3D11VideoSinkBin * videosink, - gpointer shared_handle, - guint texture_misc_flags, - guint64 acquire_key, - guint64 release_key); -}; - -GType gst_d3d11_video_sink_bin_get_type (void); - -G_END_DECLS - -#endif /* __GST_D3D11_VIDEO_SINK_BIN_H__ */ diff --git a/sys/d3d11/meson.build b/sys/d3d11/meson.build index a75fbb9..902748f 100644 --- a/sys/d3d11/meson.build +++ b/sys/d3d11/meson.build @@ -11,7 +11,6 @@ d3d11_sources = [ 'gstd3d11upload.cpp', 'gstd3d11videoprocessor.cpp', 'gstd3d11videosink.cpp', - 'gstd3d11videosinkbin.cpp', 'gstd3d11window.cpp', 'gstd3d11window_dummy.cpp', 'plugin.c', diff --git a/sys/d3d11/plugin.c b/sys/d3d11/plugin.c index 3b2aa7e..18521de 100644 --- a/sys/d3d11/plugin.c +++ b/sys/d3d11/plugin.c @@ -27,7 +27,6 @@ #include "gstd3d11upload.h" #include "gstd3d11download.h" #include "gstd3d11convert.h" -#include "gstd3d11videosinkbin.h" #include "gstd3d11shader.h" #include "gstd3d11compositor.h" #include "gstd3d11compositorbin.h" @@ -214,10 +213,7 @@ plugin_init (GstPlugin * plugin) gst_element_register (plugin, "d3d11scale", GST_RANK_NONE, GST_TYPE_D3D11_SCALE); gst_element_register (plugin, - "d3d11videosinkelement", GST_RANK_NONE, GST_TYPE_D3D11_VIDEO_SINK); - - gst_element_register (plugin, - "d3d11videosink", video_sink_rank, GST_TYPE_D3D11_VIDEO_SINK_BIN); + "d3d11videosink", video_sink_rank, GST_TYPE_D3D11_VIDEO_SINK); gst_element_register (plugin, "d3d11compositorelement", GST_RANK_NONE, GST_TYPE_D3D11_COMPOSITOR); -- 2.7.4