From 7b9debedc8a4a33c5dd593eb6ddbbfb4e34dd26b Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Wed, 20 Jan 2021 02:29:43 +0900 Subject: [PATCH] d3d11: Don't use hardcoded maximum resolution value Maximum supported texture dimension is pre-defined based on feature level and it couldn't be INT_MAX in any case. See also https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro Part-of: --- sys/d3d11/gstd3d11colorconvert.c | 42 +++++----- sys/d3d11/gstd3d11compositor.c | 30 +++---- sys/d3d11/gstd3d11compositorbin.c | 35 ++++---- sys/d3d11/gstd3d11desktopdupsrc.c | 16 ++-- sys/d3d11/gstd3d11download.c | 62 +++++++------- sys/d3d11/gstd3d11pluginutils.c | 42 ++++++++++ sys/d3d11/gstd3d11pluginutils.h | 4 + sys/d3d11/gstd3d11upload.c | 60 +++++++------- sys/d3d11/gstd3d11videosink.c | 21 ++--- sys/d3d11/gstd3d11videosinkbin.c | 32 ++++---- sys/d3d11/plugin.c | 130 ++++++++++++++++-------------- 11 files changed, 268 insertions(+), 206 deletions(-) diff --git a/sys/d3d11/gstd3d11colorconvert.c b/sys/d3d11/gstd3d11colorconvert.c index 9d1e71fcbf..cdd07b06a0 100644 --- a/sys/d3d11/gstd3d11colorconvert.c +++ b/sys/d3d11/gstd3d11colorconvert.c @@ -54,27 +54,21 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_convert_debug); #define GST_CAT_DEFAULT gst_d3d11_convert_debug -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, +static GstStaticCaps sink_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_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)); -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, +static GstStaticCaps src_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SRC_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_SRC_FORMATS)) - ); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SRC_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_SRC_FORMATS)); struct _GstD3D11Convert { @@ -264,11 +258,19 @@ gst_d3d11_convert_class_init (GstD3D11ConvertClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass); GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_convert_dispose; - gst_element_class_add_static_pad_template (element_class, &sink_template); - gst_element_class_add_static_pad_template (element_class, &src_template); + caps = gst_d3d11_get_updated_template_caps (&sink_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); + + caps = gst_d3d11_get_updated_template_caps (&src_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + gst_caps_unref (caps); gst_element_class_set_static_metadata (element_class, "Direct3D11 colorspace converter and scaler", diff --git a/sys/d3d11/gstd3d11compositor.c b/sys/d3d11/gstd3d11compositor.c index a363ac6270..f8bad28945 100644 --- a/sys/d3d11/gstd3d11compositor.c +++ b/sys/d3d11/gstd3d11compositor.c @@ -1213,19 +1213,9 @@ gst_d3d11_compositor_pad_setup_converter (GstVideoAggregatorPad * pad, return gst_d3d11_color_converter_update_dest_rect (cpad->convert, &rect); } -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink_%u", - GST_PAD_SINK, - GST_PAD_REQUEST, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "{ RGBA, BGRA }") - )); - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "{ RGBA, BGRA }") - )); +static GstStaticCaps pad_template_caps = +GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "{ RGBA, BGRA }")); enum { @@ -1284,6 +1274,7 @@ gst_d3d11_compositor_class_init (GstD3D11CompositorClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstAggregatorClass *aggregator_class = GST_AGGREGATOR_CLASS (klass); GstVideoAggregatorClass *vagg_class = GST_VIDEO_AGGREGATOR_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_compositor_dispose; gobject_class->set_property = gst_d3d11_compositor_set_property; @@ -1326,10 +1317,15 @@ gst_d3d11_compositor_class_init (GstD3D11CompositorClass * klass) vagg_class->aggregate_frames = GST_DEBUG_FUNCPTR (gst_d3d11_compositor_aggregate_frames); - gst_element_class_add_static_pad_template_with_gtype (element_class, - &src_template, GST_TYPE_AGGREGATOR_PAD); - gst_element_class_add_static_pad_template_with_gtype (element_class, - &sink_template, GST_TYPE_D3D11_COMPOSITOR_PAD); + caps = gst_d3d11_get_updated_template_caps (&pad_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST, + caps, GST_TYPE_D3D11_COMPOSITOR_PAD)); + + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + caps, GST_TYPE_AGGREGATOR_PAD)); + gst_caps_unref (caps); gst_element_class_set_static_metadata (element_class, "Direct3D11 Compositor", "Filter/Editor/Video/Compositor", diff --git a/sys/d3d11/gstd3d11compositorbin.c b/sys/d3d11/gstd3d11compositorbin.c index b8577f2d91..25fb07cf82 100644 --- a/sys/d3d11/gstd3d11compositorbin.c +++ b/sys/d3d11/gstd3d11compositorbin.c @@ -26,6 +26,7 @@ #include #include "gstd3d11compositorbin.h" #include "gstd3d11compositor.h" +#include "gstd3d11pluginutils.h" GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_compositor_debug); #define GST_CAT_DEFAULT gst_d3d11_compositor_debug @@ -441,21 +442,15 @@ gst_d3d11_compositor_bin_input_set_target (GstD3D11CompositorBinPad * pad, * GstD3D11CompositorBin * *************************/ -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink_%u", - GST_PAD_SINK, - GST_PAD_REQUEST, +static GstStaticCaps sink_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 (GST_D3D11_SINK_FORMATS) - )); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SINK_FORMATS) ";" + GST_VIDEO_CAPS_MAKE (GST_D3D11_SINK_FORMATS)); -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, +static GstStaticCaps src_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SRC_FORMATS) ";" - GST_VIDEO_CAPS_MAKE (GST_D3D11_SRC_FORMATS) - )); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SRC_FORMATS) ";" + GST_VIDEO_CAPS_MAKE (GST_D3D11_SRC_FORMATS)); enum { @@ -533,6 +528,7 @@ gst_d3d11_compositor_bin_class_init (GstD3D11CompositorBinClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstElementClass *element_class = GST_ELEMENT_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_compositor_bin_dispose; gobject_class->set_property = gst_d3d11_compositor_bin_set_property; @@ -551,10 +547,17 @@ gst_d3d11_compositor_bin_class_init (GstD3D11CompositorBinClass * klass) "Composite multiple video streams via D3D11 API", "Seungha Yang "); - gst_element_class_add_static_pad_template_with_gtype (element_class, - &sink_template, GST_TYPE_D3D11_COMPOSITOR_BIN_INPUT); - gst_element_class_add_static_pad_template_with_gtype (element_class, - &src_template, GST_TYPE_D3D11_COMPOSITOR_BIN_PAD); + caps = gst_d3d11_get_updated_template_caps (&sink_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("sink_%u", GST_PAD_SINK, GST_PAD_REQUEST, + caps, GST_TYPE_D3D11_COMPOSITOR_BIN_INPUT)); + gst_caps_unref (caps); + + caps = gst_d3d11_get_updated_template_caps (&src_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new_with_gtype ("src", GST_PAD_SRC, GST_PAD_ALWAYS, + caps, GST_TYPE_D3D11_COMPOSITOR_BIN_PAD)); + gst_caps_unref (caps); g_object_class_install_property (gobject_class, PROP_MIXER, g_param_spec_object ("mixer", "D3D11 mixer element", diff --git a/sys/d3d11/gstd3d11desktopdupsrc.c b/sys/d3d11/gstd3d11desktopdupsrc.c index a83e5aa8b0..191ef6e1b7 100644 --- a/sys/d3d11/gstd3d11desktopdupsrc.c +++ b/sys/d3d11/gstd3d11desktopdupsrc.c @@ -39,6 +39,7 @@ #include "gstd3d11desktopdupsrc.h" #include "gstd3d11desktopdup.h" +#include "gstd3d11pluginutils.h" #include @@ -59,12 +60,9 @@ static GParamSpec *properties[PROP_LAST]; #define DEFAULT_MONITOR_INDEX -1 #define DEFAULT_SHOW_CURSOR FALSE -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "BGRA") - )); +static GstStaticCaps template_caps = +GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, "BGRA")); struct _GstD3D11DesktopDupSrc { @@ -124,6 +122,7 @@ gst_d3d11_desktop_dup_src_class_init (GstD3D11DesktopDupSrcClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstBaseSrcClass *basesrc_class = GST_BASE_SRC_CLASS (klass); GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_desktop_dup_src_dispose; gobject_class->set_property = gst_d3d11_desktop_dup_src_set_property; @@ -150,7 +149,10 @@ gst_d3d11_desktop_dup_src_class_init (GstD3D11DesktopDupSrcClass * klass) "Capture desktop image by using Desktop Duplication API", "Seungha Yang "); - gst_element_class_add_static_pad_template (element_class, &src_template); + caps = gst_d3d11_get_updated_template_caps (&template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + gst_caps_unref (caps); basesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_d3d11_desktop_dup_src_get_caps); diff --git a/sys/d3d11/gstd3d11download.c b/sys/d3d11/gstd3d11download.c index db99a17325..d2ce883194 100644 --- a/sys/d3d11/gstd3d11download.c +++ b/sys/d3d11/gstd3d11download.c @@ -26,37 +26,31 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_download_debug); #define GST_CAT_DEFAULT gst_d3d11_download_debug -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, +static GstStaticCaps sink_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) - )); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS)); -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, +static GstStaticCaps src_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) - )); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS)); struct _GstD3D11Download { @@ -92,11 +86,19 @@ gst_d3d11_download_class_init (GstD3D11DownloadClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass); GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_download_dispose; - gst_element_class_add_static_pad_template (element_class, &sink_template); - gst_element_class_add_static_pad_template (element_class, &src_template); + caps = gst_d3d11_get_updated_template_caps (&sink_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); + + caps = gst_d3d11_get_updated_template_caps (&src_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + gst_caps_unref (caps); gst_element_class_set_static_metadata (element_class, "Direct3D11 downloader", "Filter/Video", diff --git a/sys/d3d11/gstd3d11pluginutils.c b/sys/d3d11/gstd3d11pluginutils.c index 962c860e3c..e260a89157 100644 --- a/sys/d3d11/gstd3d11pluginutils.c +++ b/sys/d3d11/gstd3d11pluginutils.c @@ -30,6 +30,48 @@ GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_plugin_utils_debug); #define GST_CAT_DEFAULT gst_d3d11_plugin_utils_debug +/* Max Texture Dimension for feature level 11_0 ~ 12_1 */ +static guint _gst_d3d11_texture_max_dimension = 16384; + +void +gst_d3d11_plugin_utils_init (D3D_FEATURE_LEVEL feature_level) +{ + static gsize _init_once = 0; + + if (g_once_init_enter (&_init_once)) { + /* https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro */ + if (feature_level >= D3D_FEATURE_LEVEL_11_0) + _gst_d3d11_texture_max_dimension = 16384; + else if (feature_level >= D3D_FEATURE_LEVEL_10_0) + _gst_d3d11_texture_max_dimension = 8192; + else + _gst_d3d11_texture_max_dimension = 4096; + + g_once_init_leave (&_init_once, 1); + } +} + +GstCaps * +gst_d3d11_get_updated_template_caps (GstStaticCaps * template_caps) +{ + GstCaps *caps; + + g_return_val_if_fail (template_caps != NULL, NULL); + + caps = gst_static_caps_get (template_caps); + if (!caps) { + GST_ERROR ("Couldn't get caps from static caps"); + return NULL; + } + + caps = gst_caps_make_writable (caps); + gst_caps_set_simple (caps, + "width", GST_TYPE_INT_RANGE, 1, _gst_d3d11_texture_max_dimension, + "height", GST_TYPE_INT_RANGE, 1, _gst_d3d11_texture_max_dimension, NULL); + + return caps; +} + gboolean gst_d3d11_is_windows_8_or_greater (void) { diff --git a/sys/d3d11/gstd3d11pluginutils.h b/sys/d3d11/gstd3d11pluginutils.h index 02ad0794b1..947673e950 100644 --- a/sys/d3d11/gstd3d11pluginutils.h +++ b/sys/d3d11/gstd3d11pluginutils.h @@ -48,6 +48,10 @@ struct _GstDxgiColorSpace GstVideoColorPrimaries primaries; }; +void gst_d3d11_plugin_utils_init (D3D_FEATURE_LEVEL feature_level); + +GstCaps * gst_d3d11_get_updated_template_caps (GstStaticCaps * template_caps); + gboolean gst_d3d11_is_windows_8_or_greater (void); GstD3D11DeviceVendor gst_d3d11_get_device_vendor (GstD3D11Device * device); diff --git a/sys/d3d11/gstd3d11upload.c b/sys/d3d11/gstd3d11upload.c index acabd8ec74..73ea368a84 100644 --- a/sys/d3d11/gstd3d11upload.c +++ b/sys/d3d11/gstd3d11upload.c @@ -28,36 +28,30 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_upload_debug); #define GST_CAT_DEFAULT gst_d3d11_upload_debug -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, +static GstStaticCaps sink_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, - GST_D3D11_ALL_FORMATS) ";" - GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY - "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS)) - ); + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, + GST_D3D11_ALL_FORMATS) ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY + "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS)); -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, +static GstStaticCaps src_template_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS) ";" - GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " - GST_VIDEO_CAPS_MAKE_WITH_FEATURES - (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," - GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, - GST_D3D11_ALL_FORMATS)) - ); + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS) ";" + GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; " + GST_VIDEO_CAPS_MAKE_WITH_FEATURES + (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "," + GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION, + GST_D3D11_ALL_FORMATS)); struct _GstD3D11Upload { @@ -92,11 +86,19 @@ gst_d3d11_upload_class_init (GstD3D11UploadClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass); GstD3D11BaseFilterClass *bfilter_class = GST_D3D11_BASE_FILTER_CLASS (klass); + GstCaps *caps; gobject_class->dispose = gst_d3d11_upload_dispose; - gst_element_class_add_static_pad_template (element_class, &sink_template); - gst_element_class_add_static_pad_template (element_class, &src_template); + caps = gst_d3d11_get_updated_template_caps (&sink_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); + + caps = gst_d3d11_get_updated_template_caps (&src_template_caps); + gst_element_class_add_pad_template (element_class, + gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps)); + gst_caps_unref (caps); gst_element_class_set_static_metadata (element_class, "Direct3D11 uploader", "Filter/Video", diff --git a/sys/d3d11/gstd3d11videosink.c b/sys/d3d11/gstd3d11videosink.c index 51dc45ce22..d02bf93c2d 100644 --- a/sys/d3d11/gstd3d11videosink.c +++ b/sys/d3d11/gstd3d11videosink.c @@ -51,16 +51,13 @@ enum #define DEFAULT_FULLSCREEN FALSE #define DEFAULT_RENDER_STATS FALSE -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, +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_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_DEBUG_CATEGORY (d3d11_video_sink_debug); #define GST_CAT_DEFAULT d3d11_video_sink_debug @@ -141,6 +138,7 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) GstElementClass *element_class = GST_ELEMENT_CLASS (klass); GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS (klass); GstVideoSinkClass *videosink_class = GST_VIDEO_SINK_CLASS (klass); + GstCaps *caps; gobject_class->set_property = gst_d3d11_videosink_set_property; gobject_class->get_property = gst_d3d11_videosink_get_property; @@ -197,7 +195,10 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass) "A Direct3D11 based videosink", "Seungha Yang "); - gst_element_class_add_static_pad_template (element_class, &sink_template); + 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); basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_d3d11_video_sink_get_caps); basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_d3d11_video_sink_set_caps); diff --git a/sys/d3d11/gstd3d11videosinkbin.c b/sys/d3d11/gstd3d11videosinkbin.c index 4f71c087b6..96cc1b86a8 100644 --- a/sys/d3d11/gstd3d11videosinkbin.c +++ b/sys/d3d11/gstd3d11videosinkbin.c @@ -28,6 +28,7 @@ #include #include "gstd3d11videosink.h" #include "gstd3d11videosinkbin.h" +#include "gstd3d11pluginutils.h" enum { @@ -82,21 +83,18 @@ enum #define DEFAULT_FULLSCREEN FALSE #define DEFAULT_RENDER_STATS FALSE -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, +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_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 @@ -136,6 +134,7 @@ 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; @@ -249,7 +248,10 @@ gst_d3d11_video_sink_bin_class_init (GstD3D11VideoSinkBinClass * klass) "A Direct3D11 based videosink", "Seungha Yang "); - gst_element_class_add_static_pad_template (element_class, &sink_template); + 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 diff --git a/sys/d3d11/plugin.c b/sys/d3d11/plugin.c index 11a6ac2a99..03b44978c4 100644 --- a/sys/d3d11/plugin.c +++ b/sys/d3d11/plugin.c @@ -68,8 +68,9 @@ GST_DEBUG_CATEGORY (gst_d3d11_desktop_dup_debug); static gboolean plugin_init (GstPlugin * plugin) { - GstD3D11Device *device = NULL; - GstRank video_sink_rank = GST_RANK_NONE; + GstRank video_sink_rank = GST_RANK_PRIMARY; + D3D_FEATURE_LEVEL max_feature_level = D3D_FEATURE_LEVEL_9_3; + guint i; /** * plugin-d3d11: @@ -97,53 +98,9 @@ plugin_init (GstPlugin * plugin) GST_WARNING ("Cannot initialize d3d11 shader"); return TRUE; } - - gst_element_register (plugin, - "d3d11upload", GST_RANK_NONE, GST_TYPE_D3D11_UPLOAD); - gst_element_register (plugin, - "d3d11download", GST_RANK_NONE, GST_TYPE_D3D11_DOWNLOAD); - gst_element_register (plugin, - "d3d11convert", GST_RANK_NONE, GST_TYPE_D3D11_CONVERT); - gst_element_register (plugin, - "d3d11colorconvert", GST_RANK_NONE, GST_TYPE_D3D11_COLOR_CONVERT); - 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); - - device = gst_d3d11_device_new (0, D3D11_CREATE_DEVICE_BGRA_SUPPORT); - - /* FIXME: Our shader code is not compatible with D3D_FEATURE_LEVEL_9_3 - * or lower. So HLSL compiler cannot understand our shader code and - * therefore d3d11colorconverter cannot be configured. - * - * Known D3D_FEATURE_LEVEL_9_3 driver is - * "VirtualBox Graphics Adapter (WDDM)" - * ... and there might be some more old physical devices which don't support - * D3D_FEATURE_LEVEL_10_0. - */ - if (device) { - D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_10_0; - ID3D11Device *device_handle = gst_d3d11_device_get_device_handle (device); - - feature_level = ID3D11Device_GetFeatureLevel (device_handle); - if (feature_level >= D3D_FEATURE_LEVEL_10_0) - video_sink_rank = GST_RANK_PRIMARY; - } - - gst_element_register (plugin, - "d3d11videosink", video_sink_rank, GST_TYPE_D3D11_VIDEO_SINK_BIN); - - gst_element_register (plugin, - "d3d11compositorelement", GST_RANK_NONE, GST_TYPE_D3D11_COMPOSITOR); - gst_element_register (plugin, - "d3d11compositor", GST_RANK_SECONDARY, GST_TYPE_D3D11_COMPOSITOR_BIN); - #ifdef HAVE_DXVA_H /* DXVA2 API is availble since Windows 8 */ if (gst_d3d11_is_windows_8_or_greater ()) { - gint i = 0; - GST_DEBUG_CATEGORY_INIT (gst_d3d11_h264_dec_debug, "d3d11h264dec", 0, "Direct3D11 H.264 Video Decoder"); GST_DEBUG_CATEGORY_INIT (gst_d3d11_vp9_dec_debug, @@ -152,25 +109,41 @@ plugin_init (GstPlugin * plugin) "d3d11h265dec", 0, "Direct3D11 H.265 Video Decoder"); GST_DEBUG_CATEGORY_INIT (gst_d3d11_vp8_dec_debug, "d3d11vp8dec", 0, "Direct3D11 VP8 Decoder"); + } +#endif - do { + /* Enumerate devices to register decoders per device and to get the highest + * feature level */ + /* AMD seems supporting up to 12 cards, and 8 for NVIDIA */ + for (i = 0; i < 12; i++) { + GstD3D11Device *device = NULL; + ID3D11Device *device_handle; + D3D_FEATURE_LEVEL feature_level; + + device = gst_d3d11_device_new (i, D3D11_CREATE_DEVICE_BGRA_SUPPORT); + if (!device) + break; + + device_handle = gst_d3d11_device_get_device_handle (device); + feature_level = ID3D11Device_GetFeatureLevel (device_handle); + + if (feature_level > max_feature_level) + max_feature_level = feature_level; + +#ifdef HAVE_DXVA_H + /* DXVA2 API is availble since Windows 8 */ + if (gst_d3d11_is_windows_8_or_greater ()) { GstD3D11Decoder *decoder = NULL; gboolean legacy; gboolean hardware; - if (!device) - device = gst_d3d11_device_new (i, D3D11_CREATE_DEVICE_BGRA_SUPPORT); - - if (!device) - break; - g_object_get (device, "hardware", &hardware, NULL); if (!hardware) - goto clear; + goto done; decoder = gst_d3d11_decoder_new (device); if (!decoder) - goto clear; + goto done; legacy = gst_d3d11_decoder_util_is_legacy_device (device); @@ -185,14 +158,49 @@ plugin_init (GstPlugin * plugin) GST_RANK_SECONDARY); } - clear: - gst_clear_object (&device); + done: gst_clear_object (&decoder); - i++; - } while (1); - } + } #endif + gst_object_unref (device); + } + + /* FIXME: Our shader code is not compatible with D3D_FEATURE_LEVEL_9_3 + * or lower. So HLSL compiler cannot understand our shader code and + * therefore d3d11colorconverter cannot be configured. + * + * Known D3D_FEATURE_LEVEL_9_3 driver is + * "VirtualBox Graphics Adapter (WDDM)" + * ... and there might be some more old physical devices which don't support + * D3D_FEATURE_LEVEL_10_0. + */ + if (max_feature_level < D3D_FEATURE_LEVEL_10_0) + video_sink_rank = GST_RANK_NONE; + + gst_d3d11_plugin_utils_init (max_feature_level); + + gst_element_register (plugin, + "d3d11upload", GST_RANK_NONE, GST_TYPE_D3D11_UPLOAD); + gst_element_register (plugin, + "d3d11download", GST_RANK_NONE, GST_TYPE_D3D11_DOWNLOAD); + gst_element_register (plugin, + "d3d11convert", GST_RANK_NONE, GST_TYPE_D3D11_CONVERT); + gst_element_register (plugin, + "d3d11colorconvert", GST_RANK_NONE, GST_TYPE_D3D11_COLOR_CONVERT); + 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); + + gst_element_register (plugin, + "d3d11compositorelement", GST_RANK_NONE, GST_TYPE_D3D11_COMPOSITOR); + gst_element_register (plugin, + "d3d11compositor", GST_RANK_SECONDARY, GST_TYPE_D3D11_COMPOSITOR_BIN); + #ifdef HAVE_DXGI_DESKTOP_DUP if (gst_d3d11_is_windows_8_or_greater ()) { GST_DEBUG_CATEGORY_INIT (gst_d3d11_desktop_dup_debug, @@ -202,8 +210,6 @@ plugin_init (GstPlugin * plugin) } #endif - gst_clear_object (&device); - return TRUE; }