libgstgl: run a custom shader to convert YUV to RGB on mac and ios

When GL_APPLE_ycbcr_422 is available, run a custom shader to convert
GL_TEXTURE_RECTANGLE textures from YUV to RGB.

See https://www.opengl.org/registry/specs/APPLE/ycbcr_422.txt
This commit is contained in:
Alessandro Decina 2015-01-28 00:48:27 +11:00
parent 8734abb1ce
commit 3655e8b8bc

View file

@ -136,6 +136,23 @@ static const gchar frag_REORDER[] =
" gl_FragColor = vec4(t.%c, t.%c, t.%c, t.%c);\n" " gl_FragColor = vec4(t.%c, t.%c, t.%c, t.%c);\n"
"}"; "}";
static const gchar frag_APPLE_YUV_TO_RGB[] =
"#ifdef GL_ES\n"
"precision mediump float;\n"
"#endif\n"
"varying vec2 v_texcoord;\n"
"uniform float width;\n"
"uniform float height;\n"
"uniform sampler2DRect tex;\n"
"uniform vec2 tex_scale0;\n"
"uniform vec2 tex_scale1;\n"
"uniform vec2 tex_scale2;\n"
"void main(void)\n"
"{\n"
" vec4 t = texture2DRect(tex, v_texcoord * vec2(width, height) * tex_scale0);\n"
" gl_FragColor = vec4(t.%c, t.%c, t.%c, t.%c);\n"
"}";
/* GRAY16 to RGB conversion /* GRAY16 to RGB conversion
* data transfered as GL_LUMINANCE_ALPHA then convert back to GRAY16 * data transfered as GL_LUMINANCE_ALPHA then convert back to GRAY16
* high byte weight as : 255*256/65535 * high byte weight as : 255*256/65535
@ -816,9 +833,26 @@ _YUV_to_RGB (GstGLColorConvert * convert)
gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg") gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
|| gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg"); || gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
#endif #endif
gboolean apple_ycbcr = gst_gl_context_check_feature (convert->context,
"GL_APPLE_ycbcr_422");
gboolean in_tex_rectangular = FALSE;
GstMemory *memory = gst_buffer_peek_memory (convert->inbuf, 0);
if (gst_is_gl_memory (memory)) {
in_tex_rectangular =
((GstGLMemory *) memory)->tex_target == GL_TEXTURE_RECTANGLE;
}
info->out_n_textures = 1; info->out_n_textures = 1;
if (in_tex_rectangular && apple_ycbcr
&& gst_buffer_n_memory (convert->inbuf) == 1) {
info->frag_prog =
g_strdup_printf (frag_APPLE_YUV_TO_RGB, pixel_order[0], pixel_order[1],
pixel_order[2], pixel_order[3]);
info->in_n_textures = 1;
info->shader_tex_names[0] = "tex";
} else {
switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) { switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) {
case GST_VIDEO_FORMAT_AYUV: case GST_VIDEO_FORMAT_AYUV:
info->frag_prog = g_strdup_printf (frag_AYUV_to_RGB, pixel_order[0], info->frag_prog = g_strdup_printf (frag_AYUV_to_RGB, pixel_order[0],
@ -830,7 +864,8 @@ _YUV_to_RGB (GstGLColorConvert * convert)
case GST_VIDEO_FORMAT_Y444: case GST_VIDEO_FORMAT_Y444:
case GST_VIDEO_FORMAT_Y42B: case GST_VIDEO_FORMAT_Y42B:
case GST_VIDEO_FORMAT_Y41B: case GST_VIDEO_FORMAT_Y41B:
info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0], info->frag_prog =
g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
pixel_order[1], pixel_order[2], pixel_order[3]); pixel_order[1], pixel_order[2], pixel_order[3]);
info->in_n_textures = 3; info->in_n_textures = 3;
info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[0] = "Ytex";
@ -838,7 +873,8 @@ _YUV_to_RGB (GstGLColorConvert * convert)
info->shader_tex_names[2] = "Vtex"; info->shader_tex_names[2] = "Vtex";
break; break;
case GST_VIDEO_FORMAT_YV12: case GST_VIDEO_FORMAT_YV12:
info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0], info->frag_prog =
g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
pixel_order[1], pixel_order[2], pixel_order[3]); pixel_order[1], pixel_order[2], pixel_order[3]);
info->in_n_textures = 3; info->in_n_textures = 3;
info->shader_tex_names[0] = "Ytex"; info->shader_tex_names[0] = "Ytex";
@ -888,6 +924,7 @@ _YUV_to_RGB (GstGLColorConvert * convert)
default: default:
break; break;
} }
}
if (gst_video_colorimetry_matches (&convert->in_info.colorimetry, if (gst_video_colorimetry_matches (&convert->in_info.colorimetry,
GST_VIDEO_COLORIMETRY_BT709)) { GST_VIDEO_COLORIMETRY_BT709)) {