" 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
* data transfered as GL_LUMINANCE_ALPHA then convert back to GRAY16
* high byte weight as : 255*256/65535
gst_gl_context_check_feature (convert->context, "GL_EXT_texture_rg")
|| gst_gl_context_check_feature (convert->context, "GL_ARB_texture_rg");
#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;
- switch (GST_VIDEO_INFO_FORMAT (&convert->in_info)) {
- case GST_VIDEO_FORMAT_AYUV:
- info->frag_prog = g_strdup_printf (frag_AYUV_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";
- break;
- case GST_VIDEO_FORMAT_I420:
- case GST_VIDEO_FORMAT_Y444:
- case GST_VIDEO_FORMAT_Y42B:
- case GST_VIDEO_FORMAT_Y41B:
- info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
- pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 3;
- info->shader_tex_names[0] = "Ytex";
- info->shader_tex_names[1] = "Utex";
- info->shader_tex_names[2] = "Vtex";
- break;
- case GST_VIDEO_FORMAT_YV12:
- info->frag_prog = g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
- pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 3;
- info->shader_tex_names[0] = "Ytex";
- info->shader_tex_names[1] = "Vtex";
- info->shader_tex_names[2] = "Utex";
- break;
- case GST_VIDEO_FORMAT_YUY2:
- {
- char uv_val = texture_rg ? 'g' : 'a';
- info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, 'r', uv_val,
- uv_val, 'g', 'a', pixel_order[0], pixel_order[1], pixel_order[2],
- pixel_order[3]);
- info->in_n_textures = 1;
- info->shader_tex_names[0] = "Ytex";
- break;
- }
- case GST_VIDEO_FORMAT_NV12:
- {
- char val2 = texture_rg ? 'g' : 'a';
- info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'r', val2,
- pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 2;
- info->shader_tex_names[0] = "Ytex";
- info->shader_tex_names[1] = "UVtex";
- break;
- }
- case GST_VIDEO_FORMAT_NV21:
- {
- char val2 = texture_rg ? 'g' : 'a';
- info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, val2, 'r',
- pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
- info->in_n_textures = 2;
- info->shader_tex_names[0] = "Ytex";
- info->shader_tex_names[1] = "UVtex";
- break;
- }
- case GST_VIDEO_FORMAT_UYVY:
- {
- char y_val = texture_rg ? 'g' : 'a';
- info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, y_val, 'g',
- 'g', 'r', 'b', pixel_order[0], pixel_order[1], pixel_order[2],
- pixel_order[3]);
- info->in_n_textures = 1;
- info->shader_tex_names[0] = "Ytex";
- break;
+ 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)) {
+ case GST_VIDEO_FORMAT_AYUV:
+ info->frag_prog = g_strdup_printf (frag_AYUV_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";
+ break;
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_Y444:
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_Y41B:
+ info->frag_prog =
+ g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
+ pixel_order[1], pixel_order[2], pixel_order[3]);
+ info->in_n_textures = 3;
+ info->shader_tex_names[0] = "Ytex";
+ info->shader_tex_names[1] = "Utex";
+ info->shader_tex_names[2] = "Vtex";
+ break;
+ case GST_VIDEO_FORMAT_YV12:
+ info->frag_prog =
+ g_strdup_printf (frag_PLANAR_YUV_to_RGB, pixel_order[0],
+ pixel_order[1], pixel_order[2], pixel_order[3]);
+ info->in_n_textures = 3;
+ info->shader_tex_names[0] = "Ytex";
+ info->shader_tex_names[1] = "Vtex";
+ info->shader_tex_names[2] = "Utex";
+ break;
+ case GST_VIDEO_FORMAT_YUY2:
+ {
+ char uv_val = texture_rg ? 'g' : 'a';
+ info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, 'r', uv_val,
+ uv_val, 'g', 'a', pixel_order[0], pixel_order[1], pixel_order[2],
+ pixel_order[3]);
+ info->in_n_textures = 1;
+ info->shader_tex_names[0] = "Ytex";
+ break;
+ }
+ case GST_VIDEO_FORMAT_NV12:
+ {
+ char val2 = texture_rg ? 'g' : 'a';
+ info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, 'r', val2,
+ pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
+ info->in_n_textures = 2;
+ info->shader_tex_names[0] = "Ytex";
+ info->shader_tex_names[1] = "UVtex";
+ break;
+ }
+ case GST_VIDEO_FORMAT_NV21:
+ {
+ char val2 = texture_rg ? 'g' : 'a';
+ info->frag_prog = g_strdup_printf (frag_NV12_NV21_to_RGB, val2, 'r',
+ pixel_order[0], pixel_order[1], pixel_order[2], pixel_order[3]);
+ info->in_n_textures = 2;
+ info->shader_tex_names[0] = "Ytex";
+ info->shader_tex_names[1] = "UVtex";
+ break;
+ }
+ case GST_VIDEO_FORMAT_UYVY:
+ {
+ char y_val = texture_rg ? 'g' : 'a';
+ info->frag_prog = g_strdup_printf (frag_YUY2_UYVY_to_RGB, y_val, 'g',
+ 'g', 'r', 'b', pixel_order[0], pixel_order[1], pixel_order[2],
+ pixel_order[3]);
+ info->in_n_textures = 1;
+ info->shader_tex_names[0] = "Ytex";
+ break;
+ }
+ default:
+ break;
}
- default:
- break;
}
if (gst_video_colorimetry_matches (&convert->in_info.colorimetry,