d3d11videosink: Disable d3d11videosink depending on supported feature level
authorSeungha Yang <seungha@centricular.com>
Mon, 15 Jun 2020 19:41:14 +0000 (04:41 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 25 Jun 2020 07:55:47 +0000 (07:55 +0000)
Current shader code is not compatible with HLSL profile "ps_4_0_level_9_3"
or lower. So d3dcompiler cannot compile our shader code in that case.
Note that VirtualBox is one known driver which doesn't support currently
implemented shader code.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1343>

sys/d3d11/plugin.c

index d00a2592ee551edef08c5540d0d69bd79fef24ef..1ccdce230b2cb361d6388fe86a89df48a647d75c 100644 (file)
@@ -64,6 +64,9 @@ GST_DEBUG_CATEGORY (gst_d3d11_vp8_dec_debug);
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
+  GstD3D11Device *device = NULL;
+  GstRank video_sink_rank = GST_RANK_NONE;
+
   GST_DEBUG_CATEGORY_INIT (gst_d3d11_debug, "d3d11", 0, "direct3d 11 plugin");
   GST_DEBUG_CATEGORY_INIT (gst_d3d11_shader_debug,
       "d3d11shader", 0, "d3d11shader");
@@ -101,13 +104,32 @@ plugin_init (GstPlugin * plugin)
       "d3d11convert", GST_RANK_NONE, GST_TYPE_D3D11_COLOR_CONVERT);
   gst_element_register (plugin,
       "d3d11videosinkelement", GST_RANK_NONE, GST_TYPE_D3D11_VIDEO_SINK);
+
+  device = gst_d3d11_device_new (0);
+
+  /* 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;
+
+    feature_level = gst_d3d11_device_get_chosen_feature_level (device);
+    if (feature_level >= D3D_FEATURE_LEVEL_10_0)
+      video_sink_rank = GST_RANK_PRIMARY;
+  }
+
   gst_element_register (plugin,
-      "d3d11videosink", GST_RANK_PRIMARY, GST_TYPE_D3D11_VIDEO_SINK_BIN);
+      "d3d11videosink", video_sink_rank, GST_TYPE_D3D11_VIDEO_SINK_BIN);
 
 #ifdef HAVE_DXVA_H
   /* DXVA2 API is availble since Windows 8 */
   if (gst_d3d11_is_windows_8_or_greater ()) {
-    GstD3D11Device *device = NULL;
     gint i = 0;
 
     GST_DEBUG_CATEGORY_INIT (gst_d3d11_h264_dec_debug,
@@ -119,11 +141,17 @@ plugin_init (GstPlugin * plugin)
     GST_DEBUG_CATEGORY_INIT (gst_d3d11_vp8_dec_debug,
         "d3d11vp8dec", 0, "Direct3D11 VP8 Decoder");
 
-    while ((device = gst_d3d11_device_new (i)) != NULL) {
+    do {
       GstD3D11Decoder *decoder = NULL;
       gboolean legacy;
       gboolean hardware;
 
+      if (!device)
+        device = gst_d3d11_device_new (i);
+
+      if (!device)
+        break;
+
       g_object_get (device, "hardware", &hardware, NULL);
       if (!hardware)
         goto clear;
@@ -149,10 +177,12 @@ plugin_init (GstPlugin * plugin)
       gst_clear_object (&device);
       gst_clear_object (&decoder);
       i++;
-    }
+    } while (1);
   }
 #endif
 
+  gst_clear_object (&device);
+
   return TRUE;
 }