From ea24a2e5279c7920ee925ef774e081a03c1650fc Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 18 Sep 2020 01:41:35 +0900 Subject: [PATCH] d3d11: Add support for packed 8bits 4:2:2 YUV formats 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: --- sys/d3d11/gstd3d11colorconvert.c | 8 +- sys/d3d11/gstd3d11colorconverter.c | 174 +++++++++++++++++++++++ sys/d3d11/gstd3d11device.c | 56 ++++++-- sys/d3d11/gstd3d11download.c | 16 +-- sys/d3d11/gstd3d11format.c | 6 + sys/d3d11/gstd3d11format.h | 19 ++- sys/d3d11/gstd3d11memory.c | 3 + sys/d3d11/gstd3d11shader.c | 2 + sys/d3d11/gstd3d11upload.c | 12 +- sys/d3d11/gstd3d11videosink.c | 4 +- sys/d3d11/gstd3d11videosinkbin.c | 8 +- tests/check/elements/d3d11colorconvert.c | 50 ++++++- 12 files changed, 320 insertions(+), 38 deletions(-) diff --git a/sys/d3d11/gstd3d11colorconvert.c b/sys/d3d11/gstd3d11colorconvert.c index 5893352e90..65c78b7243 100644 --- a/sys/d3d11/gstd3d11colorconvert.c +++ b/sys/d3d11/gstd3d11colorconvert.c @@ -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 diff --git a/sys/d3d11/gstd3d11colorconverter.c b/sys/d3d11/gstd3d11colorconverter.c index 5b0a636470..724139f89f 100644 --- a/sys/d3d11/gstd3d11colorconverter.c +++ b/sys/d3d11/gstd3d11colorconverter.c @@ -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); diff --git a/sys/d3d11/gstd3d11device.c b/sys/d3d11/gstd3d11device.c index 0641e5a500..c022354fab 100644 --- a/sys/d3d11/gstd3d11device.c +++ b/sys/d3d11/gstd3d11device.c @@ -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; diff --git a/sys/d3d11/gstd3d11download.c b/sys/d3d11/gstd3d11download.c index 574ecfe139..7176209773 100644 --- a/sys/d3d11/gstd3d11download.c +++ b/sys/d3d11/gstd3d11download.c @@ -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 diff --git a/sys/d3d11/gstd3d11format.c b/sys/d3d11/gstd3d11format.c index 29148ae138..336788e059 100644 --- a/sys/d3d11/gstd3d11format.c +++ b/sys/d3d11/gstd3d11format.c @@ -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; diff --git a/sys/d3d11/gstd3d11format.h b/sys/d3d11/gstd3d11format.h index 5c28072116..7b0717fa86 100644 --- a/sys/d3d11/gstd3d11format.h +++ b/sys/d3d11/gstd3d11format.h @@ -25,9 +25,22 @@ #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 diff --git a/sys/d3d11/gstd3d11memory.c b/sys/d3d11/gstd3d11memory.c index 9fa9cf8e7c..d1a43e5a4d 100644 --- a/sys/d3d11/gstd3d11memory.c +++ b/sys/d3d11/gstd3d11memory.c @@ -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; diff --git a/sys/d3d11/gstd3d11shader.c b/sys/d3d11/gstd3d11shader.c index d2ab639ac8..f3fc0d9715 100644 --- a/sys/d3d11/gstd3d11shader.c +++ b/sys/d3d11/gstd3d11shader.c @@ -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); diff --git a/sys/d3d11/gstd3d11upload.c b/sys/d3d11/gstd3d11upload.c index 0485e62c96..3ed64ac07b 100644 --- a/sys/d3d11/gstd3d11upload.c +++ b/sys/d3d11/gstd3d11upload.c @@ -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); diff --git a/sys/d3d11/gstd3d11videosink.c b/sys/d3d11/gstd3d11videosink.c index 2d36896ab8..f8ce40e595 100644 --- a/sys/d3d11/gstd3d11videosink.c +++ b/sys/d3d11/gstd3d11videosink.c @@ -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); diff --git a/sys/d3d11/gstd3d11videosinkbin.c b/sys/d3d11/gstd3d11videosinkbin.c index 1fd8052547..aeb807a9f9 100644 --- a/sys/d3d11/gstd3d11videosinkbin.c +++ b/sys/d3d11/gstd3d11videosinkbin.c @@ -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); diff --git a/tests/check/elements/d3d11colorconvert.c b/tests/check/elements/d3d11colorconvert.c index 67a831dc8b..5665dcff18 100644 --- a/tests/check/elements/d3d11colorconvert.c +++ b/tests/check/elements/d3d11colorconvert.c @@ -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;