diff --git a/sys/winscreencap/dxgicapture.c b/sys/winscreencap/dxgicapture.c index eb4060ad3a..6d2de48fae 100644 --- a/sys/winscreencap/dxgicapture.c +++ b/sys/winscreencap/dxgicapture.c @@ -24,6 +24,7 @@ #include "dxgicapture.h" #include +#include GST_DEBUG_CATEGORY_EXTERN (gst_dxgi_screen_cap_src_debug); #define GST_CAT_DEFAULT gst_dxgi_screen_cap_src_debug @@ -159,6 +160,51 @@ static void _set_verteces (DxgiCapture * self, vertex * verteces, RECT * dest_rect, const D3D11_TEXTURE2D_DESC * dst_desc, RECT * rect, const D3D11_TEXTURE2D_DESC * src_desc); +static GModule *d3d_compiler_module = NULL; +static pD3DCompile GstD3DCompileFunc = NULL; + +gboolean +gst_dxgicap_shader_init (void) +{ + static volatile gsize _init = 0; + static const gchar *d3d_compiler_names[] = { + "d3dcompiler_47.dll", + "d3dcompiler_46.dll", + "d3dcompiler_45.dll", + "d3dcompiler_44.dll", + "d3dcompiler_43.dll", + }; + + if (g_once_init_enter (&_init)) { + gint i; + for (i = 0; i < G_N_ELEMENTS (d3d_compiler_names); i++) { + d3d_compiler_module = + g_module_open (d3d_compiler_names[i], G_MODULE_BIND_LAZY); + + if (d3d_compiler_module) { + GST_INFO ("D3D compiler %s is available", d3d_compiler_names[i]); + if (!g_module_symbol (d3d_compiler_module, "D3DCompile", + (gpointer *) & GstD3DCompileFunc)) { + GST_ERROR ("Cannot load D3DCompile symbol from %s", + d3d_compiler_names[i]); + g_module_close (d3d_compiler_module); + d3d_compiler_module = NULL; + GstD3DCompileFunc = NULL; + } else { + break; + } + } + } + + if (!GstD3DCompileFunc) + GST_WARNING ("D3D11 compiler library is unavailable"); + + g_once_init_leave (&_init, 1); + } + + return ! !GstD3DCompileFunc; +} + DxgiCapture * dxgicap_new (HMONITOR monitor, GstDXGIScreenCapSrc * src) { @@ -272,13 +318,15 @@ dxgicap_new (HMONITOR monitor, GstDXGIScreenCapSrc * src) } if (DXGI_MODE_ROTATION_IDENTITY != self->dupl_desc.Rotation) { + g_assert (GstD3DCompileFunc); + /* For a rotated display, create a shader. */ - hr = D3DCompile (STR_VERTEX_SHADER, sizeof (STR_VERTEX_SHADER), + hr = GstD3DCompileFunc (STR_VERTEX_SHADER, sizeof (STR_VERTEX_SHADER), NULL, NULL, NULL, "vs_main", "vs_4_0_level_9_1", 0, 0, &vertex_shader_blob, NULL); HR_FAILED_GOTO (hr, D3DCompile, new_error); - hr = D3DCompile (STR_PIXEL_SHADER, sizeof (STR_PIXEL_SHADER), + hr = GstD3DCompileFunc (STR_PIXEL_SHADER, sizeof (STR_PIXEL_SHADER), NULL, NULL, NULL, "ps_main", "ps_4_0_level_9_1", 0, 0, &pixel_shader_blob, NULL); HR_FAILED_GOTO (hr, D3DCompile, new_error); diff --git a/sys/winscreencap/dxgicapture.h b/sys/winscreencap/dxgicapture.h index 2f6c5204ef..f2967b6b2c 100644 --- a/sys/winscreencap/dxgicapture.h +++ b/sys/winscreencap/dxgicapture.h @@ -61,6 +61,8 @@ typedef struct _GstDXGIScreenCapSrc GstDXGIScreenCapSrc; typedef struct _DxgiCapture DxgiCapture; +gboolean gst_dxgicap_shader_init (void); + DxgiCapture *dxgicap_new (HMONITOR monitor, GstDXGIScreenCapSrc * src); void dxgicap_destory (DxgiCapture * _this); diff --git a/sys/winscreencap/gstdxgiscreencapsrc.c b/sys/winscreencap/gstdxgiscreencapsrc.c index b416c9a138..2ed902aac2 100644 --- a/sys/winscreencap/gstdxgiscreencapsrc.c +++ b/sys/winscreencap/gstdxgiscreencapsrc.c @@ -43,6 +43,8 @@ #include "config.h" #endif +#include +#include #include #include "gstdxgiscreencapsrc.h" #include "dxgicapture.h" @@ -560,3 +562,20 @@ _get_hmonitor (GstDXGIScreenCapSrc * src) } return hmonitor; } + +void +gst_dxgi_screen_cap_src_register (GstPlugin * plugin, GstRank rank) +{ + if (!IsWindows8OrGreater ()) { + GST_WARNING ("OS version is too old"); + return; + } + + if (!gst_dxgicap_shader_init ()) { + GST_WARNING ("Couldn't load HLS compiler"); + return; + } + + gst_element_register (plugin, "dxgiscreencapsrc", + rank, GST_TYPE_DXGI_SCREEN_CAP_SRC); +} diff --git a/sys/winscreencap/gstdxgiscreencapsrc.h b/sys/winscreencap/gstdxgiscreencapsrc.h index 4e5fa2283e..4c08c503f1 100644 --- a/sys/winscreencap/gstdxgiscreencapsrc.h +++ b/sys/winscreencap/gstdxgiscreencapsrc.h @@ -28,5 +28,8 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (GstDXGIScreenCapSrc, gst_dxgi_screen_cap_src, GST, DXGI_SCREEN_CAP_SRC, GstPushSrc); +void gst_dxgi_screen_cap_src_register (GstPlugin * plugin, + GstRank rank); + G_END_DECLS #endif /* __GST_DXGI_SCREEN_CAP_SRC_H__ */ diff --git a/sys/winscreencap/gstwinscreencap.c b/sys/winscreencap/gstwinscreencap.c index f24939699d..9224cde4e9 100644 --- a/sys/winscreencap/gstwinscreencap.c +++ b/sys/winscreencap/gstwinscreencap.c @@ -25,7 +25,6 @@ #include "gstdx9screencapsrc.h" #ifdef HAVE_DXGI_CAP -#include #include "gstdxgiscreencapsrc.h" GST_DEBUG_CATEGORY (gst_dxgi_screen_cap_src_debug); @@ -73,16 +72,7 @@ plugin_init (GstPlugin * plugin) return FALSE; } #ifdef HAVE_DXGI_CAP - if (IsWindows8OrGreater ()) { - GST_DEBUG_CATEGORY_INIT (gst_dxgi_screen_cap_src_debug, - "dxgiscreencapsrc", 0, "DirectX DXGI screen capture source"); - - /* dxgiscreencapsrc is needs Windows8 or later. */ - if (!gst_element_register (plugin, "dxgiscreencapsrc", - GST_RANK_NONE, GST_TYPE_DXGI_SCREEN_CAP_SRC)) { - return FALSE; - } - } + gst_dxgi_screen_cap_src_register (plugin, GST_RANK_NONE); #endif return TRUE; diff --git a/sys/winscreencap/meson.build b/sys/winscreencap/meson.build index de740dd816..6700231dd9 100644 --- a/sys/winscreencap/meson.build +++ b/sys/winscreencap/meson.build @@ -17,7 +17,6 @@ d3d_dep = cc.find_library('d3d9', required : get_option('winscreencap')) gdi_dep = cc.find_library('gdi32', required : get_option('winscreencap')) d3d11_dep = cc.find_library('d3d11', required : false) dxgi_lib_dep = cc.find_library('dxgi', required : false) -d3d_compile_dep = cc.find_library('d3dcompiler', required : false) windowscodecs_dep = cc.find_library('windowscodecs', required : false) dxguid_dep = cc.find_library('dxguid', required : false) @@ -31,12 +30,12 @@ if not have_d3d9_h and get_option('winscreencap').enabled() error('winscreencap plugin enabled but d3d9.h not found') endif -have_dxgi = d3d11_dep.found() and dxgi_lib_dep.found() and d3d_compile_dep.found() and windowscodecs_dep.found() and dxguid_dep.found() and have_d3d11_h and have_dxgi_h and have_d3dcompiler_h and have_versionhelpers_h +have_dxgi = d3d11_dep.found() and dxgi_lib_dep.found() and windowscodecs_dep.found() and dxguid_dep.found() and have_d3d11_h and have_dxgi_h and have_d3dcompiler_h and have_versionhelpers_h if have_dxgi dxgi_c_args += ['-DHAVE_DXGI_CAP'] dxgiscreencap_sources += ['dxgicapture.c', 'gstdxgiscreencapsrc.c'] - dxgi_dep += [d3d11_dep, dxgi_lib_dep, d3d_compile_dep, windowscodecs_dep, dxguid_dep] + dxgi_dep += [gmodule_dep, d3d11_dep, dxgi_lib_dep, windowscodecs_dep, dxguid_dep] endif if d3d_dep.found() and gdi_dep.found() and have_d3d9_h