mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-29 19:50:40 +00:00
glcolorconvert: add support for v210->UYVY/YUY2 (and reverse)
Also support YUY2/UYVY->YUY2/UYVY conversion Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6795>
This commit is contained in:
parent
f6d3aca076
commit
4c27a2d5eb
1 changed files with 100 additions and 53 deletions
|
@ -569,7 +569,7 @@ static const gchar glsl_func_YUY2_UYVY_pack[] =
|
|||
" vec4 yuva, yuv1, yuv2;\n"
|
||||
" float fx, dx, fy;\n"
|
||||
/* v_texcoord are normalized, texcoord may not be e.g. rectangle textures */
|
||||
" float inorder = mod (v_texcoord.x * width, 2.0);\n"
|
||||
" float inorder = mod (v_texcoord.x * out_width, 2.0);\n"
|
||||
" fx = texcoord.x;\n"
|
||||
" dx = poffset_x;\n"
|
||||
" if (inorder > 1.0) {\n"
|
||||
|
@ -599,7 +599,7 @@ static const gchar templ_RGB_to_YUY2_UYVY_BODY[] =
|
|||
|
||||
static const struct shader_templ templ_RGB_to_YUY2_UYVY =
|
||||
{ NULL,
|
||||
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D tex;\n",
|
||||
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D tex;\n" "uniform float out_width;\n",
|
||||
{ glsl_func_swizzle, glsl_func_color_matrix, glsl_func_YUY2_UYVY_pack, NULL, },
|
||||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
@ -616,7 +616,7 @@ static const gchar templ_PLANAR_YUV_to_YUY2_UYVY_BODY[] =
|
|||
|
||||
static const struct shader_templ templ_PLANAR_YUV_to_YUY2_UYVY =
|
||||
{ NULL,
|
||||
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D Ytex;\n" "uniform sampler2D Utex;\n" "uniform sampler2D Vtex;\n" "uniform float in_bitdepth_factor;\n",
|
||||
DEFAULT_UNIFORMS RGB_TO_YUV_COEFFICIENTS "uniform sampler2D Ytex;\n" "uniform sampler2D Utex;\n" "uniform sampler2D Vtex;\n" "uniform float in_bitdepth_factor;\n" "uniform float out_width;\n",
|
||||
{ glsl_func_swizzle, glsl_func_color_matrix, glsl_func_YUY2_UYVY_pack, glsl_func_fetch_planar_yuv, NULL, },
|
||||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
@ -759,6 +759,47 @@ static const struct shader_templ templ_RGB_to_v210 =
|
|||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
||||
static const gchar templ_YUY2_UYVY_to_v210_BODY[] =
|
||||
"vec2 texcoord0, texcoord1, texcoord2;\n"
|
||||
"ivec3 idx = v210_pack(v_texcoord, texcoord0, texcoord1, texcoord2);\n"
|
||||
"vec4 yuva0 = yuy2_uyvy_unpack(tex, texcoord0, texcoord0, vec2(1.0));\n"
|
||||
"vec4 yuva1 = yuy2_uyvy_unpack(tex, texcoord1, texcoord1, vec2(1.0));\n"
|
||||
"vec4 yuva2 = yuy2_uyvy_unpack(tex, texcoord2, texcoord2, vec2(1.0));\n"
|
||||
"gl_FragColor = vec4(yuva0[idx[0]], yuva1[idx[1]], yuva2[idx[2]], 1.0);\n";
|
||||
|
||||
static const struct shader_templ templ_YUY2_UYVY_to_v210 =
|
||||
{ NULL,
|
||||
DEFAULT_UNIFORMS YUV_TO_RGB_COEFFICIENTS "uniform sampler2D tex;\n" "uniform float out_width;\n",
|
||||
{ glsl_func_swizzle, glsl_func_color_matrix, glsl_func_YUY2_UYVY_unpack, glsl_func_v210_pack, NULL, },
|
||||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
||||
static const gchar templ_v210_to_YUY2_UYVY_BODY[] =
|
||||
"vec4 yuva = v210_unpack(tex, v_texcoord, vec2(1.0));\n"
|
||||
"vec2 texcoord0, texcoord1;\n"
|
||||
"ivec2 idx = YUY2_UYVY_pack(texcoord, v_texcoord, texcoord0, texcoord1);\n"
|
||||
"gl_FragColor = vec4(yuva[idx[0]], yuva[idx[1]], 0.0, 0.0);\n";
|
||||
|
||||
static const struct shader_templ templ_v210_to_YUY2_UYVY =
|
||||
{ NULL,
|
||||
DEFAULT_UNIFORMS YUV_TO_RGB_COEFFICIENTS "uniform sampler2D tex;\n" "uniform float out_width;\n",
|
||||
{ glsl_func_swizzle, glsl_func_color_matrix, glsl_func_v210_unpack, glsl_func_YUY2_UYVY_pack, NULL, },
|
||||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
||||
static const gchar templ_YUY2_UYVY_to_YUY2_UYVY_BODY[] =
|
||||
"vec4 yuva = yuy2_uyvy_unpack(tex, texcoord, v_texcoord, vec2(1.0));\n"
|
||||
"vec2 texcoord0, texcoord1;\n"
|
||||
"ivec2 idx = YUY2_UYVY_pack(texcoord, v_texcoord, texcoord0, texcoord1);\n"
|
||||
"gl_FragColor = vec4(yuva[idx[0]], yuva[idx[1]], 0.0, 0.0);\n";
|
||||
|
||||
static const struct shader_templ templ_YUY2_UYVY_to_YUY2_UYVY =
|
||||
{ NULL,
|
||||
DEFAULT_UNIFORMS YUV_TO_RGB_COEFFICIENTS "uniform sampler2D tex;\n" "uniform float out_width;\n",
|
||||
{ glsl_func_swizzle, glsl_func_color_matrix, glsl_func_YUY2_UYVY_unpack, glsl_func_YUY2_UYVY_pack, NULL, },
|
||||
GST_GL_TEXTURE_TARGET_2D
|
||||
};
|
||||
|
||||
/* PLANAR RGB to PACKED RGB conversion */
|
||||
static const gchar templ_PLANAR_RGB_to_PACKED_RGB_BODY[] =
|
||||
"vec4 rgba;\n"
|
||||
|
@ -1308,48 +1349,37 @@ _gst_gl_color_convert_can_passthrough_info (const GstVideoInfo * in,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supports_yuv_yuv_conversion (const GstVideoFormatInfo * from)
|
||||
{
|
||||
if (GST_VIDEO_FORMAT_INFO_IS_YUV (from)
|
||||
&& GST_VIDEO_FORMAT_INFO_N_PLANES (from) ==
|
||||
GST_VIDEO_FORMAT_INFO_N_COMPONENTS (from))
|
||||
return TRUE;
|
||||
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_v210)
|
||||
return TRUE;
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_UYVY)
|
||||
return TRUE;
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_YUY2)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
conversion_formats_are_supported (const GstVideoFormatInfo * in_finfo,
|
||||
const GstVideoFormatInfo * out_finfo)
|
||||
{
|
||||
gboolean input_yuv_planar = GST_VIDEO_FORMAT_INFO_IS_YUV (in_finfo)
|
||||
&& GST_VIDEO_FORMAT_INFO_N_PLANES (in_finfo) ==
|
||||
GST_VIDEO_FORMAT_INFO_N_COMPONENTS (in_finfo);
|
||||
gboolean output_yuv_planar = GST_VIDEO_FORMAT_INFO_IS_YUV (out_finfo)
|
||||
&& GST_VIDEO_FORMAT_INFO_N_PLANES (out_finfo) ==
|
||||
GST_VIDEO_FORMAT_INFO_N_COMPONENTS (out_finfo);
|
||||
|
||||
/* GRAY/YUV -> GRAY/YUV is not supported for non-passthrough */
|
||||
if (GST_VIDEO_FORMAT_INFO_IS_RGB (in_finfo))
|
||||
return TRUE;
|
||||
if (GST_VIDEO_FORMAT_INFO_IS_RGB (out_finfo))
|
||||
return TRUE;
|
||||
|
||||
if (input_yuv_planar && output_yuv_planar)
|
||||
if (supports_yuv_yuv_conversion (in_finfo)
|
||||
&& supports_yuv_yuv_conversion (out_finfo))
|
||||
return TRUE;
|
||||
|
||||
if (input_yuv_planar) {
|
||||
switch GST_VIDEO_FORMAT_INFO_FORMAT (out_finfo) {
|
||||
case GST_VIDEO_FORMAT_v210:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (output_yuv_planar) {
|
||||
switch GST_VIDEO_FORMAT_INFO_FORMAT (in_finfo) {
|
||||
case GST_VIDEO_FORMAT_v210:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1696,24 +1726,6 @@ _init_supported_formats (GstGLContext * context, gboolean output,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
supports_yuv_yuv_conversion (const GstVideoFormatInfo *from)
|
||||
{
|
||||
if (GST_VIDEO_FORMAT_INFO_IS_YUV (from)
|
||||
&& GST_VIDEO_FORMAT_INFO_N_PLANES (from) ==
|
||||
GST_VIDEO_FORMAT_INFO_N_COMPONENTS (from))
|
||||
return TRUE;
|
||||
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_v210)
|
||||
return TRUE;
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_UYVY)
|
||||
return TRUE;
|
||||
if (GST_VIDEO_FORMAT_INFO_FORMAT (from) == GST_VIDEO_FORMAT_YUY2)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copies the given caps */
|
||||
static GstCaps *
|
||||
gst_gl_color_convert_caps_transform_format_info (GstGLContext * context,
|
||||
|
@ -2859,7 +2871,42 @@ _YUV_to_YUV (GstGLColorConvert * convert)
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
g_assert_not_reached ();
|
||||
switch (in_format) {
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
info->shader_tex_names[0] = "tex";
|
||||
switch (out_format) {
|
||||
case GST_VIDEO_FORMAT_v210:
|
||||
info->templ = &templ_YUY2_UYVY_to_v210;
|
||||
info->frag_body = g_strdup (templ_YUY2_UYVY_to_v210_BODY);
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
info->templ = &templ_YUY2_UYVY_to_YUY2_UYVY;
|
||||
info->frag_body = g_strdup (templ_YUY2_UYVY_to_YUY2_UYVY_BODY);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GST_VIDEO_FORMAT_v210:
|
||||
info->shader_tex_names[0] = "tex";
|
||||
switch (out_format) {
|
||||
case GST_VIDEO_FORMAT_YUY2:
|
||||
case GST_VIDEO_FORMAT_UYVY:
|
||||
info->templ = &templ_v210_to_YUY2_UYVY;
|
||||
info->frag_body = g_strdup (templ_v210_to_YUY2_UYVY_BODY);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue