mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 20:21:24 +00:00
[698/906] move sink-specific stuff from GstGLDisplay into glimagesink
This commit is contained in:
parent
ba9e2213fc
commit
d76a61608d
4 changed files with 302 additions and 349 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue