d3d11window: Do not check shader resource view if not doing conversion
authorSeungha Yang <seungha.yang@navercorp.com>
Sun, 8 Dec 2019 15:14:53 +0000 (00:14 +0900)
committerSeungha Yang <seungha.yang@navercorp.com>
Tue, 10 Dec 2019 04:06:28 +0000 (04:06 +0000)
If d3d11window does not convert format internally, shader resource view
is not required. Note that shader resource view is used for
color conversion using shader but when conversion is not required,
we just copy input input texture to backbuffer.

sys/d3d11/gstd3d11videosink.c
sys/d3d11/gstd3d11videosink.h
sys/d3d11/gstd3d11window.c
sys/d3d11/gstd3d11window.h

index cb1f7fc..e3adf37 100644 (file)
@@ -247,7 +247,6 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
   guint num, den;
   GError *error = NULL;
   GstStructure *config;
-  GstD3D11AllocationParams *d3d11_params;
   gint i;
 
   GST_DEBUG_OBJECT (self, "set caps %" GST_PTR_FORMAT, caps);
@@ -339,7 +338,7 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
 
   if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self),
           GST_VIDEO_SINK_HEIGHT (self), video_par_n, video_par_d,
-          caps, &error)) {
+          caps, &self->need_srv, &error)) {
     GstMessage *error_msg;
 
     GST_ERROR_OBJECT (self, "cannot create swapchain");
@@ -361,20 +360,25 @@ gst_d3d11_video_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
   gst_buffer_pool_config_set_params (config,
       caps, GST_VIDEO_INFO_SIZE (&self->info), 0, 2);
 
-  d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
-  if (!d3d11_params) {
-    d3d11_params = gst_d3d11_allocation_params_new (&self->info,
-        GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT,
-        D3D11_BIND_SHADER_RESOURCE);
-  } else {
-    /* Set bind flag */
-    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->info); i++) {
-      d3d11_params->desc[i].BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+  if (self->need_srv) {
+    GstD3D11AllocationParams *d3d11_params;
+
+    d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
+    if (!d3d11_params) {
+      d3d11_params = gst_d3d11_allocation_params_new (&self->info,
+          GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT,
+          D3D11_BIND_SHADER_RESOURCE);
+    } else {
+      /* Set bind flag */
+      for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&self->info); i++) {
+        d3d11_params->desc[i].BindFlags |= 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_d3d11_allocation_params (config, d3d11_params);
-  gst_d3d11_allocation_params_free (d3d11_params);
   gst_buffer_pool_set_config (self->fallback_pool, config);
 
   return TRUE;
@@ -519,8 +523,8 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query)
   size = info.size;
 
   if (need_pool) {
-    GstD3D11AllocationParams *d3d11_params;
     gint i;
+    GstCaps *render_caps;
 
     GST_DEBUG_OBJECT (self, "create new pool");
 
@@ -529,20 +533,34 @@ gst_d3d11_video_sink_propose_allocation (GstBaseSink * sink, GstQuery * query)
     gst_buffer_pool_config_set_params (config, caps, size, 2,
         DXGI_MAX_SWAP_CHAIN_BUFFERS);
 
-    d3d11_params = gst_buffer_pool_config_get_d3d11_allocation_params (config);
-    if (!d3d11_params) {
-      d3d11_params = gst_d3d11_allocation_params_new (&info,
-          GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT,
-          D3D11_BIND_SHADER_RESOURCE);
-    } else {
-      /* Set bind flag */
-      for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&info); i++) {
-        d3d11_params->desc[i].BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+    render_caps = gst_d3d11_device_get_supported_caps (self->device,
+        D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DISPLAY);
+
+    /* if we need conversion, request shader resource view */
+    if (render_caps && !gst_caps_can_intersect (caps, render_caps)) {
+      GstD3D11AllocationParams *d3d11_params;
+
+      GST_DEBUG_OBJECT (self,
+          "upstream format %s is not display foramt, need shader resource",
+          gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&info)));
+
+      d3d11_params =
+          gst_buffer_pool_config_get_d3d11_allocation_params (config);
+      if (!d3d11_params) {
+        d3d11_params = gst_d3d11_allocation_params_new (&info,
+            GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT, D3D11_USAGE_DEFAULT,
+            D3D11_BIND_SHADER_RESOURCE);
+      } else {
+        /* Set bind flag */
+        for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&info); i++) {
+          d3d11_params->desc[i].BindFlags |= 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_d3d11_allocation_params (config, d3d11_params);
+      gst_d3d11_allocation_params_free (d3d11_params);
+    }
+    gst_clear_caps (&render_caps);
 
     if (!gst_buffer_pool_set_config (pool, config)) {
       g_object_unref (pool);
@@ -653,7 +671,7 @@ gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf)
       break;
     }
 
-    if (!gst_d3d11_memory_ensure_shader_resource_view (mem)) {
+    if (self->need_srv && !gst_d3d11_memory_ensure_shader_resource_view (mem)) {
       render_buf = NULL;
       break;
     }
index 768bdf0..d3225cf 100644 (file)
@@ -64,6 +64,9 @@ struct _GstD3D11VideoSink
 
   GstBufferPool *fallback_pool;
   gboolean can_convert;
+
+  /* whether shader resource view is required for direct rendering or not */
+  gboolean need_srv;
 };
 
 struct _GstD3D11VideoSinkClass
index ab83f0a..f9f4a44 100644 (file)
@@ -982,7 +982,8 @@ gst_d3d11_window_color_space_from_video_info (GstD3D11Window * self,
 
 gboolean
 gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
-    guint aspect_ratio_n, guint aspect_ratio_d, GstCaps * caps, GError ** error)
+    guint aspect_ratio_n, guint aspect_ratio_d, GstCaps * caps,
+    gboolean * do_convert, GError ** error)
 {
   DXGI_SWAP_CHAIN_DESC desc = { 0, };
   GstD3D11ThreadFuncData data;
@@ -996,6 +997,7 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
   g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE);
   g_return_val_if_fail (aspect_ratio_n > 0, FALSE);
   g_return_val_if_fail (aspect_ratio_d > 0, FALSE);
+  g_return_val_if_fail (do_convert != NULL, FALSE);
 
   GST_DEBUG_OBJECT (window, "Prepare window with %dx%d caps %" GST_PTR_FORMAT,
       width, height, caps);
@@ -1186,6 +1188,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint width, guint height,
 
   GST_DEBUG_OBJECT (window, "New swap chain 0x%p created", window->swap_chain);
 
+  *do_convert = ! !window->converter;
+
   return TRUE;
 }
 
index dc9d0dc..c7b0431 100644 (file)
@@ -130,6 +130,7 @@ gboolean gst_d3d11_window_prepare (GstD3D11Window * window,
                                    guint aspect_ratio_n,
                                    guint aspect_ratio_d,
                                    GstCaps * caps,
+                                   gboolean * do_convert,
                                    GError ** error);
 
 GstFlowReturn gst_d3d11_window_render (GstD3D11Window * window,