[698/906] move sink-specific stuff from GstGLDisplay into glimagesink

This commit is contained in:
Matthew Waters 2013-06-11 12:26:50 +10:00
parent ba9e2213fc
commit d76a61608d
4 changed files with 302 additions and 349 deletions

View file

@ -75,9 +75,6 @@ static void gst_gl_display_finalize (GObject * object);
gpointer gst_gl_display_thread_create_context (GstGLDisplay * display);
void gst_gl_display_thread_destroy_context (GstGLDisplay * display);
void gst_gl_display_thread_run_generic (GstGLDisplay * display);
#if GST_GL_HAVE_GLES2
void gst_gl_display_thread_init_redisplay (GstGLDisplay * display);
#endif
void gst_gl_display_thread_gen_fbo (GstGLDisplay * display);
void gst_gl_display_thread_use_fbo (GstGLDisplay * display);
void gst_gl_display_thread_use_fbo_v2 (GstGLDisplay * display);
@ -88,9 +85,6 @@ void gst_gl_display_thread_del_shader (GstGLDisplay * display);
/* private methods */
void gst_gl_display_lock (GstGLDisplay * display);
void gst_gl_display_unlock (GstGLDisplay * display);
void gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height);
void gst_gl_display_on_draw (GstGLDisplay * display);
void gst_gl_display_on_close (GstGLDisplay * display);
void gst_gl_display_del_texture_thread (GstGLDisplay * display,
GLuint * pTexture);
@ -103,29 +97,6 @@ void _del_shader (GstGLDisplay * display);
void _use_fbo (GstGLDisplay * display);
void _use_fbo_v2 (GstGLDisplay * display);
#if GST_GL_HAVE_GLES2
/* *INDENT-OFF* */
static const gchar *redisplay_vertex_shader_str_gles2 =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
static const gchar *redisplay_fragment_shader_str_gles2 =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"} \n";
/* *INDENT-ON* */
#endif
struct _GstGLDisplayPrivate
{
/* conditions */
@ -136,18 +107,6 @@ struct _GstGLDisplayPrivate
GstGLDisplayThreadFunc generic_callback;
gpointer data;
/* action redisplay */
GLuint redisplay_texture;
GLuint redisplay_texture_width;
GLuint redisplay_texture_height;
#if GST_GL_HAVE_GLES2
GstGLShader *redisplay_shader;
gchar *redisplay_vertex_shader_str_gles2;
gchar *redisplay_fragment_shader_str_gles2;
GLint redisplay_attr_position_loc;
GLint redisplay_attr_texture_loc;
#endif
/* action gen and del texture */
GLuint gen_texture;
GLuint gen_texture_width;
@ -541,14 +500,6 @@ gst_gl_display_thread_create_context (GstGLDisplay * display)
goto failure;
}
/* setup callbacks */
gst_gl_window_set_resize_callback (display->gl_window,
GST_GL_WINDOW_RESIZE_CB (gst_gl_display_on_resize), display);
gst_gl_window_set_draw_callback (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_on_draw), display);
gst_gl_window_set_close_callback (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_on_close), display);
g_cond_signal (&display->priv->cond_create_context);
display->isAlive = TRUE;
@ -590,13 +541,6 @@ failure:
void
gst_gl_display_thread_destroy_context (GstGLDisplay * display)
{
#if GST_GL_HAVE_GLES2
if (display->priv->redisplay_shader) {
g_object_unref (G_OBJECT (display->priv->redisplay_shader));
display->priv->redisplay_shader = NULL;
}
#endif
GST_INFO ("Context destroyed");
}
@ -610,36 +554,6 @@ gst_gl_display_thread_run_generic (GstGLDisplay * display)
display->priv->generic_callback (display, display->priv->data);
}
#if GST_GL_HAVE_GLES2
/* Called in the gl thread */
void
gst_gl_display_thread_init_redisplay (GstGLDisplay * display)
{
GError *error = NULL;
display->priv->redisplay_shader = gst_gl_shader_new (display);
gst_gl_shader_set_vertex_source (display->priv->redisplay_shader,
redisplay_vertex_shader_str_gles2);
gst_gl_shader_set_fragment_source (display->priv->redisplay_shader,
redisplay_fragment_shader_str_gles2);
gst_gl_shader_compile (display->priv->redisplay_shader, &error);
if (error) {
gst_gl_display_set_error (display, "%s", error->message);
g_error_free (error);
error = NULL;
gst_gl_display_clear_shader (display);
} else {
display->priv->redisplay_attr_position_loc =
gst_gl_shader_get_attribute_location (display->priv->redisplay_shader,
"a_position");
display->priv->redisplay_attr_texture_loc =
gst_gl_shader_get_attribute_location (display->priv->redisplay_shader,
"a_texCoord");
}
}
#endif
void
_gen_fbo (GstGLDisplay * display)
{
@ -932,168 +846,6 @@ _del_shader (GstGLDisplay * display)
//---------------------- BEGIN PRIVATE -----------------------
//------------------------------------------------------------
void
gst_gl_display_on_resize (GstGLDisplay * display, gint width, gint height)
{
const GstGLFuncs *gl = display->gl_vtable;
GST_TRACE ("GL Window resized to %ux%u", width, height);
//check if a client reshape callback is registered
if (display->priv->clientReshapeCallback)
display->priv->clientReshapeCallback (width, height,
display->priv->client_data);
//default reshape
else {
if (display->keep_aspect_ratio) {
GstVideoRectangle src, dst, result;
src.x = 0;
src.y = 0;
src.w = display->priv->redisplay_texture_width;
src.h = display->priv->redisplay_texture_height;
dst.x = 0;
dst.y = 0;
dst.w = width;
dst.h = height;
gst_video_sink_center_rect (src, dst, &result, TRUE);
gl->Viewport (result.x, result.y, result.w, result.h);
} else {
gl->Viewport (0, 0, width, height);
}
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (display)) {
gl->MatrixMode (GL_PROJECTION);
gl->LoadIdentity ();
gluOrtho2D (0, width, 0, height);
gl->MatrixMode (GL_MODELVIEW);
}
#endif
}
}
void
gst_gl_display_on_draw (GstGLDisplay * display)
{
const GstGLFuncs *gl = display->gl_vtable;
/* check if texture is ready for being drawn */
if (!display->priv->redisplay_texture)
return;
/* opengl scene */
GST_TRACE ("drawing texture:%u", display->priv->redisplay_texture);
/* make sure that the environnement is clean */
gst_gl_display_clear_shader (display);
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (display))
gl->Disable (GL_TEXTURE_RECTANGLE_ARB);
#endif
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, 0);
/* check if a client draw callback is registered */
if (display->priv->clientDrawCallback) {
gboolean doRedisplay =
display->priv->clientDrawCallback (display->priv->redisplay_texture,
display->priv->redisplay_texture_width,
display->priv->redisplay_texture_height,
display->priv->client_data);
if (doRedisplay && display->gl_window)
gst_gl_window_draw_unlocked (display->gl_window,
display->priv->redisplay_texture_width,
display->priv->redisplay_texture_height);
}
/* default opengl scene */
else {
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (display)) {
gfloat verts[8] = { 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
gint texcoords[8] = { display->priv->redisplay_texture_width, 0,
0, 0,
0, display->priv->redisplay_texture_height,
display->priv->redisplay_texture_width,
display->priv->redisplay_texture_height
};
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl->MatrixMode (GL_PROJECTION);
gl->LoadIdentity ();
gl->Enable (GL_TEXTURE_RECTANGLE_ARB);
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB,
display->priv->redisplay_texture);
gl->EnableClientState (GL_VERTEX_ARRAY);
gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
gl->TexCoordPointer (2, GL_INT, 0, &texcoords);
gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);
gl->DisableClientState (GL_VERTEX_ARRAY);
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
gl->Disable (GL_TEXTURE_RECTANGLE_ARB);
}
#endif
#if GST_GL_HAVE_GLES2
if (USING_GLES2 (display)) {
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
gl->Clear (GL_COLOR_BUFFER_BIT);
gst_gl_shader_use (display->priv->redisplay_shader);
/* Load the vertex position */
gl->VertexAttribPointer (display->priv->redisplay_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
/* Load the texture coordinate */
gl->VertexAttribPointer (display->priv->redisplay_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->EnableVertexAttribArray (display->priv->redisplay_attr_position_loc);
gl->EnableVertexAttribArray (display->priv->redisplay_attr_texture_loc);
gl->ActiveTexture (GL_TEXTURE0);
gl->BindTexture (GL_TEXTURE_2D, display->priv->redisplay_texture);
gst_gl_shader_set_uniform_1i (display->priv->redisplay_shader,
"s_texture", 0);
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
#endif
} /* end default opengl scene */
}
void
gst_gl_display_on_close (GstGLDisplay * display)
{
gst_gl_display_set_error (display, "Output window was closed");
}
void
gst_gl_display_gen_texture_window_cb (GstGLDisplay * display)
{
@ -1289,42 +1041,6 @@ gst_gl_display_create_context (GstGLDisplay * display,
return isAlive;
}
/* Called by the glimagesink element */
gboolean
gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture,
gint gl_width, gint gl_height, gint window_width, gint window_height,
gboolean keep_aspect_ratio)
{
gboolean isAlive;
gst_gl_display_lock (display);
if (display->isAlive) {
#if GST_GL_HAVE_GLES2
if (USING_GLES2 (display)) {
if (!display->priv->redisplay_shader) {
gst_gl_window_send_message (display->gl_window,
GST_GL_WINDOW_CB (gst_gl_display_thread_init_redisplay), display);
}
}
#endif
if (texture) {
display->priv->redisplay_texture = texture;
display->priv->redisplay_texture_width = gl_width;
display->priv->redisplay_texture_height = gl_height;
}
display->keep_aspect_ratio = keep_aspect_ratio;
if (display->gl_window)
gst_gl_window_draw (display->gl_window, window_width, window_height);
}
isAlive = display->isAlive;
gst_gl_display_unlock (display);
return isAlive;
}
void
gst_gl_display_thread_add (GstGLDisplay * display,
GstGLDisplayThreadFunc func, gpointer data)
@ -1337,7 +1053,6 @@ gst_gl_display_thread_add (GstGLDisplay * display,
gst_gl_display_unlock (display);
}
/* Called by gst_gl_buffer_new */
void
gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
GstVideoFormat v_format, GLint width, GLint height)
@ -1357,8 +1072,6 @@ gst_gl_display_gen_texture (GstGLDisplay * display, GLuint * pTexture,
gst_gl_display_unlock (display);
}
/* Called by gst_gl_buffer_finalize */
void
gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture)
{
@ -1369,7 +1082,6 @@ gst_gl_display_del_texture (GstGLDisplay * display, GLuint * pTexture)
gst_gl_display_unlock (display);
}
/* Called by gltestsrc and glfilter */
gboolean
gst_gl_display_gen_fbo (GstGLDisplay * display, gint width, gint height,
GLuint * fbo, GLuint * depthbuffer)
@ -1516,44 +1228,6 @@ gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader)
gst_gl_display_unlock (display);
}
/* Called by the glimagesink */
void
gst_gl_display_set_window_id (GstGLDisplay * display, guintptr window_id)
{
gst_gl_display_lock (display);
gst_gl_window_set_window_handle (display->gl_window, window_id);
gst_gl_display_unlock (display);
}
/* Called by the glimagesink */
void
gst_gl_display_set_client_reshape_callback (GstGLDisplay * display, CRCB cb)
{
gst_gl_display_lock (display);
display->priv->clientReshapeCallback = cb;
gst_gl_display_unlock (display);
}
/* Called by the glimagesink */
void
gst_gl_display_set_client_draw_callback (GstGLDisplay * display, CDCB cb)
{
gst_gl_display_lock (display);
display->priv->clientDrawCallback = cb;
gst_gl_display_unlock (display);
}
void
gst_gl_display_set_client_data (GstGLDisplay * display, gpointer data)
{
gst_gl_display_lock (display);
display->priv->client_data = data;
gst_gl_display_unlock (display);
}
gulong
gst_gl_display_get_internal_gl_context (GstGLDisplay * display)
{

View file

@ -179,9 +179,6 @@ GstGLDisplay *gst_gl_display_new (void);
gboolean gst_gl_display_create_context (GstGLDisplay * display,
gulong external_gl_context);
gboolean gst_gl_display_redisplay (GstGLDisplay * display, GLuint texture,
gint gl_width, gint gl_height, gint window_width, gint window_height,
gboolean keep_aspect_ratio);
void gst_gl_display_thread_add (GstGLDisplay * display,
GstGLDisplayThreadFunc func, gpointer data);
@ -211,12 +208,6 @@ gboolean gst_gl_display_gen_shader (GstGLDisplay * display,
const gchar * shader_fragment_source, GstGLShader ** shader);
void gst_gl_display_del_shader (GstGLDisplay * display, GstGLShader * shader);
void gst_gl_display_set_window_id (GstGLDisplay * display, guintptr window_id);
void gst_gl_display_set_client_reshape_callback (GstGLDisplay * display,
CRCB cb);
void gst_gl_display_set_client_draw_callback (GstGLDisplay * display, CDCB cb);
void gst_gl_display_set_client_data (GstGLDisplay * display, gpointer data);
gulong gst_gl_display_get_internal_gl_context (GstGLDisplay * display);
void gst_gl_display_activate_gl_context (GstGLDisplay * display, gboolean activate);

View file

@ -90,6 +90,23 @@
GST_DEBUG_CATEGORY (gst_debug_glimage_sink);
#define GST_CAT_DEFAULT gst_debug_glimage_sink
#define USING_OPENGL(display) (display->gl_api & GST_GL_API_OPENGL)
#define USING_OPENGL3(display) (display->gl_api & GST_GL_API_OPENGL3)
#define USING_GLES(display) (display->gl_api & GST_GL_API_GLES)
#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2)
#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3)
#if GST_GL_HAVE_GLES2
static void gst_glimage_sink_thread_init_redisplay (GstGLDisplay * display);
#endif
static void gst_glimage_sink_on_close (GstGLImageSink * gl_sink);
static void gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width,
gint height);
static void gst_glimage_sink_on_draw (GstGLImageSink * gl_sink);
static gboolean gst_glimage_sink_redisplay (GstGLImageSink * gl_sink,
GLuint texture, gint gl_width, gint gl_height, gint window_width,
gint window_height, gboolean keep_aspect_ratio);
static void gst_glimage_sink_finalize (GObject * object);
static void gst_glimage_sink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * param_spec);
@ -115,6 +132,30 @@ static void gst_glimage_sink_set_window_handle (GstVideoOverlay * overlay,
guintptr id);
static void gst_glimage_sink_expose (GstVideoOverlay * overlay);
#if GST_GL_HAVE_GLES2
/* *INDENT-OFF* */
static const gchar *redisplay_vertex_shader_str_gles2 =
"attribute vec4 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_texCoord; \n"
"void main() \n"
"{ \n"
" gl_Position = a_position; \n"
" v_texCoord = a_texCoord; \n"
"} \n";
static const gchar *redisplay_fragment_shader_str_gles2 =
"precision mediump float; \n"
"varying vec2 v_texCoord; \n"
"uniform sampler2D s_texture; \n"
"void main() \n"
"{ \n"
" gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"} \n";
/* *INDENT-ON* */
#endif
static GstStaticPadTemplate gst_glimage_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
@ -390,6 +431,14 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
return GST_STATE_CHANGE_FAILURE;
}
/* setup callbacks */
gst_gl_window_set_resize_callback (glimage_sink->display->gl_window,
GST_GL_WINDOW_RESIZE_CB (gst_glimage_sink_on_resize), glimage_sink);
gst_gl_window_set_draw_callback (glimage_sink->display->gl_window,
GST_GL_WINDOW_CB (gst_glimage_sink_on_draw), glimage_sink);
gst_gl_window_set_close_callback (glimage_sink->display->gl_window,
GST_GL_WINDOW_CB (gst_glimage_sink_on_close), glimage_sink);
}
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
@ -489,15 +538,6 @@ gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
gst_gl_upload_init_format (glimage_sink->upload,
GST_VIDEO_INFO_FORMAT (&vinfo), width, height, width, height);
gst_gl_display_set_client_reshape_callback (glimage_sink->display,
glimage_sink->clientReshapeCallback);
gst_gl_display_set_client_draw_callback (glimage_sink->display,
glimage_sink->clientDrawCallback);
gst_gl_display_set_client_data (glimage_sink->display,
glimage_sink->client_data);
par_n = GST_VIDEO_INFO_PAR_N (&vinfo);
par_d = GST_VIDEO_INFO_PAR_D (&vinfo);
@ -588,7 +628,7 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
if (glimage_sink->window_id != glimage_sink->new_window_id) {
glimage_sink->window_id = glimage_sink->new_window_id;
gst_gl_display_set_window_id (glimage_sink->display,
gst_gl_window_set_window_handle (glimage_sink->display->gl_window,
glimage_sink->window_id);
}
//the buffer is cleared when an other comes in
@ -605,7 +645,7 @@ gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf)
GST_VIDEO_SINK_HEIGHT (glimage_sink));
//redisplay opengl scene
if (!gst_gl_display_redisplay (glimage_sink->display,
if (!gst_glimage_sink_redisplay (glimage_sink,
tex_id, GST_VIDEO_INFO_WIDTH (&glimage_sink->info),
GST_VIDEO_INFO_HEIGHT (&glimage_sink->info),
GST_VIDEO_SINK_WIDTH (glimage_sink),
@ -657,16 +697,16 @@ gst_glimage_sink_expose (GstVideoOverlay * overlay)
{
GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (overlay);
//redisplay opengl scene
/* redisplay opengl scene */
if (glimage_sink->display && glimage_sink->window_id) {
if (glimage_sink->window_id != glimage_sink->new_window_id) {
glimage_sink->window_id = glimage_sink->new_window_id;
gst_gl_display_set_window_id (glimage_sink->display,
gst_gl_window_set_window_handle (glimage_sink->display->gl_window,
glimage_sink->window_id);
}
gst_gl_display_redisplay (glimage_sink->display, 0, 0, 0, 0, 0,
gst_glimage_sink_redisplay (glimage_sink, 0, 0, 0, 0, 0,
glimage_sink->keep_aspect_ratio);
}
}
@ -749,3 +789,237 @@ config_failed:
return FALSE;
}
}
#if GST_GL_HAVE_GLES2
/* Called in the gl thread */
static void
gst_gl_display_thread_init_redisplay (GstGLImageSink * gl_sink)
{
GError *error = NULL;
gl_sink->redisplay_shader = gst_gl_shader_new (gl_sink->display);
gst_gl_shader_set_vertex_source (gl_sink->redisplay_shader,
redisplay_vertex_shader_str_gles2);
gst_gl_shader_set_fragment_source (gl_sink->redisplay_shader,
redisplay_fragment_shader_str_gles2);
gst_gl_shader_compile (display->gl_sink->redisplay_shader, &error);
if (error) {
gst_gl_display_set_error (gl_sink->display, "%s", error->message);
g_error_free (error);
error = NULL;
gst_gl_display_clear_shader (gl_sink->display);
} else {
gl_sink->redisplay_attr_position_loc =
gst_gl_shader_get_attribute_location (display->priv->redisplay_shader,
"a_position");
gl_sink->redisplay_attr_texture_loc =
gst_gl_shader_get_attribute_location (display->priv->redisplay_shader,
"a_texCoord");
}
}
#endif
static void
gst_glimage_sink_on_resize (GstGLImageSink * gl_sink, gint width, gint height)
{
const GstGLFuncs *gl = gl_sink->display->gl_vtable;
GST_TRACE ("GL Window resized to %ux%u", width, height);
/* check if a client reshape callback is registered */
if (gl_sink->clientReshapeCallback)
gl_sink->clientReshapeCallback (width, height, gl_sink->client_data);
/* default reshape */
else {
if (gl_sink->keep_aspect_ratio) {
GstVideoRectangle src, dst, result;
src.x = 0;
src.y = 0;
src.w = gl_sink->redisplay_texture_width;
src.h = gl_sink->redisplay_texture_height;
dst.x = 0;
dst.y = 0;
dst.w = width;
dst.h = height;
gst_video_sink_center_rect (src, dst, &result, TRUE);
gl->Viewport (result.x, result.y, result.w, result.h);
} else {
gl->Viewport (0, 0, width, height);
}
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (gl_sink->display)) {
gl->MatrixMode (GL_PROJECTION);
gl->LoadIdentity ();
gluOrtho2D (0, width, 0, height);
gl->MatrixMode (GL_MODELVIEW);
}
#endif
}
}
static void
gst_glimage_sink_on_draw (GstGLImageSink * gl_sink)
{
const GstGLFuncs *gl = gl_sink->display->gl_vtable;
/* check if texture is ready for being drawn */
if (!gl_sink->redisplay_texture)
return;
/* opengl scene */
GST_TRACE ("redrawing texture:%u", gl_sink->redisplay_texture);
/* make sure that the environnement is clean */
gst_gl_display_clear_shader (gl_sink->display);
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (gl_sink->display))
gl->Disable (GL_TEXTURE_RECTANGLE_ARB);
#endif
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, 0);
/* check if a client draw callback is registered */
if (gl_sink->clientDrawCallback) {
gboolean doRedisplay =
gl_sink->clientDrawCallback (gl_sink->redisplay_texture,
gl_sink->redisplay_texture_width,
gl_sink->redisplay_texture_height,
gl_sink->client_data);
if (doRedisplay && gl_sink->display->gl_window)
gst_gl_window_draw_unlocked (gl_sink->display->gl_window,
gl_sink->redisplay_texture_width, gl_sink->redisplay_texture_height);
}
/* default opengl scene */
else {
#if GST_GL_HAVE_OPENGL
if (USING_OPENGL (gl_sink->display)) {
gfloat verts[8] = { 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
gint texcoords[8] = { gl_sink->redisplay_texture_width, 0,
0, 0,
0, gl_sink->redisplay_texture_height,
gl_sink->redisplay_texture_width,
gl_sink->redisplay_texture_height
};
gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl->MatrixMode (GL_PROJECTION);
gl->LoadIdentity ();
gl->Enable (GL_TEXTURE_RECTANGLE_ARB);
gl->BindTexture (GL_TEXTURE_RECTANGLE_ARB, gl_sink->redisplay_texture);
gl->EnableClientState (GL_VERTEX_ARRAY);
gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
gl->VertexPointer (2, GL_FLOAT, 0, &verts);
gl->TexCoordPointer (2, GL_INT, 0, &texcoords);
gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);
gl->DisableClientState (GL_VERTEX_ARRAY);
gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);
gl->Disable (GL_TEXTURE_RECTANGLE_ARB);
}
#endif
#if GST_GL_HAVE_GLES2
if (USING_GLES2 (display)) {
const GLfloat vVertices[] = { 1.0f, 1.0f, 0.0f,
1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, 1.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f
};
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
gl->Clear (GL_COLOR_BUFFER_BIT);
gst_gl_shader_use (gl_sink->redisplay_shader);
/* Load the vertex position */
gl->VertexAttribPointer (display->priv->redisplay_attr_position_loc, 3,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), vVertices);
/* Load the texture coordinate */
gl->VertexAttribPointer (display->priv->redisplay_attr_texture_loc, 2,
GL_FLOAT, GL_FALSE, 5 * sizeof (GLfloat), &vVertices[3]);
gl->EnableVertexAttribArray (display->priv->redisplay_attr_position_loc);
gl->EnableVertexAttribArray (display->priv->redisplay_attr_texture_loc);
gl->ActiveTexture (GL_TEXTURE0);
gl->BindTexture (GL_TEXTURE_2D, display->priv->redisplay_texture);
gst_gl_shader_set_uniform_1i (display->priv->redisplay_shader,
"s_texture", 0);
gl->DrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}
#endif
} /* end default opengl scene */
}
static void
gst_glimage_sink_on_close (GstGLImageSink * gl_sink)
{
gst_gl_display_set_error (gl_sink->display, "Output window was closed");
}
static gboolean
gst_glimage_sink_redisplay (GstGLImageSink * gl_sink, GLuint texture,
gint gl_width, gint gl_height, gint window_width, gint window_height,
gboolean keep_aspect_ratio)
{
gboolean isAlive;
gst_gl_display_lock (gl_sink->display);
if (gl_sink->display->isAlive) {
#if GST_GL_HAVE_GLES2
if (USING_GLES2 (gl_sink->display)) {
if (!gl_sink->redisplay_shader) {
gst_gl_window_send_message (display->gl_window,
GST_GL_WINDOW_CB (gst_glimage_sink_thread_init_redisplay), display);
}
}
#endif
if (texture) {
gl_sink->redisplay_texture = texture;
gl_sink->redisplay_texture_width = gl_width;
gl_sink->redisplay_texture_height = gl_height;
}
gl_sink->keep_aspect_ratio = keep_aspect_ratio;
if (gl_sink->display->gl_window)
gst_gl_window_draw (gl_sink->display->gl_window, window_width,
window_height);
}
isAlive = gl_sink->display->isAlive;
gst_gl_display_unlock (gl_sink->display);
return isAlive;
}
void
temp (GstGLImageSink * gl_sink)
{
#if GST_GL_HAVE_GLES2
if (gl_sink->redisplay_shader) {
g_object_unref (G_OBJECT (gl_sink->redisplay_shader));
gl_sink->redisplay_shader = NULL;
}
#endif
}

View file

@ -28,6 +28,7 @@
#include <gst/video/video.h>
#include "gstglbufferpool.h"
#include <gst/gl/gstglconfig.h>
G_BEGIN_DECLS
@ -73,6 +74,19 @@ struct _GstGLImageSink
GValue *par;
GstBufferPool *pool;
/* action redisplay */
GLuint redisplay_texture;
GLuint redisplay_texture_width;
GLuint redisplay_texture_height;
#if GST_GL_HAVE_GLES2
GstGLShader *redisplay_shader;
gchar *redisplay_vertex_shader_str_gles2;
gchar *redisplay_fragment_shader_str_gles2;
GLint redisplay_attr_position_loc;
GLint redisplay_attr_texture_loc;
#endif
};
struct _GstGLImageSinkClass