From 7c94b9c4b0d70366bd016f4d2e22f06e576323cd Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Mon, 21 Jun 2021 17:13:33 +0900 Subject: [PATCH] d3d11: Add support for GRAY and more YUV formats By this commit, following formats will be newly supported by d3d11 elements * Y444_{8, 12, 16}LE formats: Similar to other planar formats. Such Y444 variants are not supported by Direct3D11 natively, but we can simply map each plane by using R8 and/or R16 texture. * P012_LE: It is not different from P016_LE, but defining P012 and P016 separately for more explicit signalling. Note that DXVA uses P016 texture for 12bits encoded bitstreams. * GRAY: This format is required for some codecs (e.g., AV1) if monochrome is supported * 4:2:0 planar 12bits (I420_12LE) and 4:2:2 planar 8, 10, 12bits formats (Y42B, I422_10LE, and I422_12LE) Part-of: --- gst-libs/gst/d3d11/gstd3d11device.cpp | 77 ++++++- gst-libs/gst/d3d11/gstd3d11format.h | 4 +- sys/d3d11/gstd3d11converter.cpp | 333 ++++++++++++++++++++++++++++++- sys/d3d11/gstd3d11deinterlace.cpp | 8 + tests/check/elements/d3d11colorconvert.c | 201 ++++++++++++------- 5 files changed, 545 insertions(+), 78 deletions(-) diff --git a/gst-libs/gst/d3d11/gstd3d11device.cpp b/gst-libs/gst/d3d11/gstd3d11device.cpp index 41d48bf..0b03a0a 100644 --- a/gst-libs/gst/d3d11/gstd3d11device.cpp +++ b/gst-libs/gst/d3d11/gstd3d11device.cpp @@ -95,7 +95,7 @@ enum #define DEFAULT_ADAPTER 0 #define DEFAULT_CREATE_FLAGS 0 -#define GST_D3D11_N_FORMATS 18 +#define GST_D3D11_N_FORMATS 29 struct _GstD3D11DevicePrivate { @@ -627,6 +627,18 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self) priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_UNKNOWN; n_formats++; + /* P012 is identical to P016 from runtime point of view */ + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_P012_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, + 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++; + 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; @@ -657,6 +669,69 @@ gst_d3d11_device_setup_format_table (GstD3D11Device * self) priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; n_formats++; + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I420_12LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y42B; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I422_10LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_I422_12LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R8_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R8_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_10LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_12LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_Y444_16LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[1] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].resource_format[2] = DXGI_FORMAT_R16_UNORM; + n_formats++; + + /* GRAY */ + /* NOTE: To support conversion by using video processor, + * mark DXGI_FORMAT_{R8,R16}_UNORM formats as known dxgi_format. + * Otherwise, d3d11 elements will not try to use video processor for + * those formats */ + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_GRAY8; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R8_UNORM; + priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R8_UNORM; + n_formats++; + + priv->format_table[n_formats].format = GST_VIDEO_FORMAT_GRAY16_LE; + priv->format_table[n_formats].resource_format[0] = DXGI_FORMAT_R16_UNORM; + priv->format_table[n_formats].dxgi_format = DXGI_FORMAT_R16_UNORM; + n_formats++; + g_assert (n_formats == GST_D3D11_N_FORMATS); } diff --git a/gst-libs/gst/d3d11/gstd3d11format.h b/gst-libs/gst/d3d11/gstd3d11format.h index fb2980d..de0bb38 100644 --- a/gst-libs/gst/d3d11/gstd3d11format.h +++ b/gst-libs/gst/d3d11/gstd3d11format.h @@ -28,7 +28,9 @@ G_BEGIN_DECLS #define GST_D3D11_COMMON_FORMATS \ "BGRA, RGBA, RGB10A2_LE, BGRx, RGBx, VUYA, NV12, NV21, " \ - "P010_10LE, P016_LE, I420, YV12, I420_10LE" + "P010_10LE, P012_LE, P016_LE, I420, YV12, I420_10LE, I420_12LE, " \ + "Y42B, I422_10LE, I422_12LE, Y444, Y444_10LE, Y444_12LE, Y444_16LE, " \ + "GRAY8, GRAY16_LE" #define GST_D3D11_EXTRA_IN_FORMATS \ "YUY2, UYVY, VYUY, Y210, Y410" diff --git a/sys/d3d11/gstd3d11converter.cpp b/sys/d3d11/gstd3d11converter.cpp index 0206080..dd63411 100644 --- a/sys/d3d11/gstd3d11converter.cpp +++ b/sys/d3d11/gstd3d11converter.cpp @@ -115,6 +115,9 @@ static const gchar templ_alpha_const_buffer[] = static const PixelShaderTemplate templ_REORDER = { FALSE, TRUE, NULL }; +static const PixelShaderTemplate templ_REORDER_NO_ALPHA = + { FALSE, FALSE, NULL }; + static const PixelShaderTemplate templ_YUV_to_RGB = { TRUE, FALSE, HLSL_FUNC_YUV_TO_RGB }; @@ -288,6 +291,73 @@ static const gchar templ_PACKED_YUV_TO_SEMI_PLANAR_CHROMA_BODY[] = " sample.y = shaderTexture[0].Sample(samplerState, input.Texture).%c;\n" " output.Plane_0 = float4(sample.%c%c, 0.0, 0.0);\n"; +/* to GRAY */ +static const gchar templ_RGB_to_GRAY_BODY[] = + " float4 sample, rgba;\n" + " rgba.rgb = shaderTexture[0].Sample(samplerState, input.Texture).rgb;\n" + " sample.x = rgb_to_yuv (sample.rgb).x;\n" + " sample.y = 0.0;\n" + " sample.z = 0.0;\n" + " sample.a = 0.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_VUYA_to_GRAY_BODY[] = + " float4 sample;\n" + " sample.x = shaderTexture[0].Sample(samplerState, input.Texture).z;\n" + " sample.y = 0.0;\n" + " sample.z = 0.0;\n" + " sample.a = 0.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_YUV_to_GRAY_BODY[] = + " float4 sample;\n" + " sample.x = shaderTexture[0].Sample(samplerState, input.Texture).x * %u;\n" + " sample.y = 0.0;\n" + " sample.z = 0.0;\n" + " sample.a = 0.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_GRAY_to_GRAY_BODY[] = + " float4 sample;\n" + " sample.x = shaderTexture[0].Sample(samplerState, input.Texture).x;\n" + " sample.y = 0.0;\n" + " sample.z = 0.0;\n" + " sample.a = 0.0;\n" + " output.Plane_0 = sample;\n"; + +/* from GRAY */ +static const gchar templ_GRAY_to_RGB_BODY[] = + " float4 sample, rgba;\n" + " sample.x = shaderTexture[0].Sample(samplerState, input.Texture).x;\n" + " sample.y = sample.x;\n" + " sample.z = sample.x;\n" + " sample.a = 1.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_GRAY_to_VUYA_BODY[] = + " float4 sample;\n" + " sample.z = shaderTexture[0].Sample(samplerState, input.Texture).x;\n" + " sample.x = 0.5;\n" + " sample.y = 0.5;\n" + " sample.a = 1.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_GRAY_to_LUMA_BODY[] = + " float4 sample;\n" + " sample.x = shaderTexture[0].Sample(samplerState, input.Texture).x / %u;\n" + " sample.y = 0.0;\n" + " sample.z = 0.0;\n" + " sample.a = 0.0;\n" + " output.Plane_0 = sample;\n"; + +static const gchar templ_GRAY_to_PLANAR_CHROMA_BODY[] = + " float val = 0.5 / %u;\n" + " output.Plane_0 = float4(val, 0.0, 0.0, 0.0);\n" + " output.Plane_1 = float4(val, 0.0, 0.0, 0.0);\n"; + +static const gchar templ_GRAY_to_SEMI_PLANAR_CHROMA_BODY[] = + " output.Plane_0 = float4(0.5, 0.5, 0.0, 0.0);\n"; + static const gchar templ_pixel_shader[] = /* constant buffer */ "%s\n" @@ -696,10 +766,21 @@ static void get_planar_component (const GstVideoInfo * info, gchar * u, gchar * v, guint * scale) { - if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_I420_10LE) - *scale = 64; - else - *scale = 1; + switch (GST_VIDEO_INFO_FORMAT (info)) { + case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_Y444_10LE: + *scale = (1 << 6); + break; + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444_12LE: + *scale = (1 << 4); + break; + default: + *scale = 1; + break; + } if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_YV12) { *u = 'z'; @@ -754,6 +835,14 @@ setup_convert_info_yuv_to_rgb (GstD3D11Converter * self, case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: { guint mul; gchar u, v; @@ -767,6 +856,7 @@ setup_convert_info_yuv_to_rgb (GstD3D11Converter * self, case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: case GST_VIDEO_FORMAT_P016_LE: { gchar u, v; @@ -802,6 +892,7 @@ setup_convert_info_rgb_to_yuv (GstD3D11Converter * self, case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: case GST_VIDEO_FORMAT_P016_LE: { gchar u, v; @@ -817,6 +908,14 @@ setup_convert_info_rgb_to_yuv (GstD3D11Converter * self, case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: { guint div; gchar u, v; @@ -1106,6 +1205,14 @@ is_planar_format (const GstVideoInfo * info) case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: return TRUE; default: break; @@ -1172,6 +1279,180 @@ setup_convert_info_yuv_to_yuv (GstD3D11Converter * self, } static gboolean +setup_convert_info_rgb_to_gray (GstD3D11Converter * self, + const GstVideoInfo * in_info, const GstVideoInfo * out_info) +{ + ConvertInfo *info = &self->convert_info; + + info->templ = &templ_RGB_to_YUV; + info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + + switch (GST_VIDEO_INFO_FORMAT (out_info)) { + case GST_VIDEO_FORMAT_GRAY8: + case GST_VIDEO_FORMAT_GRAY16_LE: + info->ps_body[0] = g_strdup_printf (templ_RGB_to_GRAY_BODY); + break; + default: + GST_FIXME_OBJECT (self, + "Unhandled output format %s", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info))); + return FALSE; + } + + return TRUE; +} + +static gboolean +setup_convert_info_yuv_to_gray (GstD3D11Converter * self, + const GstVideoInfo * in_info, const GstVideoInfo * out_info) +{ + ConvertInfo *info = &self->convert_info; + + info->templ = &templ_REORDER_NO_ALPHA; + info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + + if (GST_VIDEO_INFO_FORMAT (out_info) != GST_VIDEO_FORMAT_GRAY8 && + GST_VIDEO_INFO_FORMAT (out_info) != GST_VIDEO_FORMAT_GRAY16_LE) + return FALSE; + + switch (GST_VIDEO_INFO_FORMAT (in_info)) { + case GST_VIDEO_FORMAT_VUYA: + info->ps_body[0] = g_strdup_printf (templ_VUYA_to_GRAY_BODY); + break; + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: + case GST_VIDEO_FORMAT_P016_LE: + { + gchar u, v; + guint scale; + + get_planar_component (in_info, &u, &v, &scale); + + info->ps_body[0] = g_strdup_printf (templ_YUV_to_GRAY_BODY, scale); + break; + } + default: + GST_FIXME_OBJECT (self, + "Unhandled input format %s", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (in_info))); + return FALSE; + } + + return TRUE; +} + +static gboolean +setup_convert_info_gray_to_gray (GstD3D11Converter * self, + const GstVideoInfo * in_info, const GstVideoInfo * out_info) +{ + ConvertInfo *info = &self->convert_info; + + info->templ = &templ_REORDER_NO_ALPHA; + info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + + if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY8 && + GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY16_LE) + return FALSE; + + if (GST_VIDEO_INFO_FORMAT (out_info) != GST_VIDEO_FORMAT_GRAY8 && + GST_VIDEO_INFO_FORMAT (out_info) != GST_VIDEO_FORMAT_GRAY16_LE) + return FALSE; + + info->ps_body[0] = g_strdup_printf (templ_GRAY_to_GRAY_BODY); + + return TRUE; +} + +static gboolean +setup_convert_info_gray_to_rgb (GstD3D11Converter * self, + const GstVideoInfo * in_info, const GstVideoInfo * out_info) +{ + ConvertInfo *info = &self->convert_info; + + info->templ = &templ_REORDER_NO_ALPHA; + info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + + if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY8 && + GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY16_LE) + return FALSE; + + info->ps_body[0] = g_strdup_printf (templ_GRAY_to_RGB_BODY); + + return TRUE; +} + +static gboolean +setup_convert_info_gray_to_yuv (GstD3D11Converter * self, + const GstVideoInfo * in_info, const GstVideoInfo * out_info) +{ + ConvertInfo *info = &self->convert_info; + + info->templ = &templ_REORDER_NO_ALPHA; + info->ps_output[0] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + + if (GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY8 && + GST_VIDEO_INFO_FORMAT (in_info) != GST_VIDEO_FORMAT_GRAY16_LE) + return FALSE; + + switch (GST_VIDEO_INFO_FORMAT (out_info)) { + case GST_VIDEO_FORMAT_VUYA: + info->ps_body[0] = g_strdup_printf (templ_GRAY_to_VUYA_BODY); + break; + case GST_VIDEO_FORMAT_I420: + case GST_VIDEO_FORMAT_YV12: + case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: + { + gchar u, v; + guint div; + + get_planar_component (out_info, &u, &v, &div); + info->ps_body[0] = g_strdup_printf (templ_GRAY_to_LUMA_BODY, div); + info->ps_body[1] = + g_strdup_printf (templ_GRAY_to_PLANAR_CHROMA_BODY, div); + info->ps_output[1] = HLSL_PS_OUTPUT_TWO_PLANES_BODY; + break; + } + case GST_VIDEO_FORMAT_NV12: + case GST_VIDEO_FORMAT_NV21: + case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: + case GST_VIDEO_FORMAT_P016_LE: + info->ps_body[0] = g_strdup_printf (templ_GRAY_to_LUMA_BODY, 1); + info->ps_body[1] = + g_strdup_printf (templ_GRAY_to_SEMI_PLANAR_CHROMA_BODY); + info->ps_output[1] = HLSL_PS_OUTPUT_ONE_PLANE_BODY; + default: + GST_FIXME_OBJECT (self, + "Unhandled output format %s", + gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (out_info))); + return FALSE; + } + + return TRUE; +} + +static gboolean gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self, GstD3D11Device * device, GstVideoInfo * in_info, GstVideoInfo * out_info) { @@ -1562,6 +1843,9 @@ gst_d3d11_converter_new (GstD3D11Device * device, } else if (GST_VIDEO_INFO_IS_YUV (out_info)) { is_supported = setup_convert_info_rgb_to_yuv (converter, in_info, out_info); + } else if (GST_VIDEO_INFO_IS_GRAY (out_info)) { + is_supported = + setup_convert_info_rgb_to_gray (converter, in_info, out_info); } } else if (GST_VIDEO_INFO_IS_YUV (in_info)) { if (GST_VIDEO_INFO_IS_RGB (out_info)) { @@ -1570,6 +1854,20 @@ gst_d3d11_converter_new (GstD3D11Device * device, } else if (GST_VIDEO_INFO_IS_YUV (out_info)) { is_supported = setup_convert_info_yuv_to_yuv (converter, in_info, out_info); + } else if (GST_VIDEO_INFO_IS_GRAY (out_info)) { + is_supported = + setup_convert_info_yuv_to_gray (converter, in_info, out_info); + } + } else if (GST_VIDEO_INFO_IS_GRAY (in_info)) { + if (GST_VIDEO_INFO_IS_RGB (out_info)) { + is_supported = + setup_convert_info_gray_to_rgb (converter, in_info, out_info); + } else if (GST_VIDEO_INFO_IS_YUV (out_info)) { + is_supported = + setup_convert_info_gray_to_yuv (converter, in_info, out_info); + } else if (GST_VIDEO_INFO_IS_GRAY (out_info)) { + is_supported = + setup_convert_info_gray_to_gray (converter, in_info, out_info); } } @@ -1873,10 +2171,12 @@ gst_d3d11_converter_update_viewport (GstD3D11Converter * converter, case GST_VIDEO_FORMAT_NV12: case GST_VIDEO_FORMAT_NV21: case GST_VIDEO_FORMAT_P010_10LE: + case GST_VIDEO_FORMAT_P012_LE: case GST_VIDEO_FORMAT_P016_LE: case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_I420_10LE: + case GST_VIDEO_FORMAT_I420_12LE: { guint i; converter->viewport[1].TopLeftX = converter->viewport[0].TopLeftX / 2; @@ -1889,6 +2189,31 @@ gst_d3d11_converter_update_viewport (GstD3D11Converter * converter, break; } + case GST_VIDEO_FORMAT_Y42B: + case GST_VIDEO_FORMAT_I422_10LE: + case GST_VIDEO_FORMAT_I422_12LE: + { + guint i; + converter->viewport[1].TopLeftX = converter->viewport[0].TopLeftX / 2; + converter->viewport[1].TopLeftY = converter->viewport[0].TopLeftY; + converter->viewport[1].Width = converter->viewport[0].Width / 2; + converter->viewport[1].Height = converter->viewport[0].Height; + + for (i = 2; i < GST_VIDEO_INFO_N_PLANES (&converter->out_info); i++) + converter->viewport[i] = converter->viewport[1]; + + break; + } + case GST_VIDEO_FORMAT_Y444: + case GST_VIDEO_FORMAT_Y444_10LE: + case GST_VIDEO_FORMAT_Y444_12LE: + case GST_VIDEO_FORMAT_Y444_16LE: + { + guint i; + for (i = 1; i < GST_VIDEO_INFO_N_PLANES (&converter->out_info); i++) + converter->viewport[i] = converter->viewport[1]; + break; + } default: if (converter->num_output_view > 1) g_assert_not_reached (); diff --git a/sys/d3d11/gstd3d11deinterlace.cpp b/sys/d3d11/gstd3d11deinterlace.cpp index 8d49cb0..64e04b4 100644 --- a/sys/d3d11/gstd3d11deinterlace.cpp +++ b/sys/d3d11/gstd3d11deinterlace.cpp @@ -2368,6 +2368,14 @@ gst_d3d11_deinterlace_register (GstPlugin * plugin, GstD3D11Device * device, g_value_init (supported_formats, GST_TYPE_LIST); } + if (formats_to_check[i] == DXGI_FORMAT_P016) { + /* This is used for P012 as well */ + g_value_init (&val, G_TYPE_STRING); + g_value_set_static_string (&val, + gst_video_format_to_string (GST_VIDEO_FORMAT_P012_LE)); + gst_value_list_append_and_take_value (supported_formats, &val); + } + g_value_init (&val, G_TYPE_STRING); g_value_set_static_string (&val, gst_video_format_to_string (format)); gst_value_list_append_and_take_value (supported_formats, &val); diff --git a/tests/check/elements/d3d11colorconvert.c b/tests/check/elements/d3d11colorconvert.c index 675a68e..44e9376 100644 --- a/tests/check/elements/d3d11colorconvert.c +++ b/tests/check/elements/d3d11colorconvert.c @@ -45,6 +45,24 @@ typedef struct _TestFrame static const guint8 rgba_reorder_data[] = { 0x49, 0x24, 0x72, 0xff }; static const guint8 bgra_reorder_data[] = { 0x72, 0x24, 0x49, 0xff }; +static const gchar *YUV_FORMATS[] = { + "VUYA", "NV12", "P010_10LE", "P012_LE", "P016_LE", "I420", "I420_10LE", + "I420_12LE", "YV12", "NV21", "Y444", "Y444_10LE", "Y444_12LE", "Y444_16LE", + "Y42B", "I422_10LE", "I422_12LE", +}; + +static const gchar *RGB_FORMATS[] = { + "BGRA", "RGBA", "RGB10A2_LE", "BGRx", "RGBx", +}; + +static const gchar *PACKED_YUV_FORMATS[] = { + "YUY2", "UYVY", "VYUY", "Y210", "Y410", +}; + +static const gchar *GRAY_FORMATS[] = { + "GRAY8", "GRAY16_LE" +}; + static TestFrame test_rgba_reorder[] = { {1, 1, GST_VIDEO_FORMAT_RGBA, {(guint8 *) & rgba_reorder_data}}, {1, 1, GST_VIDEO_FORMAT_BGRA, {(guint8 *) & bgra_reorder_data}}, @@ -102,7 +120,6 @@ GST_START_TEST (test_d3d11_color_convert_rgba_reorder) GST_END_TEST; -#if RUN_VISUAL_TEST static gboolean bus_cb (GstBus * bus, GstMessage * message, gpointer data) { @@ -162,19 +179,15 @@ run_convert_pipelne (const gchar * in_format, const gchar * out_format) GST_START_TEST (test_d3d11_color_convert_yuv_yuv) { - const gchar *format_list[] = { - "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE", "YV12", "NV21" - }; - gint i, j; - for (i = 0; i < G_N_ELEMENTS (format_list); i++) { - for (j = 0; j < G_N_ELEMENTS (format_list); j++) { + for (i = 0; i < G_N_ELEMENTS (YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (YUV_FORMATS); j++) { if (i == j) continue; - GST_DEBUG ("run conversion %s to %s", format_list[i], format_list[j]); - run_convert_pipelne (format_list[i], format_list[j]); + GST_DEBUG ("run conversion %s to %s", YUV_FORMATS[i], YUV_FORMATS[j]); + run_convert_pipelne (YUV_FORMATS[i], YUV_FORMATS[j]); } } } @@ -183,24 +196,32 @@ GST_END_TEST; GST_START_TEST (test_d3d11_color_convert_yuv_rgb) { - const gchar *in_format_list[] = { - "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE", "YV12", "NV21" - }; - const gchar *out_format_list[] = { - "BGRA", "RGBA", "RGB10A2_LE", "BGRx", "RGBx", - }; + gint i, j; + + for (i = 0; i < G_N_ELEMENTS (YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (RGB_FORMATS); j++) { + if (i == j) + continue; + + GST_DEBUG ("run conversion %s to %s", YUV_FORMATS[i], RGB_FORMATS[j]); + run_convert_pipelne (YUV_FORMATS[i], RGB_FORMATS[j]); + } + } +} +GST_END_TEST; +GST_START_TEST (test_d3d11_color_convert_yuv_gray) +{ 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++) { + for (i = 0; i < G_N_ELEMENTS (YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (GRAY_FORMATS); j++) { if (i == j) continue; - 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_DEBUG ("run conversion %s to %s", YUV_FORMATS[i], GRAY_FORMATS[j]); + run_convert_pipelne (YUV_FORMATS[i], GRAY_FORMATS[j]); } } } @@ -209,20 +230,12 @@ GST_END_TEST; GST_START_TEST (test_d3d11_color_convert_rgb_yuv) { - const gchar *in_format_list[] = { - "BGRA", "RGBA", "RGB10A2_LE", "BGRx", "RGBx", - }; - const gchar *out_format_list[] = { - "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE", "YV12", "NV21" - }; - 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]); + for (i = 0; i < G_N_ELEMENTS (RGB_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (YUV_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", RGB_FORMATS[i], YUV_FORMATS[j]); + run_convert_pipelne (RGB_FORMATS[i], YUV_FORMATS[j]); } } } @@ -231,41 +244,44 @@ GST_END_TEST; GST_START_TEST (test_d3d11_color_convert_rgb_rgb) { - const gchar *format_list[] = { - "BGRA", "RGBA", "RGB10A2_LE", "BGRx", "RGBx", - }; - gint i, j; - for (i = 0; i < G_N_ELEMENTS (format_list); i++) { - for (j = 0; j < G_N_ELEMENTS (format_list); j++) { + for (i = 0; i < G_N_ELEMENTS (RGB_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (RGB_FORMATS); j++) { if (i == j) continue; - GST_DEBUG ("run conversion %s to %s", format_list[i], format_list[j]); - run_convert_pipelne (format_list[i], format_list[j]); + GST_DEBUG ("run conversion %s to %s", RGB_FORMATS[i], RGB_FORMATS[j]); + run_convert_pipelne (RGB_FORMATS[i], RGB_FORMATS[j]); } } } GST_END_TEST; -GST_START_TEST (test_d3d11_color_convert_packed_yuv_yuv) +GST_START_TEST (test_d3d11_color_convert_rgb_gray) { - const gchar *in_format_list[] = { - "YUY2", "UYVY", "VYUY", "Y210", "Y410", - }; - const gchar *out_format_list[] = { - "VUYA", "NV12", "P010_10LE", "P016_LE", "I420", "I420_10LE", "YV12", "NV21" - }; + gint i, j; + for (i = 0; i < G_N_ELEMENTS (RGB_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (GRAY_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", RGB_FORMATS[i], GRAY_FORMATS[j]); + run_convert_pipelne (RGB_FORMATS[i], GRAY_FORMATS[j]); + } + } +} + +GST_END_TEST; + +GST_START_TEST (test_d3d11_color_convert_packed_yuv_yuv) +{ 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]); + for (i = 0; i < G_N_ELEMENTS (PACKED_YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (YUV_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", PACKED_YUV_FORMATS[i], + YUV_FORMATS[j]); + run_convert_pipelne (PACKED_YUV_FORMATS[i], YUV_FORMATS[j]); } } } @@ -274,43 +290,84 @@ GST_END_TEST; GST_START_TEST (test_d3d11_color_convert_packed_yuv_rgb) { - const gchar *in_format_list[] = { - "YUY2", "UYVY", "VYUY", "Y210", "Y410", - }; - const gchar *out_format_list[] = { - "BGRA", "RGBA", "RGB10A2_LE", "BGRx", "RGBx", - }; + gint i, j; + + for (i = 0; i < G_N_ELEMENTS (PACKED_YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (RGB_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", PACKED_YUV_FORMATS[i], + RGB_FORMATS[j]); + run_convert_pipelne (PACKED_YUV_FORMATS[i], RGB_FORMATS[j]); + } + } +} + +GST_END_TEST; +GST_START_TEST (test_d3d11_color_convert_packed_yuv_gray) +{ 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]); + for (i = 0; i < G_N_ELEMENTS (PACKED_YUV_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (GRAY_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", PACKED_YUV_FORMATS[i], + GRAY_FORMATS[j]); + run_convert_pipelne (PACKED_YUV_FORMATS[i], GRAY_FORMATS[j]); + } + } +} + +GST_END_TEST; + +GST_START_TEST (test_d3d11_color_convert_gray_yuv) +{ + gint i, j; + + for (i = 0; i < G_N_ELEMENTS (GRAY_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (YUV_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", GRAY_FORMATS[i], YUV_FORMATS[j]); + run_convert_pipelne (GRAY_FORMATS[i], YUV_FORMATS[j]); + } + } +} + +GST_END_TEST; + +GST_START_TEST (test_d3d11_color_convert_gray_rgb) +{ + gint i, j; + + for (i = 0; i < G_N_ELEMENTS (GRAY_FORMATS); i++) { + for (j = 0; j < G_N_ELEMENTS (RGB_FORMATS); j++) { + GST_DEBUG ("run conversion %s to %s", GRAY_FORMATS[i], RGB_FORMATS[j]); + run_convert_pipelne (GRAY_FORMATS[i], RGB_FORMATS[j]); } } } GST_END_TEST; -#endif /* RUN_VISUAL_TEST */ static Suite * d3d11colorconvert_suite (void) { Suite *s = suite_create ("d3d11colorconvert"); TCase *tc_basic = tcase_create ("general"); + const gchar *run_visual_test = g_getenv ("RUN_VISUAL_TEST"); suite_add_tcase (s, tc_basic); tcase_add_test (tc_basic, test_d3d11_color_convert_rgba_reorder); -#if RUN_VISUAL_TEST - tcase_add_test (tc_basic, test_d3d11_color_convert_yuv_yuv); - 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 + if (run_visual_test != NULL) { + tcase_add_test (tc_basic, test_d3d11_color_convert_yuv_yuv); + tcase_add_test (tc_basic, test_d3d11_color_convert_yuv_rgb); + tcase_add_test (tc_basic, test_d3d11_color_convert_yuv_gray); + 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_rgb_gray); + tcase_add_test (tc_basic, test_d3d11_color_convert_packed_yuv_yuv); + tcase_add_test (tc_basic, test_d3d11_color_convert_packed_yuv_rgb); + tcase_add_test (tc_basic, test_d3d11_color_convert_packed_yuv_gray); + tcase_add_test (tc_basic, test_d3d11_color_convert_gray_yuv); + tcase_add_test (tc_basic, test_d3d11_color_convert_gray_rgb); + } return s; } -- 2.7.4