summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2013-07-21 11:43:24 +0200
committerSebastian Dröge <slomo@circular-chaos.org>2013-07-24 13:36:34 +0200
commitc3a92871076aeb73f24f8b0c5b8fbcea9436b254 (patch)
treef456b5c12d8d2af7a232588adc7b996acd911d8e
parentd8f38905091b6f9d70ff01dbc5c898f93407c961 (diff)
gldownload: Add support for downloading multi-planar formats to GLES2download-planar
https://bugzilla.gnome.org/show_bug.cgi?id=704222
-rw-r--r--gst-libs/gst/gl/gstgldownload.c97
-rw-r--r--gst-libs/gst/gl/gstgles2.h4
2 files changed, 88 insertions, 13 deletions
diff --git a/gst-libs/gst/gl/gstgldownload.c b/gst-libs/gst/gl/gstgldownload.c
index 7439282..3681393 100644
--- a/gst-libs/gst/gl/gstgldownload.c
+++ b/gst-libs/gst/gl/gstgldownload.c
@@ -163,10 +163,29 @@ static const gchar *text_shader_YUY2_UYVY_gles2 =
" gl_FragColor=vec4(%s);\n"
"}\n";
-/* no OpenGL ES 2.0 support because for now it's not possible
- * to attach multiple textures to a frame buffer object
- */
-#define text_shader_I420_YV12_gles2 NULL
+static const gchar *text_shader_I420_YV12_gles2 =
+ "precision mediump float;\n"
+ "varying vec2 v_texCoord;\n"
+ "uniform sampler2D tex;\n"
+ "uniform float w, h;\n"
+ RGB_TO_YUV_COEFFICIENTS
+ "void main(void) {\n"
+ " vec3 rgb1, rgb2;\n"
+ " float fx,fy,y,u,v;\n"
+ " fx = v_texCoord.x;\n"
+ " fy = v_texCoord.y;\n"
+ " rgb1=texture2D(tex,vec2(fx, fy)).rgb;\n"
+ " rgb2=texture2D(tex,vec2(fx*2.0, fy*2.0)).rgb;\n"
+ " y=dot(rgb1, ycoeff);\n"
+ " u=dot(rgb2, ucoeff);\n"
+ " v=dot(rgb2, vcoeff);\n"
+ " y+=offset.x;\n"
+ " u+=offset.y;\n"
+ " v+=offset.z;\n"
+ " gl_FragData[0] = vec4(y, 0.0, 0.0, 1.0);\n"
+ " gl_FragData[1] = vec4(u, 0.0, 0.0, 1.0);\n"
+ " gl_FragData[2] = vec4(v, 0.0, 0.0, 1.0);\n"
+ "}\n";
static const gchar *text_shader_AYUV_gles2 =
"precision mediump float;\n"
@@ -566,6 +585,15 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
}
GST_INFO ("Context, EXT_framebuffer_object supported: yes");
+ /* Need the NV extension for multi-planar formats with GLES2,
+ * or need GLES3 */
+ if (USING_GLES2 (display) && GST_VIDEO_INFO_N_PLANES (&download->info)
+ && (!gl->DrawBuffers || !gl->ReadBuffer)) {
+ gst_gl_display_set_error (display,
+ "No glDrawBuffers or glReadBuffer support");
+ goto error;
+ }
+
/* setup FBO */
gl->GenFramebuffers (1, &download->fbo);
gl->BindFramebuffer (GL_FRAMEBUFFER, download->fbo);
@@ -663,10 +691,10 @@ _init_download (GstGLDisplay * display, GstGLDownload * download)
}
break;
default:
- break;
gst_gl_display_set_error (display, "Unsupported download video format %d",
v_format);
g_assert_not_reached ();
+ break;
}
no_convert:
@@ -794,8 +822,17 @@ _init_download_shader (GstGLDisplay * display, GstGLDownload * download)
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
{
- _create_shader (display, download->priv->vert_shader,
- download->priv->I420_YV12, &download->shader);
+ if (_create_shader (display, download->priv->vert_shader,
+ download->priv->I420_YV12, &download->shader)) {
+ if (USING_GLES2 (display)) {
+ download->shader_attr_position_loc =
+ gst_gl_shader_get_attribute_location (download->shader,
+ "a_position");
+ download->shader_attr_texture_loc =
+ gst_gl_shader_get_attribute_location (download->shader,
+ "a_texCoord");
+ }
+ }
break;
}
case GST_VIDEO_FORMAT_AYUV:
@@ -1167,9 +1204,9 @@ _do_download_draw_yuv_opengl (GstGLDisplay * display, GstGLDownload * download)
break;
default:
- break;
gst_gl_display_set_error (display,
"Download video format inconsistensy %d", v_format);
+ break;
}
gl->ClientActiveTexture (GL_TEXTURE0);
@@ -1262,10 +1299,10 @@ _do_download_draw_yuv_opengl (GstGLDisplay * display, GstGLDownload * download)
}
break;
default:
- break;
gst_gl_display_set_error (display,
"Download video format inconsistensy %d", v_format);
g_assert_not_reached ();
+ break;
}
gl->ReadBuffer (GL_NONE);
@@ -1285,6 +1322,18 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
GLint viewport_dim[4];
+ GLenum singleRT[] = {
+ GL_COLOR_ATTACHMENT0
+ };
+ GLenum multipleRT[] = {
+ GL_COLOR_ATTACHMENT0,
+ GL_COLOR_ATTACHMENT1,
+ GL_COLOR_ATTACHMENT2
+ };
+ GLenum noneRT[] = {
+ GL_NONE
+ };
+
const GLfloat vVertices[] = { 1.0f, -1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
@@ -1318,6 +1367,9 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
case GST_VIDEO_FORMAT_UYVY:
case GST_VIDEO_FORMAT_AYUV:
{
+ if (gl->DrawBuffers)
+ gl->DrawBuffers (1, singleRT);
+
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -1340,11 +1392,21 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
case GST_VIDEO_FORMAT_I420:
case GST_VIDEO_FORMAT_YV12:
{
+ gl->DrawBuffers (3, multipleRT);
+
gl->ClearColor (0.0, 0.0, 0.0, 0.0);
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gst_gl_shader_use (download->shader);
+ gl->VertexAttribPointer (download->shader_attr_position_loc, 3,
+ GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
+ gl->VertexAttribPointer (download->shader_attr_texture_loc, 2,
+ GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
+
+ gl->EnableVertexAttribArray (download->shader_attr_position_loc);
+ gl->EnableVertexAttribArray (download->shader_attr_texture_loc);
+
gl->ActiveTexture (GL_TEXTURE0);
gst_gl_shader_set_uniform_1i (download->shader, "tex", 0);
gst_gl_shader_set_uniform_1f (download->shader, "w", (gfloat) out_width);
@@ -1354,14 +1416,17 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
break;
default:
- break;
gst_gl_display_set_error (display,
"Download video format inconsistensy %d", v_format);
+ break;
}
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+ if (gl->DrawBuffers)
+ gl->DrawBuffers (1, noneRT);
+
/* don't check if GLSL is available
* because download yuv is not available
* without GLSL (whereas rgb is)
@@ -1371,6 +1436,9 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
gl->Viewport (viewport_dim[0], viewport_dim[1], viewport_dim[2],
viewport_dim[3]);
+ if (gl->ReadBuffer)
+ gl->ReadBuffer (GL_COLOR_ATTACHMENT0);
+
switch (v_format) {
case GST_VIDEO_FORMAT_AYUV:
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
@@ -1396,10 +1464,12 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
gl->ReadPixels (0, 0, out_width, out_height, GL_LUMINANCE,
GL_UNSIGNED_BYTE, download->data[0]);
+ gl->ReadBuffer (GL_COLOR_ATTACHMENT1);
gl->ReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[1]);
+ gl->ReadBuffer (GL_COLOR_ATTACHMENT2);
gl->ReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[2]);
@@ -1410,22 +1480,27 @@ _do_download_draw_yuv_gles2 (GstGLDisplay * display, GstGLDownload * download)
gl->ReadPixels (0, 0, out_width, out_height, GL_LUMINANCE,
GL_UNSIGNED_BYTE, download->data[0]);
+ gl->ReadBuffer (GL_COLOR_ATTACHMENT1);
gl->ReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[2]);
+ gl->ReadBuffer (GL_COLOR_ATTACHMENT2);
gl->ReadPixels (0, 0, GST_ROUND_UP_2 (out_width) / 2,
GST_ROUND_UP_2 (out_height) / 2, GL_LUMINANCE, GL_UNSIGNED_BYTE,
download->data[1]);
}
break;
default:
- break;
gst_gl_display_set_error (display,
"Download video format inconsistensy %d", v_format);
g_assert_not_reached ();
+ break;
}
+ if (gl->ReadBuffer)
+ gl->ReadBuffer (GL_NONE);
+
gst_gl_display_check_framebuffer_status (display);
gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
}
diff --git a/gst-libs/gst/gl/gstgles2.h b/gst-libs/gst/gl/gstgles2.h
index 49e744b..01948c3 100644
--- a/gst-libs/gst/gl/gstgles2.h
+++ b/gst-libs/gst/gl/gstgles2.h
@@ -35,6 +35,8 @@ G_BEGIN_DECLS
#define GL_BGR GL_RGB
#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_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
//END FIXME
#define GL_TEXTURE_RECTANGLE_ARB GL_TEXTURE_2D
@@ -46,8 +48,6 @@ G_BEGIN_DECLS
#define GL_UNSIGNED_SHORT_8_8_MESA 0
#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0
-#define GL_COLOR_ATTACHMENT1 0
-#define GL_COLOR_ATTACHMENT2 0
#define GL_TEXTURE_ENV 0
#define GL_TEXTURE_ENV_MODE 0
#define GL_DEPTH24_STENCIL8 0