d3d11: Add support for packed 8bits 4:2:2 YUV formats
authorSeungha Yang <seungha@centricular.com>
Thu, 17 Sep 2020 16:41:35 +0000 (01:41 +0900)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 18 Sep 2020 14:47:21 +0000 (14:47 +0000)
Note that newly added formats (YUY2, UYVY, and VYUY) are not supported
render target view formats. So such formats can be only input of d3d11convert
or d3d11videosink. Another note is that YUY2 format is a very common
format for hardware en/decoders on Windows.

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

12 files changed:
sys/d3d11/gstd3d11colorconvert.c
sys/d3d11/gstd3d11colorconverter.c
sys/d3d11/gstd3d11device.c
sys/d3d11/gstd3d11download.c
sys/d3d11/gstd3d11format.c
sys/d3d11/gstd3d11format.h
sys/d3d11/gstd3d11memory.c
sys/d3d11/gstd3d11shader.c
sys/d3d11/gstd3d11upload.c
sys/d3d11/gstd3d11videosink.c
sys/d3d11/gstd3d11videosinkbin.c
tests/check/elements/d3d11colorconvert.c

index 5893352e904d69fa1a747f7f3943545def989f12..65c78b724307a3b2311fbb5096f0af1ebe02355b 100644 (file)
@@ -60,22 +60,22 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SINK_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS))
+            GST_D3D11_SINK_FORMATS))
     );
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SRC_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS))
+            GST_D3D11_SRC_FORMATS))
     );
 
 #define gst_d3d11_color_convert_parent_class parent_class
index 5b0a6364709c0206ee5eb061672f05851249cea7..724139f89f8ff01ada2f9d88bea9dcefa6ba431a 100644 (file)
@@ -114,6 +114,15 @@ static const gchar templ_RGB_to_VUYA_BODY[] =
     "  vuya.a = sample.a;\n"
     "  output.Plane_0 = vuya;\n";
 
+static const gchar templ_PACKED_YUV_to_RGB_BODY[] =
+    "  float4 sample, rgba;\n"
+    "  sample.x  = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.y  = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.z  = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  rgba.rgb = yuv_to_rgb (sample.xyz);\n"
+    "  rgba.a = 1;\n"
+    "  output.Plane_0 = rgba;\n";
+
 /* YUV to RGB conversion */
 static const gchar templ_PLANAR_YUV_to_RGB_BODY[] =
     "  float4 sample, rgba;\n"
@@ -221,6 +230,32 @@ static const gchar templ_SEMI_PLANAR_to_VUYA_BODY[] =
     "  sample.xy = shaderTexture[1].Sample(samplerState, input.Texture).yx;\n"
     "  output.Plane_0 = float4(sample.xyz, 1.0f);\n";
 
+static const gchar templ_PACKED_YUV_to_VUYA_BODY[] =
+    "  float4 sample;\n"
+    "  sample.z = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.y = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.x = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  output.Plane_0 = float4(sample.xyz, 1.0f);\n";
+
+/* packed YUV to (semi) planar YUV */
+static const gchar templ_PACKED_YUV_to_LUMA_BODY[] =
+    "  float4 sample;\n"
+    "  sample.x = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  output.Plane_0 = float4(sample.x / %d, 0.0, 0.0, 0.0);\n";
+
+static const gchar templ_PACKED_YUV_TO_PLANAR_CHROMA_BODY[] =
+    "  float4 sample;\n"
+    "  sample.y = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.z = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  output.Plane_0 = float4(sample.y / %d, 0.0, 0.0, 0.0);\n"
+    "  output.Plane_1 = float4(sample.z / %d, 0.0, 0.0, 0.0);\n";
+
+static const gchar templ_PACKED_YUV_TO_SEMI_PLANAR_CHROMA_BODY[] =
+    "  float4 sample;\n"
+    "  sample.y = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  sample.z = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n"
+    "  output.Plane_0 = float4(sample.yz, 0.0, 0.0);\n";
+
 static const gchar templ_pixel_shader[] =
     /* constant buffer */
     "%s\n"
@@ -544,6 +579,52 @@ setup_convert_info_rgb_to_rgb (GstD3D11ColorConverter * self,
   return TRUE;
 }
 
+static gboolean
+get_packed_yuv_components (GstD3D11ColorConverter * self, GstVideoFormat
+    format, gchar * y, gchar * u, gchar * v)
+{
+  switch (format) {
+    case GST_VIDEO_FORMAT_YUY2:
+    {
+      const GstD3D11Format *d3d11_format =
+          gst_d3d11_device_format_from_gst (self->device,
+          GST_VIDEO_FORMAT_YUY2);
+
+      g_assert (d3d11_format != NULL);
+
+      if (d3d11_format->resource_format[0] == DXGI_FORMAT_R8G8B8A8_UNORM) {
+        *y = 'x';
+        *u = 'y';
+        *v = 'a';
+      } else if (d3d11_format->resource_format[0] ==
+          DXGI_FORMAT_G8R8_G8B8_UNORM) {
+        *y = 'y';
+        *u = 'x';
+        *v = 'z';
+      } else {
+        g_assert_not_reached ();
+        return FALSE;
+      }
+      break;
+    }
+    case GST_VIDEO_FORMAT_UYVY:
+      *y = 'y';
+      *u = 'x';
+      *v = 'z';
+      break;
+    case GST_VIDEO_FORMAT_VYUY:
+      *y = 'y';
+      *u = 'z';
+      *v = 'x';
+      break;
+    default:
+      g_assert_not_reached ();
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
 static gboolean
 setup_convert_info_yuv_to_rgb (GstD3D11ColorConverter * self,
     const GstVideoInfo * in_info, const GstVideoInfo * out_info)
@@ -556,6 +637,20 @@ setup_convert_info_yuv_to_rgb (GstD3D11ColorConverter * self,
     case GST_VIDEO_FORMAT_VUYA:
       info->ps_body[0] = g_strdup_printf (templ_VUYA_to_RGB_BODY);
       break;
+    case GST_VIDEO_FORMAT_YUY2:
+    case GST_VIDEO_FORMAT_UYVY:
+    case GST_VIDEO_FORMAT_VYUY:
+    {
+      gchar y, u, v;
+      if (!get_packed_yuv_components (self, GST_VIDEO_INFO_FORMAT (in_info),
+              &y, &u, &v)) {
+        return FALSE;
+      }
+
+      info->ps_body[0] =
+          g_strdup_printf (templ_PACKED_YUV_to_RGB_BODY, y, u, v);
+      break;
+    }
     case GST_VIDEO_FORMAT_I420:
       info->ps_body[0] =
           g_strdup_printf (templ_PLANAR_YUV_to_RGB_BODY, 1, 1, 1);
@@ -761,6 +856,25 @@ setup_convert_info_planar_to_vuya (GstD3D11ColorConverter * self,
   return TRUE;
 }
 
+static gboolean
+setup_convert_info_packed_yuv_to_vuya (GstD3D11ColorConverter * self,
+    const GstVideoInfo * in_info, const GstVideoInfo * out_info)
+{
+  ConvertInfo *info = &self->convert_info;
+  gchar y, u, v;
+
+  info->templ = &templ_REORDER;
+
+  if (!get_packed_yuv_components (self, GST_VIDEO_INFO_FORMAT (in_info),
+          &y, &u, &v)) {
+    return FALSE;
+  }
+
+  info->ps_body[0] = g_strdup_printf (templ_PACKED_YUV_to_VUYA_BODY, y, u, v);
+
+  return TRUE;
+}
+
 static gboolean
 setup_convert_info_semi_planar_to_vuya (GstD3D11ColorConverter * self,
     const GstVideoInfo * in_info, const GstVideoInfo * out_info)
@@ -774,20 +888,72 @@ setup_convert_info_semi_planar_to_vuya (GstD3D11ColorConverter * self,
   return TRUE;
 }
 
+static gboolean
+setup_convert_info_packed_yuv_to_planar (GstD3D11ColorConverter * self,
+    const GstVideoInfo * in_info, const GstVideoInfo * out_info)
+{
+  ConvertInfo *info = &self->convert_info;
+  gint div = 1;
+  gchar y, u, v;
+
+  info->templ = &templ_REORDER;
+
+  if (GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_I420_10LE)
+    div = 64;
+
+  if (!get_packed_yuv_components (self, GST_VIDEO_INFO_FORMAT (in_info),
+          &y, &u, &v)) {
+    return FALSE;
+  }
+
+  info->ps_body[0] = g_strdup_printf (templ_PACKED_YUV_to_LUMA_BODY, y, div);
+  info->ps_body[1] =
+      g_strdup_printf (templ_PACKED_YUV_TO_PLANAR_CHROMA_BODY, u, v, div, div);
+
+  return TRUE;
+}
+
+static gboolean
+setup_convert_info_packed_yuv_to_semi_planar (GstD3D11ColorConverter * self,
+    const GstVideoInfo * in_info, const GstVideoInfo * out_info)
+{
+  ConvertInfo *info = &self->convert_info;
+  gint div = 1;
+  gchar y, u, v;
+
+  info->templ = &templ_REORDER;
+
+  if (!get_packed_yuv_components (self, GST_VIDEO_INFO_FORMAT (in_info),
+          &y, &u, &v)) {
+    return FALSE;
+  }
+
+  info->ps_body[0] = g_strdup_printf (templ_PACKED_YUV_to_LUMA_BODY, y, div);
+  info->ps_body[1] =
+      g_strdup_printf (templ_PACKED_YUV_TO_SEMI_PLANAR_CHROMA_BODY, u, v);
+
+  return TRUE;
+}
+
 static gboolean
 setup_convert_info_yuv_to_yuv (GstD3D11ColorConverter * self,
     const GstVideoInfo * in_info, const GstVideoInfo * out_info)
 {
   gboolean in_planar, out_planar;
   gboolean in_vuya, out_vuya;
+  gboolean in_packed;
 
   in_vuya = GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_VUYA;
   out_vuya = GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_VUYA;
   in_planar = (GST_VIDEO_INFO_FORMAT (in_info) == GST_VIDEO_FORMAT_I420 ||
       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);
   out_planar = (GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_I420 ||
       GST_VIDEO_INFO_FORMAT (out_info) == GST_VIDEO_FORMAT_I420_10LE);
 
+  /* From/to VUYA */
   if (in_vuya && out_vuya) {
     return setup_convert_info_vuya_to_vuya (self, in_info, out_info);
   } else if (in_vuya) {
@@ -798,6 +964,8 @@ setup_convert_info_yuv_to_yuv (GstD3D11ColorConverter * self,
   } else if (out_vuya) {
     if (in_planar)
       return setup_convert_info_planar_to_vuya (self, in_info, out_info);
+    else if (in_packed)
+      return setup_convert_info_packed_yuv_to_vuya (self, in_info, out_info);
     else
       return setup_convert_info_semi_planar_to_vuya (self, in_info, out_info);
   }
@@ -807,6 +975,12 @@ setup_convert_info_yuv_to_yuv (GstD3D11ColorConverter * self,
       return setup_convert_info_planar_to_planar (self, in_info, out_info);
     else
       return setup_convert_info_planar_to_semi_planar (self, in_info, out_info);
+  } else if (in_packed) {
+    if (out_planar)
+      return setup_convert_info_packed_yuv_to_planar (self, in_info, out_info);
+    else
+      return setup_convert_info_packed_yuv_to_semi_planar (self, in_info,
+          out_info);
   } else {
     if (out_planar)
       return setup_convert_info_semi_planar_to_planar (self, in_info, out_info);
index 0641e5a5000f8a77ecac3d566563f826f23fc921..c022354fabbd8c0aab2f8b94c5468e1f786c3d29 100644 (file)
@@ -361,15 +361,16 @@ gst_d3d11_device_init (GstD3D11Device * self)
 }
 
 static gboolean
-can_support_format (GstD3D11Device * self, DXGI_FORMAT format)
+can_support_format (GstD3D11Device * self, DXGI_FORMAT format,
+    D3D11_FORMAT_SUPPORT extra_flags)
 {
   GstD3D11DevicePrivate *priv = self->priv;
   ID3D11Device *handle = priv->device;
   HRESULT hr;
   UINT supported;
-  D3D11_FORMAT_SUPPORT flags =
-      (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET |
-      D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
+  D3D11_FORMAT_SUPPORT flags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
+
+  flags |= extra_flags;
 
   if (!gst_d3d11_is_windows_8_or_greater ()) {
     GST_WARNING_OBJECT (self, "DXGI format %d needs Windows 8 or greater",
@@ -422,17 +423,50 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self)
   /* YUV packed */
   priv->format_table[n_formats].format = GST_VIDEO_FORMAT_VUYA;
   priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
-  if (can_support_format (self, DXGI_FORMAT_AYUV))
+  if (can_support_format (self, DXGI_FORMAT_AYUV,
+          D3D11_FORMAT_SUPPORT_RENDER_TARGET |
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_AYUV;
   else
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
   n_formats++;
 
+  /* NOTE: packted yuv 4:2:2 YUY2, UYVY, and VYUY formats are not natively
+   * supported render target view formats
+   * (i.e., cannot be output format of shader pipeline) */
+  priv->format_table[n_formats].format = GST_VIDEO_FORMAT_YUY2;
+  if (can_support_format (self, DXGI_FORMAT_YUY2,
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) {
+    priv->format_table[n_formats].resource_format[0] =
+        DXGI_FORMAT_R8G8B8A8_UNORM;
+    priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_YUY2;
+  } else {
+    /* If DXGI_FORMAT_YUY2 format is not supported, use this format,
+     * it's analogous to YUY2 */
+    priv->format_table[n_formats].resource_format[0] =
+        DXGI_FORMAT_G8R8_G8B8_UNORM;
+  }
+  n_formats++;
+
+  /* No native DXGI format available for UYVY */
+  priv->format_table[n_formats].format = GST_VIDEO_FORMAT_UYVY;
+  priv->format_table[n_formats].resource_format[0] =
+      DXGI_FORMAT_R8G8_B8G8_UNORM;
+  n_formats++;
+
+  /* No native DXGI format available for VYUY */
+  priv->format_table[n_formats].format = GST_VIDEO_FORMAT_VYUY;
+  priv->format_table[n_formats].resource_format[0] =
+      DXGI_FORMAT_R8G8_B8G8_UNORM;
+  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;
   priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8G8_UNORM;
-  if (can_support_format (self, DXGI_FORMAT_NV12))
+  if (can_support_format (self, DXGI_FORMAT_NV12,
+          D3D11_FORMAT_SUPPORT_RENDER_TARGET |
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_NV12;
   else
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
@@ -441,7 +475,9 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self)
   priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P010_10LE;
   priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM;
   priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16G16_UNORM;
-  if (can_support_format (self, DXGI_FORMAT_P010))
+  if (can_support_format (self, DXGI_FORMAT_P010,
+          D3D11_FORMAT_SUPPORT_RENDER_TARGET |
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_P010;
   else
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
@@ -450,13 +486,15 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self)
   priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P016_LE;
   priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM;
   priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16G16_UNORM;
-  if (can_support_format (self, DXGI_FORMAT_P016))
+  if (can_support_format (self, DXGI_FORMAT_P016,
+          D3D11_FORMAT_SUPPORT_RENDER_TARGET |
+          D3D11_FORMAT_SUPPORT_SHADER_SAMPLE))
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_P016;
   else
     priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN;
   n_formats++;
 
-  /* YUV plannar */
+  /* YUV planar */
   priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I420;
   priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM;
   priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM;
index 574ecfe1399c952446955c35433a42dda0647a84..71762097734f6a56c0c967176a6d095dfc16133b 100644 (file)
@@ -34,32 +34,32 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS) "; "
-        GST_VIDEO_CAPS_MAKE (GST_D3D11_FORMATS) "; "
+            GST_D3D11_ALL_FORMATS) "; "
+        GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS)
+            GST_D3D11_ALL_FORMATS)
     ));
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS) "; "
-        GST_VIDEO_CAPS_MAKE (GST_D3D11_FORMATS) "; "
+            GST_D3D11_ALL_FORMATS) "; "
+        GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS)
+            GST_D3D11_ALL_FORMATS)
     ));
 
 #define gst_d3d11_download_parent_class parent_class
index 29148ae1382be983f5811f731ddfc93a4ec6b21a..336788e059e8bcc905e84587914e4931cc11726e 100644 (file)
@@ -39,10 +39,13 @@ gst_d3d11_dxgi_format_n_planes (DXGI_FORMAT format)
     case DXGI_FORMAT_R8G8B8A8_UNORM:
     case DXGI_FORMAT_R10G10B10A2_UNORM:
     case DXGI_FORMAT_AYUV:
+    case DXGI_FORMAT_YUY2:
     case DXGI_FORMAT_R8_UNORM:
     case DXGI_FORMAT_R8G8_UNORM:
     case DXGI_FORMAT_R16_UNORM:
     case DXGI_FORMAT_R16G16_UNORM:
+    case DXGI_FORMAT_G8R8_G8B8_UNORM:
+    case DXGI_FORMAT_R8G8_B8G8_UNORM:
       return 1;
     case DXGI_FORMAT_NV12:
     case DXGI_FORMAT_P010:
@@ -67,10 +70,13 @@ gst_d3d11_dxgi_format_get_size (DXGI_FORMAT format, guint width, guint height,
     case DXGI_FORMAT_R8G8B8A8_UNORM:
     case DXGI_FORMAT_R10G10B10A2_UNORM:
     case DXGI_FORMAT_AYUV:
+    case DXGI_FORMAT_YUY2:
     case DXGI_FORMAT_R8_UNORM:
     case DXGI_FORMAT_R8G8_UNORM:
     case DXGI_FORMAT_R16_UNORM:
     case DXGI_FORMAT_R16G16_UNORM:
+    case DXGI_FORMAT_G8R8_G8B8_UNORM:
+    case DXGI_FORMAT_R8G8_B8G8_UNORM:
       offset[0] = 0;
       stride[0] = pitch;
       *size = pitch * height;
index 5c28072116cec5daeb823507f96b62d73e797c22..7b0717fa865cec6fb677fcdb47210168f9d1b36d 100644 (file)
 
 #include "gstd3d11_fwd.h"
 
-#define GST_D3D11_FORMATS \
-    "{ BGRA, RGBA, RGB10A2_LE, VUYA, NV12, P010_10LE, P016_LE, I420, I420_10LE }"
-#define GST_D3D11_N_FORMATS 9
+#define GST_D3D11_COMMON_FORMATS \
+    "BGRA, RGBA, RGB10A2_LE, VUYA, NV12, P010_10LE, P016_LE, I420, I420_10LE"
+
+#define GST_D3D11_EXTRA_IN_FORMATS \
+    "YUY2, UYVY, VYUY"
+
+#define GST_D3D11_SINK_FORMATS \
+    "{ " GST_D3D11_COMMON_FORMATS " ," GST_D3D11_EXTRA_IN_FORMATS " }"
+
+#define GST_D3D11_SRC_FORMATS \
+    "{ " GST_D3D11_COMMON_FORMATS " }"
+
+#define GST_D3D11_ALL_FORMATS \
+    "{ " GST_D3D11_COMMON_FORMATS " ," GST_D3D11_EXTRA_IN_FORMATS " }"
+
+#define GST_D3D11_N_FORMATS 12
 
 G_BEGIN_DECLS
 
index 9fa9cf8e7cedd5847f3e80830db5ff98fd29e993..d1a43e5a4d17ec66c274662b4cd38491bd6959eb 100644 (file)
@@ -547,10 +547,13 @@ create_shader_resource_views (GstD3D11Memory * mem)
     case DXGI_FORMAT_R8G8_UNORM:
     case DXGI_FORMAT_R16_UNORM:
     case DXGI_FORMAT_R16G16_UNORM:
+    case DXGI_FORMAT_G8R8_G8B8_UNORM:
+    case DXGI_FORMAT_R8G8_B8G8_UNORM:
       num_views = 1;
       formats[0] = mem->desc.Format;
       break;
     case DXGI_FORMAT_AYUV:
+    case DXGI_FORMAT_YUY2:
       num_views = 1;
       formats[0] = DXGI_FORMAT_R8G8B8A8_UNORM;
       break;
index d2ab639ac86231ca4eb86705a8909755fe4fad9c..f3fc0d9715335ffb6d3095ba060d9b2c0df0d9da 100644 (file)
@@ -114,6 +114,8 @@ compile_shader (GstD3D11Device * device, const gchar * shader_source,
 
   g_assert (GstD3DCompileFunc);
 
+  GST_TRACE ("Compile code \n%s", shader_source);
+
   hr = GstD3DCompileFunc (shader_source, strlen (shader_source), NULL, NULL,
       NULL, "main", shader_target, 0, 0, &ret, &error);
 
index 0485e62c9635a0272f5f6b24a6ee85aff152d92b..3ed64ac07b376c3e82e39744ee2e98964582837e 100644 (file)
@@ -35,27 +35,27 @@ GST_DEBUG_CATEGORY_STATIC (gst_d3d11_upload_debug);
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_D3D11_FORMATS) "; "
+    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS) "; "
+            GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY,
-            GST_D3D11_FORMATS) ";"
+            GST_D3D11_ALL_FORMATS) ";"
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY
             "," GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS))
+            GST_D3D11_ALL_FORMATS))
     );
 
 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_ALL_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS)));
+            GST_D3D11_ALL_FORMATS)));
 
 #define gst_d3d11_upload_parent_class parent_class
 G_DEFINE_TYPE (GstD3D11Upload, gst_d3d11_upload, GST_TYPE_D3D11_BASE_FILTER);
index 2d36896ab84d9bdfd086ced9dac5352e157b7761..f8ce40e595762c673dc2bc5132a6c1bc66ba8bc9 100644 (file)
@@ -56,11 +56,11 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SINK_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS)
+            GST_D3D11_SINK_FORMATS)
     ));
 
 GST_DEBUG_CATEGORY (d3d11_video_sink_debug);
index 1fd8052547e0d259f1f7ff9af74eb9230abe145d..aeb807a9f9e15860d003616d8f652bcc32f18541 100644 (file)
@@ -85,16 +85,16 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE_WITH_FEATURES
-        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_FORMATS) "; "
+        (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY, GST_D3D11_SINK_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS) ";"
-        GST_VIDEO_CAPS_MAKE (GST_D3D11_FORMATS) "; "
+            GST_D3D11_SINK_FORMATS) ";"
+        GST_VIDEO_CAPS_MAKE (GST_D3D11_SINK_FORMATS) "; "
         GST_VIDEO_CAPS_MAKE_WITH_FEATURES
         (GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY ","
             GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
-            GST_D3D11_FORMATS)
+            GST_D3D11_SINK_FORMATS)
     ));
 
 GST_DEBUG_CATEGORY (d3d11_video_sink_bin_debug);
index 67a831dc8bd02e93fbe303ba11451c3470550ae2..5665dcff18044fb66be930a846247302cbb9a7ff 100644 (file)
@@ -53,7 +53,7 @@ static TestFrame test_rgba_reorder[] = {
 GST_START_TEST (test_d3d11_color_convert_rgba_reorder)
 {
   GstHarness *h =
-      gst_harness_new_parse ("d3d11upload ! d3d11colorconvert ! d3d11download");
+      gst_harness_new_parse ("d3d11upload ! d3d11convert ! d3d11download");
   gint i, j, k;
 
   for (i = 0; i < G_N_ELEMENTS (test_rgba_reorder); i++) {
@@ -139,7 +139,7 @@ run_convert_pipelne (const gchar * in_format, const gchar * out_format)
   gchar *pipeline_str =
       g_strdup_printf ("videotestsrc num-buffers=1 is-live=true ! "
       "video/x-raw,format=%s,framerate=3/1 ! d3d11upload ! "
-      "d3d11colorconvert ! d3d11download ! video/x-raw,format=%s ! "
+      "d3d11convert ! d3d11download ! video/x-raw,format=%s ! "
       "videoconvert ! d3d11videosink", in_format, out_format);
   GstElement *pipeline;
 
@@ -248,6 +248,50 @@ GST_START_TEST (test_d3d11_color_convert_rgb_rgb)
   }
 }
 
+GST_END_TEST;
+
+GST_START_TEST (test_d3d11_color_convert_packed_yuv_yuv)
+{
+  const gchar *in_format_list[] = {
+    "YUY2", "UYVY", "VYUY",
+  };
+  const gchar *out_format_list[] = {
+    "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE"
+  };
+
+  gint i, j;
+
+  for (i = 0; i < G_N_ELEMENTS (in_format_list); i++) {
+    for (j = 0; j < G_N_ELEMENTS (out_format_list); j++) {
+      GST_DEBUG ("run conversion %s to %s", in_format_list[i],
+          out_format_list[j]);
+      run_convert_pipelne (in_format_list[i], out_format_list[j]);
+    }
+  }
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_d3d11_color_convert_packed_yuv_rgb)
+{
+  const gchar *in_format_list[] = {
+    "YUY2", "UYVY", "VYUY",
+  };
+  const gchar *out_format_list[] = {
+    "BGRA", "RGBA", "RGB10A2_LE",
+  };
+
+  gint i, j;
+
+  for (i = 0; i < G_N_ELEMENTS (in_format_list); i++) {
+    for (j = 0; j < G_N_ELEMENTS (out_format_list); j++) {
+      GST_DEBUG ("run conversion %s to %s", in_format_list[i],
+          out_format_list[j]);
+      run_convert_pipelne (in_format_list[i], out_format_list[j]);
+    }
+  }
+}
+
 GST_END_TEST;
 #endif /* RUN_VISUAL_TEST */
 
@@ -264,6 +308,8 @@ d3d11colorconvert_suite (void)
   tcase_add_test (tc_basic, test_d3d11_color_convert_yuv_rgb);
   tcase_add_test (tc_basic, test_d3d11_color_convert_rgb_yuv);
   tcase_add_test (tc_basic, test_d3d11_color_convert_rgb_rgb);
+  tcase_add_test (tc_basic, test_d3d11_color_convert_packed_yuv_yuv);
+  tcase_add_test (tc_basic, test_d3d11_color_convert_packed_yuv_rgb);
 #endif
 
   return s;