[750/906] glupload: Add support for RGB reordering when using GLES2

This commit is contained in:
Sebastian Dröge 2013-07-15 14:11:20 +02:00 committed by Tim-Philipp Müller
parent 9d4f99b8bb
commit 15438d5b7f
3 changed files with 254 additions and 193 deletions

View file

@ -32,6 +32,7 @@ G_BEGIN_DECLS
//FIXME: //FIXME:
#define GL_RGBA8 GL_RGBA #define GL_RGBA8 GL_RGBA
#define GL_BGRA GL_RGBA #define GL_BGRA GL_RGBA
#define GL_BGR GL_RGB
#define GL_UNSIGNED_INT_8_8_8_8 GL_UNSIGNED_BYTE #define GL_UNSIGNED_INT_8_8_8_8 GL_UNSIGNED_BYTE
#define GL_UNSIGNED_INT_8_8_8_8_REV GL_UNSIGNED_BYTE #define GL_UNSIGNED_INT_8_8_8_8_REV GL_UNSIGNED_BYTE
//END FIXME //END FIXME
@ -40,7 +41,6 @@ G_BEGIN_DECLS
/* UNSUPPORTED */ /* UNSUPPORTED */
#define GL_BGR 0
#define GL_YCBCR_MESA 0 #define GL_YCBCR_MESA 0
#define GL_UNSIGNED_SHORT_8_8_MESA 0 #define GL_UNSIGNED_SHORT_8_8_MESA 0
#define GL_UNSIGNED_SHORT_8_8_MESA 0 #define GL_UNSIGNED_SHORT_8_8_MESA 0

View file

@ -196,6 +196,17 @@ static const gchar *text_shader_AYUV_gles2 =
" gl_FragColor=vec4(r,g,b,1.0);\n" " gl_FragColor=vec4(r,g,b,1.0);\n"
"}\n"; "}\n";
static const gchar *text_shader_ARGB_gles2 =
"precision mediump float;\n"
"varying vec2 v_texCoord;\n"
"uniform sampler2D tex;\n"
"void main(void) {\n"
" vec4 rgba;\n"
" vec2 nxy = v_texCoord.xy;\n"
" rgba=texture2D(tex,nxy);\n"
" gl_FragColor=vec4(rgba.%c,rgba.%c,rgba.%c,1.0);\n"
"}\n";
static const gchar *text_vertex_shader_gles2 = static const gchar *text_vertex_shader_gles2 =
"attribute vec4 a_position; \n" "attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n" "attribute vec2 a_texCoord; \n"
@ -214,6 +225,7 @@ struct _GstGLUploadPrivate
const gchar *YUY2_UYVY; const gchar *YUY2_UYVY;
const gchar *I420_YV12; const gchar *I420_YV12;
const gchar *AYUV; const gchar *AYUV;
const gchar *ARGB;
const gchar *vert_shader; const gchar *vert_shader;
void (*draw) (GstGLDisplay * display, GstGLUpload * download); void (*draw) (GstGLDisplay * display, GstGLUpload * download);
@ -283,6 +295,7 @@ gst_gl_upload_new (GstGLDisplay * display)
priv->YUY2_UYVY = text_shader_YUY2_UYVY_opengl; priv->YUY2_UYVY = text_shader_YUY2_UYVY_opengl;
priv->I420_YV12 = text_shader_I420_YV12_opengl; priv->I420_YV12 = text_shader_I420_YV12_opengl;
priv->AYUV = text_shader_AYUV_opengl; priv->AYUV = text_shader_AYUV_opengl;
priv->ARGB = NULL;
priv->vert_shader = text_vertex_shader_opengl; priv->vert_shader = text_vertex_shader_opengl;
priv->draw = _do_upload_draw_opengl; priv->draw = _do_upload_draw_opengl;
} }
@ -292,6 +305,7 @@ gst_gl_upload_new (GstGLDisplay * display)
priv->YUY2_UYVY = text_shader_YUY2_UYVY_gles2; priv->YUY2_UYVY = text_shader_YUY2_UYVY_gles2;
priv->I420_YV12 = text_shader_I420_YV12_gles2; priv->I420_YV12 = text_shader_I420_YV12_gles2;
priv->AYUV = text_shader_AYUV_gles2; priv->AYUV = text_shader_AYUV_gles2;
priv->ARGB = text_shader_ARGB_gles2;
priv->vert_shader = text_vertex_shader_gles2; priv->vert_shader = text_vertex_shader_gles2;
priv->draw = _do_upload_draw_gles2; priv->draw = _do_upload_draw_gles2;
} }
@ -668,6 +682,7 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
GST_INFO ("Initializing texture upload for format:%s", GST_INFO ("Initializing texture upload for format:%s",
gst_video_format_to_string (v_format)); gst_video_format_to_string (v_format));
if (GST_VIDEO_FORMAT_INFO_IS_RGB (upload->info.finfo)) {
switch (v_format) { switch (v_format) {
case GST_VIDEO_FORMAT_RGBx: case GST_VIDEO_FORMAT_RGBx:
case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_BGRx:
@ -679,17 +694,23 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
/* GLES has no support for anything else than RGB(XA) */
if (!USING_GLES2 (display) || (v_format == GST_VIDEO_FORMAT_RGBA
|| v_format == GST_VIDEO_FORMAT_RGBx
|| v_format == GST_VIDEO_FORMAT_RGB)) {
if (in_width != out_width || in_height != out_height) if (in_width != out_width || in_height != out_height)
_init_upload_fbo (display, upload); _init_upload_fbo (display, upload);
/* color space conversion is not needed */ /* color space conversion is not needed */
return;
}
break; break;
case GST_VIDEO_FORMAT_YUY2: default:
case GST_VIDEO_FORMAT_UYVY: break;
case GST_VIDEO_FORMAT_I420: }
case GST_VIDEO_FORMAT_YV12: }
case GST_VIDEO_FORMAT_AYUV:
/* color space conversion is needed */ /* color space conversion is needed */
{
/* check if fragment shader is available, then load them */ /* check if fragment shader is available, then load them */
/* shouldn't we require ARB_shading_language_100? --Filippo */ /* shouldn't we require ARB_shading_language_100? --Filippo */
if (gl->CreateProgramObject || gl->CreateProgram) { if (gl->CreateProgramObject || gl->CreateProgram) {
@ -722,14 +743,12 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
gchar text_shader_UYVY[2048]; gchar text_shader_UYVY[2048];
#if GST_GL_HAVE_OPENGL #if GST_GL_HAVE_OPENGL
if (USING_OPENGL (display)) { if (USING_OPENGL (display)) {
sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, 'a', 'b', 'r');
'a', 'b', 'r');
} }
#endif #endif
#if GST_GL_HAVE_GLES2 #if GST_GL_HAVE_GLES2
if (USING_GLES2 (display)) { if (USING_GLES2 (display)) {
sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, sprintf (text_shader_UYVY, upload->priv->YUY2_UYVY, 'a', 'r', 'b');
'a', 'r', 'b');
} }
#endif #endif
@ -798,6 +817,48 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
} }
} }
break; break;
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_BGRA:
case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_BGR:
{
gchar text_shader_ARGB[2048];
switch (v_format) {
case GST_VIDEO_FORMAT_BGR:
case GST_VIDEO_FORMAT_BGRx:
case GST_VIDEO_FORMAT_BGRA:
sprintf (text_shader_ARGB, upload->priv->ARGB, 'b', 'g', 'r');
break;
case GST_VIDEO_FORMAT_xRGB:
case GST_VIDEO_FORMAT_ARGB:
sprintf (text_shader_ARGB, upload->priv->ARGB, 'g', 'b', 'a');
break;
case GST_VIDEO_FORMAT_xBGR:
case GST_VIDEO_FORMAT_ABGR:
sprintf (text_shader_ARGB, upload->priv->ARGB, 'a', 'b', 'g');
break;
default:
g_assert_not_reached ();
break;
}
if (_create_shader (display, upload->priv->vert_shader,
text_shader_ARGB, &upload->shader)) {
if (USING_GLES2 (display)) {
upload->shader_attr_position_loc =
gst_gl_shader_get_attribute_location
(upload->shader, "a_position");
upload->shader_attr_texture_loc =
gst_gl_shader_get_attribute_location
(upload->shader, "a_texCoord");
}
}
}
break;
default: default:
gst_gl_display_set_error (display, gst_gl_display_set_error (display,
"Unsupported upload video format %s", "Unsupported upload video format %s",
@ -851,13 +912,6 @@ _init_upload (GstGLDisplay * display, GstGLUpload * upload)
"Cannot upload YUV formats without OpenGL shaders"); "Cannot upload YUV formats without OpenGL shaders");
} }
} }
break;
default:
gst_gl_display_set_error (display, "Unsupported upload video format %d",
v_format);
break;
}
}
/* called by _init_upload (in the gl thread) */ /* called by _init_upload (in the gl thread) */
@ -969,7 +1023,7 @@ _do_upload (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
if (in_width != out_width || in_height != out_height) if (in_width != out_width || in_height != out_height || upload->shader)
upload->priv->draw (display, upload); upload->priv->draw (display, upload);
/* color space conversion is not needed */ /* color space conversion is not needed */
break; break;
@ -1164,7 +1218,7 @@ _do_upload_fill (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_ARGB:
case GST_VIDEO_FORMAT_ABGR: case GST_VIDEO_FORMAT_ABGR:
/* color space conversion is not needed */ /* color space conversion is not needed */
if (in_width != out_width || in_height != out_height) if (in_width != out_width || in_height != out_height || upload->shader)
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]);
else else
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture); gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->out_texture);
@ -1405,6 +1459,8 @@ _do_upload_draw_opengl (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
{ {
g_assert (upload->shader == NULL);
gl->MatrixMode (GL_PROJECTION); gl->MatrixMode (GL_PROJECTION);
gl->LoadIdentity (); gl->LoadIdentity ();
@ -1652,6 +1708,10 @@ _do_upload_draw_gles2 (GstGLDisplay * display, GstGLUpload * upload)
case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_RGB:
case GST_VIDEO_FORMAT_BGR: case GST_VIDEO_FORMAT_BGR:
{ {
if (upload->shader) {
gst_gl_shader_use (upload->shader);
}
gl->VertexAttribPointer (upload->shader_attr_position_loc, 3, gl->VertexAttribPointer (upload->shader_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices); GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
gl->VertexAttribPointer (upload->shader_attr_texture_loc, 2, gl->VertexAttribPointer (upload->shader_attr_texture_loc, 2,
@ -1660,6 +1720,11 @@ _do_upload_draw_gles2 (GstGLDisplay * display, GstGLUpload * upload)
gl->EnableVertexAttribArray (upload->shader_attr_position_loc); gl->EnableVertexAttribArray (upload->shader_attr_position_loc);
gl->EnableVertexAttribArray (upload->shader_attr_texture_loc); gl->EnableVertexAttribArray (upload->shader_attr_texture_loc);
if (upload->shader) {
gl->ActiveTexture (GL_TEXTURE0);
gst_gl_shader_set_uniform_1i (upload->shader, "tex", 0);
}
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]); gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, upload->in_texture[0]);
gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, gl->TexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,
GL_LINEAR); GL_LINEAR);

View file

@ -92,12 +92,8 @@ struct _GstGLUploadClass
* *
* The currently supported formats that can be uploaded * The currently supported formats that can be uploaded
*/ */
#if !GST_GL_HAVE_GLES2
#define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, BGR, BGRx, BGRA, xRGB, " \ #define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, BGR, BGRx, BGRA, xRGB, " \
"xBGR, ARGB, ABGR, I420, YV12, YUY2, UYVY, AYUV }" "xBGR, ARGB, ABGR, I420, YV12, YUY2, UYVY, AYUV }"
#else /* GST_GL_HAVE_GLES2 */
# define GST_GL_UPLOAD_FORMATS "{ RGB, RGBx, RGBA, I420, YV12, YUY2, UYVY, AYUV }"
#endif /* !GST_GL_HAVE_GLES2 */
/** /**
* GST_GL_UPLOAD_VIDEO_CAPS: * GST_GL_UPLOAD_VIDEO_CAPS: