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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2346>
This commit is contained in:
Seungha Yang 2021-06-21 17:13:33 +09:00 committed by GStreamer Marge Bot
parent 52a0c36598
commit 7c94b9c4b0
5 changed files with 548 additions and 81 deletions

View file

@ -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);
}

View file

@ -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"

View file

@ -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;
@ -1171,6 +1278,180 @@ setup_convert_info_yuv_to_yuv (GstD3D11Converter * self,
return FALSE;
}
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 ();

View file

@ -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);

View file

@ -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 (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 (RGB_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], 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 (YUV_FORMATS); i++) {
for (j = 0; j < G_N_ELEMENTS (GRAY_FORMATS); j++) {
if (i == j)
continue;
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,19 +244,29 @@ 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_rgb_gray)
{
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]);
}
}
}
@ -252,20 +275,13 @@ GST_END_TEST;
GST_START_TEST (test_d3d11_color_convert_packed_yuv_yuv)
{
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 (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 (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 (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 (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;
}