From 31b67c52b1978a7c21a6e27f05c2d697501bc583 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Mon, 23 Jun 2008 18:56:29 +0000 Subject: [PATCH] [109/906] git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@543 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstgldisplay.c | 193 ++++++--------------------------- gst-libs/gst/gl/gstgldisplay.h | 21 ++-- gst/gl/gstglcolorscale.c | 6 +- gst/gl/gstglfilterapp.c | 37 +++---- gst/gl/gstglfilterapp.h | 2 +- gst/gl/gstglimagesink.c | 52 +++++++-- gst/gl/gstglimagesink.h | 4 +- gst/gl/gstgltestsrc.c | 7 +- gst/gl/gstglupload.c | 3 +- 9 files changed, 113 insertions(+), 212 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index ab23083362..4183ea6de4 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -55,7 +55,6 @@ void gst_gl_display_onClose (void); void gst_gl_display_make_texture (GstGLDisplay* display); void gst_gl_display_fill_texture (GstGLDisplay* display); void gst_gl_display_draw_texture (GstGLDisplay* display); -void gst_gl_display_draw_graphic (GstGLDisplay* display); void gst_gl_display_fill_video (GstGLDisplay* display); void gst_gl_display_gen_texture (GstGLDisplay* display, guint* pTexture); void gst_gl_display_del_texture (GstGLDisplay* display, guint* pTexture); @@ -119,10 +118,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->textureFBOWidth = 0; display->textureFBOHeight = 0; - display->graphicFBO = 0; - display->graphicDepthBuffer = 0; - display->graphicTexture = 0; - display->requestedFBO = 0; display->requestedDepthBuffer = 0; display->requestedTextureFBOWidth = 0; @@ -146,6 +141,9 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->displayedTextureWidth = 0; display->displayedTextureHeight = 0; + display->resize_width = 0; + display->resize_height = 0; + display->preparedTexture = 0; display->currentTexture = 0; @@ -176,8 +174,6 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->winId = 0; display->win_xpos = 0; display->win_ypos = 0; - display->glcontext_width = 0; - display->glcontext_height = 0; display->visible = FALSE; display->isAlive = TRUE; display->clientReshapeCallback = NULL; @@ -224,8 +220,8 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) "void main(void) {\n" " float r,g,b,y,u,v;\n" " vec2 nxy=gl_TexCoord[0].xy;\n" - " y=texture2DRect(Ytex,nxy).r;\n" - " u=texture2DRect(Utex,nxy*0.5).r;\n" + " y=texture2DRect(Ytex,nxy*0.5).r;\n" + " u=texture2DRect(Utex,nxy).r;\n" " v=texture2DRect(Vtex,nxy*0.5).r;\n" " y=1.1643*(y-0.0625);\n" " u=u-0.5;\n" @@ -460,7 +456,7 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display) //prepare opengl context glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(display->win_xpos, display->win_ypos); - glutInitWindowSize(display->glcontext_width, display->glcontext_height); + glutInitWindowSize(display->textureFBOWidth, display->textureFBOHeight); //create opengl context sprintf(buffer, "%d", glutWinId); @@ -614,50 +610,8 @@ gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display) { GST_DEBUG ("Context %d, EXT_framebuffer_object supported: yes", display->glutWinId); - - //-- init graphic frame buffer object (GL texture -> GL scene) - - //setup FBO - glGenFramebuffersEXT (1, &display->graphicFBO); - glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->graphicFBO); - - //setup the render buffer for depth - glGenRenderbuffersEXT(1, &display->graphicDepthBuffer); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, display->graphicDepthBuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, - display->glcontext_width, display->glcontext_height); - - //setup a texture to render to - glGenTextures (1, &display->graphicTexture); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture); - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, - display->glcontext_width, display->glcontext_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - //attach the texture to the FBO to renderer to - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture, 0); - - //attach the depth render buffer to the FBO - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, display->graphicDepthBuffer); - - checkFramebufferStatus(); - - g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) == - GL_FRAMEBUFFER_COMPLETE_EXT); - - //unbind the FBO - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - //-- init output frame buffer object (GL -> video) - display->outputWidth = display->glcontext_width; - display->outputHeight = display->glcontext_height; - //setup FBO glGenFramebuffersEXT (1, &display->videoFBO); glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->videoFBO); @@ -984,10 +938,6 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display) glDeleteFramebuffersEXT (1, &display->fbo); glDeleteRenderbuffersEXT(1, &display->depthBuffer); - glDeleteFramebuffersEXT (1, &display->graphicFBO); - glDeleteRenderbuffersEXT(1, &display->graphicDepthBuffer); - glDeleteTextures (1, &display->graphicTexture); - glDeleteFramebuffersEXT (1, &display->videoFBO); glDeleteRenderbuffersEXT(1, &display->videoDepthBuffer); glDeleteTextures (1, &display->videoTexture); @@ -1031,8 +981,7 @@ static void gst_gl_display_glutReshapeWindow (GstGLDisplay* display) { glutSetWindow (display->glutWinId); - glutReshapeWindow (display->glcontext_width, display->glcontext_height); - //should reset glcontext_width and height + glutReshapeWindow (display->resize_width, display->resize_height); } @@ -1074,7 +1023,6 @@ static void gst_gl_display_glutUpdateVideo (GstGLDisplay * display) { glutSetWindow (display->glutWinId); - gst_gl_display_draw_graphic (display); gst_gl_display_fill_video (display); g_cond_signal (display->cond_video); } @@ -1228,22 +1176,19 @@ gst_gl_display_new (void) /* Init an opengl context */ void -gst_gl_display_initGLContext (GstGLDisplay *display, - GLint x, GLint y, - GLint graphic_width, GLint graphic_height, - GLint video_width, GLint video_height, - gulong winId, - gboolean visible) +gst_gl_display_init_gl_context (GstGLDisplay *display, + GLint x, GLint y, + GLint width, GLint height, + gulong winId, + gboolean visible) { gst_gl_display_lock (display); display->winId = winId; display->win_xpos = x; display->win_ypos = y; - display->glcontext_width = graphic_width; - display->glcontext_height = graphic_height; - display->textureFBOWidth = video_width; - display->textureFBOHeight = video_height; + display->textureFBOWidth = width; + display->textureFBOHeight = height; display->visible = visible; //if no glut_thread exists, create it with a window associated to the display @@ -1331,8 +1276,8 @@ void gst_gl_display_resizeWindow (GstGLDisplay* display, gint width, gint height) { gst_gl_display_lock (display); - display->glcontext_width = width; - display->glcontext_height = height; + display->resize_width = width; + display->resize_height = height; gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_RESHAPE, display); gst_gl_display_unlock (display); } @@ -1500,8 +1445,8 @@ void gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height) { gst_gl_display_lock (display); - display->glcontext_width = width; - display->glcontext_height = height; + display->outputWidth = width; + display->outputHeight = height; gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_OVFBO, display); g_cond_wait (display->cond_download, display->mutex); gst_gl_display_unlock (display); @@ -1537,7 +1482,7 @@ gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader) void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) { - static gint glheight = 0; + static gint y_pos = 0; gst_gl_display_lock (display); gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DESTROY, display); @@ -1555,9 +1500,8 @@ gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) } //init opengl context - gst_gl_display_initGLContext (display, - 50, glheight++ * (display->glcontext_height+50) + 50, - display->glcontext_width, display->glcontext_height, + gst_gl_display_init_gl_context (display, + 50, y_pos++ * (display->textureFBOHeight+50) + 50, display->textureFBOWidth, display->textureFBOHeight, winId, TRUE); @@ -2048,80 +1992,10 @@ gst_gl_display_draw_texture (GstGLDisplay* display) } -/* called by gst_gl_display_glutUpdateTexture (in the glut thread) */ -void -gst_gl_display_draw_graphic (GstGLDisplay* display) -{ - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, display->graphicFBO); - - glPushAttrib(GL_VIEWPORT_BIT); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPerspective(45, (gfloat)display->glcontext_width/(gfloat)display->glcontext_height, 0.1, 100); - //gluOrtho2D(0.0, display->glcontext_width, 0.0, display->glcontext_height); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glViewport(0, 0, display->glcontext_width, display->glcontext_height); - - glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - //check if a client draw callback is registered - if (display->clientDrawCallback) - { - display->clientDrawCallback(display->recordedTexture, - display->recordedTextureWidth, display->recordedTextureHeight); - } - else - { - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); - - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->recordedTexture); - glEnable (GL_TEXTURE_RECTANGLE_ARB); - - glBegin (GL_QUADS); - glTexCoord2i (display->recordedTextureWidth, 0); - glVertex2f (1.0f, 1.0f); - glTexCoord2i (0, 0); - glVertex2f (-1.0f, 1.0f); - glTexCoord2i (0, display->recordedTextureHeight); - glVertex2f (-1.0f, -1.0f); - glTexCoord2i (display->recordedTextureWidth, display->recordedTextureHeight); - glVertex2f (1.0f, -1.0f); - glEnd (); - } - - glDrawBuffer(GL_NONE); - - glUseProgramObjectARB (0); - - glDisable(GL_TEXTURE_RECTANGLE_ARB); - - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopAttrib(); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - - checkFramebufferStatus(); -} - - /* called by gst_gl_display_glutUpdateVideo (in the glut thread) */ void gst_gl_display_fill_video (GstGLDisplay* display) { - gint width = display->outputWidth; gint height = display->outputHeight; GstVideoFormat outputVideo_format = display->outputVideo_format; @@ -2134,7 +2008,8 @@ gst_gl_display_fill_video (GstGLDisplay* display) glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - gluOrtho2D(0.0, width, 0.0, height); + //gluOrtho2D(0.0, width, 0.0, height); + gluPerspective(45, (gfloat)width/(gfloat)height, 0.1, 100); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -2157,7 +2032,7 @@ gst_gl_display_fill_video (GstGLDisplay* display) glMatrixMode (GL_PROJECTION); glLoadIdentity (); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->recordedTexture); glEnable(GL_TEXTURE_RECTANGLE_ARB); } break; @@ -2193,7 +2068,7 @@ gst_gl_display_fill_video (GstGLDisplay* display) glActiveTextureARB(GL_TEXTURE0_ARB); i = glGetUniformLocationARB (GLSLProgram_to_YUY2_UYVY, "tex"); glUniform1iARB (i, 0); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->recordedTexture); } break; @@ -2216,10 +2091,10 @@ gst_gl_display_fill_video (GstGLDisplay* display) i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "tex"); glUniform1iARB (i, 0); i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "w"); - glUniform1fARB (i, (gfloat)width); + glUniform1fARB (i, (gfloat)display->recordedTextureWidth); i = glGetUniformLocationARB (display->GLSLProgram_to_I420_YV12, "h"); - glUniform1fARB (i, (gfloat)height); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture); + glUniform1fARB (i, (gfloat)display->recordedTextureHeight); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->recordedTexture); } break; @@ -2240,7 +2115,7 @@ gst_gl_display_fill_video (GstGLDisplay* display) glActiveTextureARB(GL_TEXTURE0_ARB); i = glGetUniformLocationARB (display->GLSLProgram_to_AYUV, "tex"); glUniform1iARB (i, 0); - glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->graphicTexture); + glBindTexture (GL_TEXTURE_RECTANGLE_ARB, display->recordedTexture); } break; @@ -2250,14 +2125,14 @@ gst_gl_display_fill_video (GstGLDisplay* display) }//end switch display->currentVideo_format glBegin (GL_QUADS); - glTexCoord2i (width, 0); - glVertex2f (1.0f, 1.0f); glTexCoord2i (0, 0); - glVertex2f (-1.0f, 1.0f); - glTexCoord2i (0, height); glVertex2f (-1.0f, -1.0f); - glTexCoord2i (width, height); + glTexCoord2i (width, 0); glVertex2f (1.0f, -1.0f); + glTexCoord2i (width, height); + glVertex2f (1.0f, 1.0f); + glTexCoord2i (0, height); + glVertex2f (-1.0f, 1.0f); glEnd (); glDrawBuffer(GL_NONE); diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index ba3eaed965..d0896ee2b8 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -111,8 +111,6 @@ struct _GstGLDisplay { GString* title; gint win_xpos; gint win_ypos; - gint glcontext_width; - gint glcontext_height; gboolean visible; gboolean isAlive; @@ -123,11 +121,6 @@ struct _GstGLDisplay { GLuint textureFBOWidth; GLuint textureFBOHeight; - //graphic frame buffer object (GL texture -> GL scene) - GLuint graphicFBO; - GLuint graphicDepthBuffer; - GLuint graphicTexture; - //filter frame buffer object (GL -> GL) GLuint requestedFBO; GLuint requestedDepthBuffer; @@ -154,6 +147,9 @@ struct _GstGLDisplay { GLuint displayedTextureWidth; GLuint displayedTextureHeight; + gint resize_width; + gint resize_height; + GLuint preparedTexture; GLuint currentTexture; @@ -230,12 +226,11 @@ GType gst_gl_display_get_type (void); //-------------------- Public declarations ------------------ //------------------------------------------------------------ GstGLDisplay *gst_gl_display_new (void); -void gst_gl_display_initGLContext (GstGLDisplay* display, - GLint x, GLint y, - GLint graphic_width, GLint graphic_height, - GLint video_width, GLint video_height, - gulong winId, - gboolean visible); +void gst_gl_display_init_gl_context (GstGLDisplay* display, + GLint x, GLint y, + GLint width, GLint height, + gulong winId, + gboolean visible); void gst_gl_display_setClientReshapeCallback (GstGLDisplay* display, CRCB cb); void gst_gl_display_setClientDrawCallback (GstGLDisplay* display, CDCB cb); void gst_gl_display_setVisibleWindow (GstGLDisplay* display, gboolean visible); diff --git a/gst/gl/gstglcolorscale.c b/gst/gl/gstglcolorscale.c index 3b7d803282..21f9b8bc43 100644 --- a/gst/gl/gstglcolorscale.c +++ b/gst/gl/gstglcolorscale.c @@ -389,10 +389,10 @@ gst_gl_colorscale_set_caps (GstBaseTransform* bt, GstCaps* incaps, colorscale->display = gst_gl_display_new (); //init unvisible opengl context - gst_gl_display_initGLContext (colorscale->display, + gst_gl_display_init_gl_context (colorscale->display, 50, y_pos++ * (colorscale->output_video_height+50) + 50, - colorscale->output_video_width, colorscale->output_video_height, - colorscale->output_video_width, colorscale->output_video_height, 0, FALSE); + colorscale->output_video_width, colorscale->output_video_height, + 0, FALSE); //blocking call gst_gl_display_initDonwloadFBO (colorscale->display, diff --git a/gst/gl/gstglfilterapp.c b/gst/gl/gstglfilterapp.c index a5bfd781bf..070b5b146c 100644 --- a/gst/gl/gstglfilterapp.c +++ b/gst/gl/gstglfilterapp.c @@ -53,7 +53,6 @@ static void gst_gl_filter_app_get_property (GObject* object, guint prop_id, static gboolean gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, GstCaps* outcaps); -static void gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter); static gboolean gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf); static void gst_gl_filter_app_callback (guint width, guint height, guint texture, GLhandleARB shader); @@ -78,7 +77,6 @@ gst_gl_filter_app_class_init (GstGLFilterAppClass* klass) GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_filter_app_set_caps; GST_GL_FILTER_CLASS (klass)->filter = gst_gl_filter_app_filter; - GST_GL_FILTER_CLASS (klass)->onInitFBO = gst_gl_filter_app_setClientCallbacks; g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", @@ -145,30 +143,27 @@ gst_gl_filter_app_set_caps (GstGLFilter* filter, GstCaps* incaps, return TRUE; } -static void -gst_gl_filter_app_setClientCallbacks (GstGLFilter* filter) -{ - GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); - - //set the client reshape callback - gst_gl_display_setClientReshapeCallback (filter->display, - app_filter->clientReshapeCallback); - - //set the client draw callback - gst_gl_display_setClientDrawCallback (filter->display, - app_filter->clientDrawCallback); -} - static gboolean gst_gl_filter_app_filter (GstGLFilter* filter, GstGLBuffer* inbuf, GstGLBuffer* outbuf) { - //GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); + GstGLFilterApp* app_filter = GST_GL_FILTER_APP(filter); - //blocking call, use a FBO - gst_gl_display_useFBO (filter->display, filter->width, filter->height, - filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback, - inbuf->width, inbuf->height, inbuf->texture, 0); + if (app_filter->clientDrawCallback) + { + //blocking call, use a FBO + gst_gl_display_useFBO (filter->display, filter->width, filter->height, + filter->fbo, filter->depthbuffer, outbuf->texture, app_filter->clientDrawCallback, + inbuf->width, inbuf->height, inbuf->texture, 0); + } + //default + else + { + //blocking call, use a FBO + gst_gl_display_useFBO (filter->display, filter->width, filter->height, + filter->fbo, filter->depthbuffer, outbuf->texture, gst_gl_filter_app_callback, + inbuf->width, inbuf->height, inbuf->texture, 0); + } return TRUE; } diff --git a/gst/gl/gstglfilterapp.h b/gst/gl/gstglfilterapp.h index 95c24dbe9f..d67ca8433c 100644 --- a/gst/gl/gstglfilterapp.h +++ b/gst/gl/gstglfilterapp.h @@ -39,7 +39,7 @@ struct _GstGLFilterApp GstGLFilter filter; CRCB clientReshapeCallback; - CDCB clientDrawCallback; + GLCB clientDrawCallback; }; struct _GstGLFilterAppClass diff --git a/gst/gl/gstglimagesink.c b/gst/gl/gstglimagesink.c index 1a5957f0c5..e64d02e029 100644 --- a/gst/gl/gstglimagesink.c +++ b/gst/gl/gstglimagesink.c @@ -76,8 +76,10 @@ static GstStaticPadTemplate gst_glimage_sink_template = enum { - ARG_0, - ARG_DISPLAY + ARG_0, + ARG_DISPLAY, + PROP_CLIENT_RESHAPE_CALLBACK, + PROP_CLIENT_DRAW_CALLBACK }; GST_BOILERPLATE_FULL (GstGLImageSink, gst_glimage_sink, GstVideoSink, @@ -135,6 +137,16 @@ gst_glimage_sink_class_init (GstGLImageSinkClass* klass) g_param_spec_string ("display", "Display", "Display name", NULL, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_CLIENT_RESHAPE_CALLBACK, + g_param_spec_pointer ("client_reshape_callback", "Client reshape callback", + "Define a custom reshape callback in a client code", + G_PARAM_WRITABLE)); + + g_object_class_install_property (gobject_class, PROP_CLIENT_DRAW_CALLBACK, + g_param_spec_pointer ("client_draw_callback", "Client draw callback", + "Define a custom draw callback in a client code", + G_PARAM_WRITABLE)); + gobject_class->finalize = gst_glimage_sink_finalize; gstelement_class->change_state = gst_glimage_sink_change_state; @@ -156,6 +168,8 @@ gst_glimage_sink_init (GstGLImageSink* glimage_sink, glimage_sink->window_id = 0; glimage_sink->display = NULL; glimage_sink->stored_buffer = NULL; + glimage_sink->clientReshapeCallback = NULL; + glimage_sink->clientDrawCallback = NULL; } static void @@ -171,9 +185,21 @@ gst_glimage_sink_set_property (GObject* object, guint prop_id, switch (prop_id) { case ARG_DISPLAY: + { g_free (glimage_sink->display_name); glimage_sink->display_name = g_strdup (g_value_get_string (value)); break; + } + case PROP_CLIENT_RESHAPE_CALLBACK: + { + glimage_sink->clientReshapeCallback = g_value_get_pointer (value); + break; + } + case PROP_CLIENT_DRAW_CALLBACK: + { + glimage_sink->clientDrawCallback = g_value_get_pointer (value); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -412,6 +438,12 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) if (glimage_sink->window_id) gst_gl_display_set_windowId (glimage_sink->display, glimage_sink->window_id); + gst_gl_display_setClientReshapeCallback (glimage_sink->display, + glimage_sink->clientReshapeCallback); + + gst_gl_display_setClientDrawCallback (glimage_sink->display, + glimage_sink->clientDrawCallback); + gst_gl_display_resizeWindow (glimage_sink->display, glimage_sink->width, glimage_sink->height); gst_gl_display_setVisibleWindow (glimage_sink->display, TRUE); @@ -425,7 +457,7 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) { //do not stack when multiple windows - static gint glheight = 0; + static gint y_pos = 0; //create a display glimage_sink->display = gst_gl_display_new (); @@ -435,12 +467,16 @@ gst_glimage_sink_render (GstBaseSink* bsink, GstBuffer* buf) gst_x_overlay_prepare_xwindow_id (GST_X_OVERLAY (glimage_sink)); //init opengl context - gst_gl_display_initGLContext (glimage_sink->display, - 50, glheight++ * (glimage_sink->height+50) + 50, + gst_gl_display_init_gl_context (glimage_sink->display, + 50, y_pos++ * (glimage_sink->height+50) + 50, glimage_sink->width, glimage_sink->height, - glimage_sink->width, glimage_sink->height, - glimage_sink->window_id, - TRUE); + glimage_sink->window_id, TRUE); + + gst_gl_display_setClientReshapeCallback (glimage_sink->display, + glimage_sink->clientReshapeCallback); + + gst_gl_display_setClientDrawCallback (glimage_sink->display, + glimage_sink->clientDrawCallback); } //blocking call diff --git a/gst/gl/gstglimagesink.h b/gst/gl/gstglimagesink.h index 6ac4e76419..26823c7e35 100644 --- a/gst/gl/gstglimagesink.h +++ b/gst/gl/gstglimagesink.h @@ -51,7 +51,6 @@ struct _GstGLImageSink gchar *display_name; gulong window_id; - //gboolean isInternal; //caps GstCaps *caps; @@ -64,6 +63,9 @@ struct _GstGLImageSink GstGLDisplay *display; GstGLBuffer *stored_buffer; + + CRCB clientReshapeCallback; + CDCB clientDrawCallback; }; struct _GstGLImageSinkClass diff --git a/gst/gl/gstgltestsrc.c b/gst/gl/gstgltestsrc.c index 3a7fea8122..e53a119852 100644 --- a/gst/gl/gstgltestsrc.c +++ b/gst/gl/gstgltestsrc.c @@ -340,7 +340,7 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps) gboolean res; gint width, height, rate_denominator, rate_numerator; GstGLTestSrc* gltestsrc; - static gint y = 0; + static gint y_pos = 0; gltestsrc = GST_GL_TEST_SRC (bsrc); @@ -363,9 +363,8 @@ gst_gl_test_src_setcaps (GstBaseSrc* bsrc, GstCaps* caps) gltestsrc->display = gst_gl_display_new (); - gst_gl_display_initGLContext (gltestsrc->display, - 50, y++ * (gltestsrc->height+50) + 50, - gltestsrc->width, gltestsrc->height, + gst_gl_display_init_gl_context (gltestsrc->display, + 50, y_pos++ * (gltestsrc->height+50) + 50, gltestsrc->width, gltestsrc->height, 0, FALSE); gst_gl_display_requestFBO (gltestsrc->display, gltestsrc->width, gltestsrc->height, diff --git a/gst/gl/gstglupload.c b/gst/gl/gstglupload.c index f50e7ab85a..d86b7c1dfa 100644 --- a/gst/gl/gstglupload.c +++ b/gst/gl/gstglupload.c @@ -397,9 +397,8 @@ gst_gl_upload_set_caps (GstBaseTransform* bt, GstCaps* incaps, upload->display = gst_gl_display_new (); //init unvisible opengl context - gst_gl_display_initGLContext (upload->display, + gst_gl_display_init_gl_context (upload->display, 50, y_pos++ * (upload->gl_height+50) + 50, - upload->gl_width, upload->gl_height, upload->gl_width, upload->gl_height, 0, FALSE); return ret;