diff --git a/meson.build b/meson.build index c410c05fd2..2321395d5e 100644 --- a/meson.build +++ b/meson.build @@ -458,6 +458,13 @@ gstgl_dep = dependency('gstreamer-gl-1.0', version: gstreamer_req, required: get_option('media-gstreamer')) gstallocators_dep = dependency('gstreamer-allocators-1.0', version: gstreamer_req, required: get_option('media-gstreamer')) +if os_win32 + gstd3d12_dep = dependency('gstreamer-d3d12-1.0', version: gstreamer_req, + required: get_option('media-gstreamer')) +else + gstd3d12_dep = dependency('', required: false) +endif + fontconfig_dep = [] # only used in x11 backend diff --git a/modules/media/gtkgstsink.c b/modules/media/gtkgstsink.c index 293e858353..4950653d45 100644 --- a/modules/media/gtkgstsink.c +++ b/modules/media/gtkgstsink.c @@ -38,8 +38,9 @@ #include #endif -#if GST_GL_HAVE_WINDOW_WIN32 && (GST_GL_HAVE_PLATFORM_WGL || GST_GL_HAVE_PLATFORM_EGL) && defined (GDK_WINDOWING_WIN32) +#ifdef GDK_WINDOWING_WIN32 #include +#include #endif #if GST_GL_HAVE_PLATFORM_EGL && (GST_GL_HAVE_WINDOW_WIN32 || GST_GL_HAVE_WINDOW_X11) @@ -72,6 +73,16 @@ GST_DEBUG_CATEGORY (gtk_debug_gst_sink); #define MEMORY_TEXTURE_CAPS GST_VIDEO_CAPS_MAKE (FORMATS) +#ifdef GDK_WINDOWING_WIN32 +#define D3D12_TEXTURE_CAPS \ + "video/x-raw(" GST_CAPS_FEATURE_MEMORY_D3D12_MEMORY "), " \ + "width = " GST_VIDEO_SIZE_RANGE ", " \ + "height = " GST_VIDEO_SIZE_RANGE ", " \ + "framerate = " GST_VIDEO_FPS_RANGE ", " +#else +#define D3D12_TEXTURE_CAPS "" +#endif + #define GL_TEXTURE_CAPS \ "video/x-raw(" GST_CAPS_FEATURE_MEMORY_GL_MEMORY "), " \ "format = (string) RGBA, " \ @@ -87,6 +98,7 @@ GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS(DMABUF_TEXTURE_CAPS "; " + D3D12_TEXTURE_CAPS "; " GL_TEXTURE_CAPS "; " MEMORY_TEXTURE_CAPS) ); @@ -215,6 +227,11 @@ gtk_gst_sink_get_caps (GstBaseSink *bsink, unfiltered = gst_caps_new_empty (); +#ifdef GDK_WINDOWING_WIN32 + tmp = gst_caps_from_string (D3D12_TEXTURE_CAPS); + gst_caps_append (unfiltered, tmp); +#endif + if (self->gdk_display) { GdkDmabufFormats *formats = gdk_display_get_dmabuf_formats (self->gdk_display); @@ -263,6 +280,18 @@ gtk_gst_sink_set_caps (GstBaseSink *bsink, GST_DEBUG_OBJECT (self, "set caps with %" GST_PTR_FORMAT, caps); +#ifdef GDK_WINDOWING_WIN32 + if (gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_D3D12_MEMORY)) + { + GST_DEBUG_OBJECT (self, "using D3D12"); + + gst_video_info_dma_drm_init (&self->drm_info); + + if (!gst_video_info_from_caps (&self->v_info, caps)) + return FALSE; + } + else +#endif if (gst_video_is_dma_drm_caps (caps)) { if (!gst_video_info_dma_drm_from_caps (&self->drm_info, caps)) @@ -323,6 +352,14 @@ gtk_gst_sink_propose_allocation (GstBaseSink *bsink, return FALSE; } +#ifdef GDK_WINDOWING_WIN32 + if (gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_D3D12_MEMORY)) + { + gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); + return TRUE; + } +#endif + if (gst_caps_features_contains (gst_caps_get_features (caps, 0), GST_CAPS_FEATURE_MEMORY_DMABUF)) { gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0); @@ -425,6 +462,38 @@ gtk_gst_sink_texture_from_buffer (GtkGstSink *self, mem = gst_buffer_peek_memory (buffer, 0); +#ifdef GDK_WINDOWING_WIN32 + if (gst_is_d3d12_memory (mem) && + gst_video_frame_map (frame, &self->v_info, buffer, GST_MAP_READ_D3D12)) + { + GdkD3D12TextureBuilder *builder; + GError *error = NULL; + int i; + + /* XXX: Remove once fences land */ + gst_d3d12_memory_sync (GST_D3D12_MEMORY_CAST (mem)); + + builder = gdk_d3d12_texture_builder_new (); + gdk_d3d12_texture_builder_set_resource (builder, gst_d3d12_memory_get_resource_handle (GST_D3D12_MEMORY_CAST (mem))); + gdk_d3d12_texture_builder_set_color_state (builder, self->color_state); + + texture = gdk_d3d12_texture_builder_build (builder, + (GDestroyNotify) video_frame_free, + frame, + &error); + g_object_unref (builder); + + if (!texture) + { + GST_ERROR_OBJECT (self, "Failed to create d3d12 texture: %s", error->message); + g_error_free (error); + } + + *pixel_aspect_ratio = ((double) GST_VIDEO_INFO_PAR_N (&self->v_info) / + (double) GST_VIDEO_INFO_PAR_D (&self->v_info)); + } + else +#endif if (gst_is_dmabuf_memory (mem)) { GdkDmabufTextureBuilder *builder = NULL; diff --git a/modules/media/meson.build b/modules/media/meson.build index 9ee3e964b9..3c07d68df9 100644 --- a/modules/media/meson.build +++ b/modules/media/meson.build @@ -8,7 +8,7 @@ extra_c_args += common_cflags if gstplayer_dep.found() and gstgl_dep.found() and gstallocators_dep.found() media_backends += 'gstreamer' cdata.set('HAVE_GSTREAMER', 1) - media_gst_deps = [ libm, libgtk_dep, gstplayer_dep, gstgl_dep, gstallocators_dep ] + media_gst_deps = [ libm, libgtk_dep, gstplayer_dep, gstgl_dep, gstallocators_dep, gstd3d12_dep ] shared_module('media-gstreamer', sources: [