d3d11: Add support for packed 4:2:2 and 4:4:4 10bits formats
authorSeungha Yang <seungha@centricular.com>
Thu, 19 Nov 2020 12:15:25 +0000 (21:15 +0900)
committerSeungha Yang <seungha@centricular.com>
Thu, 19 Nov 2020 17:28:54 +0000 (02:28 +0900)
Add support for Y210 and Y410 formats which are commonly used format
for en/decoders on Windows. Note that those formats cannot be used for
render target (output) of shader.

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

sys/d3d11/gstd3d11colorconverter.c
sys/d3d11/gstd3d11device.c
sys/d3d11/gstd3d11format.c
sys/d3d11/gstd3d11format.h
sys/d3d11/gstd3d11memory.c
tests/check/elements/d3d11colorconvert.c

index eecaf0f..5eeb179 100644 (file)
@@ -622,6 +622,16 @@ get_packed_yuv_components (GstD3D11ColorConverter * self, GstVideoFormat
       *u = 'z';
       *v = 'x';
       break;
+    case GST_VIDEO_FORMAT_Y210:
+      *y = 'r';
+      *u = 'g';
+      *v = 'a';
+      break;
+    case GST_VIDEO_FORMAT_Y410:
+      *y = 'g';
+      *u = 'r';
+      *v = 'b';
+      break;
     default:
       g_assert_not_reached ();
       return FALSE;
@@ -645,6 +655,8 @@ setup_convert_info_yuv_to_rgb (GstD3D11ColorConverter * self,
     case GST_VIDEO_FORMAT_YUY2:
     case GST_VIDEO_FORMAT_UYVY:
     case GST_VIDEO_FORMAT_VYUY:
+    case GST_VIDEO_FORMAT_Y210:
+    case GST_VIDEO_FORMAT_Y410:
     {
       gchar y, u, v;
       if (!get_packed_yuv_components (self, GST_VIDEO_INFO_FORMAT (in_info),
@@ -954,7 +966,9 @@ setup_convert_info_yuv_to_yuv (GstD3D11ColorConverter * self,
       GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_I420_10LE);
   in_packed = (GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_YUY2 ||
       GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_UYVY ||
-      GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_VYUY);
+      GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_VYUY ||
+      GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_Y210 ||
+      GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_Y410);
   out_planar = (GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_I420 ||
       GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_I420_10LE);
 
index c022354..2220ee2 100644 (file)
@@ -460,6 +460,27 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self)
       DXGI_FORMAT_R8G8_B8G8_UNORM;
   n_formats++;
 
+  /* Y210 and Y410 formats cannot support rtv */
+  priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y210;
+  priv->format_table[n_formats].resource_format[0] =
+      DXGI_FORMAT_R16G16B16A16_UNORM;
+  if (can_support_format (self, DXGI_FORMAT_Y210,
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
+    priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_Y210;
+  else
+    priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
+  n_formats++;
+
+  priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y410;
+  priv->format_table[n_formats].resource_format[0] =
+      DXGI_FORMAT_R10G10B10A2_UNORM;
+  if (can_support_format (self, DXGI_FORMAT_Y410,
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
+    priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_Y410;
+  else
+    priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
+  n_formats++;
+
   /* YUV semi-planar */
   priv->format_table[n_formats].format = GST_VIDEO_FORMAT_NV12;
   priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM;
index f0462f5..4797591 100644 (file)
@@ -46,6 +46,9 @@ gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format)
     case DXGI_FORMAT_R16G16_UNORM:
     case DXGI_FORMAT_G8R8_G8B8_UNORM:
     case DXGI_FORMAT_R8G8_B8G8_UNORM:
+    case DXGI_FORMAT_Y210:
+    case DXGI_FORMAT_Y410:
+    case DXGI_FORMAT_R16G16B16A16_UNORM:
       return 1;
     case DXGI_FORMAT_NV12:
     case DXGI_FORMAT_P010:
@@ -77,6 +80,9 @@ gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format, guint width, guint height,
     case DXGI_FORMAT_R16G16_UNORM:
     case DXGI_FORMAT_G8R8_G8B8_UNORM:
     case DXGI_FORMAT_R8G8_B8G8_UNORM:
+    case DXGI_FORMAT_Y210:
+    case DXGI_FORMAT_Y410:
+    case DXGI_FORMAT_R16G16B16A16_UNORM:
       offset[0] = 0;
       stride[0] = pitch;
       *size = pitch * height;
index 7b0717f..63119b1 100644 (file)
@@ -29,7 +29,7 @@
     "BGRA, RGBA, RGB10A2_LE, VUYA, NV12, P010_10LE, P016_LE, I420, I420_10LE"
 
 #define GST_D3D11_EXTRA_IN_FORMATS \
-    "YUY2, UYVY, VYUY"
+    "YUY2, UYVY, VYUY, Y210, Y410"
 
 #define GST_D3D11_SINK_FORMATS \
     "{ " GST_D3D11_COMMON_FORMATS " ," GST_D3D11_EXTRA_IN_FORMATS " }"
@@ -40,7 +40,7 @@
 #define GST_D3D11_ALL_FORMATS \
     "{ " GST_D3D11_COMMON_FORMATS " ," GST_D3D11_EXTRA_IN_FORMATS " }"
 
-#define GST_D3D11_N_FORMATS 12
+#define GST_D3D11_N_FORMATS 14
 
 G_BEGIN_DECLS
 
index c448035..83fd471 100644 (file)
@@ -625,6 +625,7 @@ create_shader_resource_views (GstD3D11Memory * mem)
     case DXGI_FORMAT_R16G16_UNORM:
     case DXGI_FORMAT_G8R8_G8B8_UNORM:
     case DXGI_FORMAT_R8G8_B8G8_UNORM:
+    case DXGI_FORMAT_R16G16B16A16_UNORM:
       num_views = 1;
       formats[0] = mem->desc.Format;
       break;
@@ -644,6 +645,14 @@ create_shader_resource_views (GstD3D11Memory * mem)
       formats[0] = DXGI_FORMAT_R16_UNORM;
       formats[1] = DXGI_FORMAT_R16G16_UNORM;
       break;
+    case DXGI_FORMAT_Y210:
+      num_views = 1;
+      formats[0] = DXGI_FORMAT_R16G16B16A16_UNORM;
+      break;
+    case DXGI_FORMAT_Y410:
+      num_views = 1;
+      formats[0] = DXGI_FORMAT_R10G10B10A2_UNORM;
+      break;
     default:
       g_assert_not_reached ();
       return FALSE;
index 5665dcf..fc96fa8 100644 (file)
@@ -253,7 +253,7 @@ GST_END_TEST;
 GST_START_TEST (test_d3d11_color_convert_packed_yuv_yuv)
 {
   const gchar *in_format_list[] = {
-    "YUY2", "UYVY", "VYUY",
+    "YUY2", "UYVY", "VYUY", "Y210", "Y410",
   };
   const gchar *out_format_list[] = {
     "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE"
@@ -275,7 +275,7 @@ GST_END_TEST;
 GST_START_TEST (test_d3d11_color_convert_packed_yuv_rgb)
 {
   const gchar *in_format_list[] = {
-    "YUY2", "UYVY", "VYUY",
+    "YUY2", "UYVY", "VYUY", "Y210", "Y410",
   };
   const gchar *out_format_list[] = {
     "BGRA", "RGBA", "RGB10A2_LE",