From 8685e547b4a43626d226b5bceed7a1941cf507e1 Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Fri, 13 Jun 2008 00:01:26 +0000 Subject: [PATCH] [104/906] start to add a glfilteredge that proceeds edge detection using GLSL git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@517 93df14bb-0f41-7a43-8087-d3e2a2f0e464 --- gst-libs/gst/gl/gstgldisplay.c | 87 +++++++++++++++++++++++++++++++--- gst-libs/gst/gl/gstgldisplay.h | 19 ++++++-- gst-libs/gst/gl/gstglfilter.c | 6 +++ gst-libs/gst/gl/gstglfilter.h | 2 + 4 files changed, 104 insertions(+), 10 deletions(-) diff --git a/gst-libs/gst/gl/gstgldisplay.c b/gst-libs/gst/gl/gstgldisplay.c index 3f15efea28..bef4b8d231 100644 --- a/gst-libs/gst/gl/gstgldisplay.c +++ b/gst-libs/gst/gl/gstgldisplay.c @@ -28,11 +28,13 @@ static void gst_gl_display_finalize (GObject * object); static gpointer gst_gl_display_glutThreadFunc (GstGLDisplay* display); static void gst_gl_display_glutCreateWindow (GstGLDisplay* display); -static void gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display); +static void gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display); static void gst_gl_display_glutGenerateFBO (GstGLDisplay *display); static void gst_gl_display_glutUseFBO (GstGLDisplay *display); static void gst_gl_display_glutUseFBO2 (GstGLDisplay *display); static void gst_gl_display_glutDestroyFBO (GstGLDisplay *display); +static void gst_gl_display_glutInitShader (GstGLDisplay *display); +static void gst_gl_display_glutDestroyShader (GstGLDisplay *display); static void gst_gl_display_glutDestroyWindow (GstGLDisplay* display); static void gst_gl_display_glutSetVisibleWindow (GstGLDisplay* display); static void gst_gl_display_glutReshapeWindow (GstGLDisplay* display); @@ -106,6 +108,8 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->cond_create = g_cond_new (); display->cond_destroy = g_cond_new (); display->cond_download = g_cond_new (); + display->cond_initShader = g_cond_new (); + display->cond_destroyShader = g_cond_new (); display->fbo = 0; display->depthBuffer = 0; @@ -204,6 +208,11 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass) display->GLSLProgram_to_I420_YV12 = 0; display->GLSLProgram_to_AYUV = 0; + display->requestedTextShader = NULL; + display->requestedHandleShader = 0; + display->usedHandleShader = 0; + display->rejectedHandleShader = 0; + //YUY2:r,g,a //UYVY:a,b,r display->textFProgram_YUY2_UYVY = @@ -370,6 +379,14 @@ gst_gl_display_finalize (GObject *object) g_cond_free (display->cond_download); display->cond_download = NULL; } + if (display->cond_initShader) { + g_cond_free (display->cond_initShader); + display->cond_initShader = NULL; + } + if (display->cond_destroyShader) { + g_cond_free (display->cond_destroyShader); + display->cond_destroyShader = NULL; + } if (display->cond_generateFBO) { g_cond_free (display->cond_generateFBO); display->cond_generateFBO = NULL; @@ -595,7 +612,7 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display) /* Called by the idle funtion */ static void -gst_gldisplay_glutGenerateOutputVideoFBO (GstGLDisplay *display) +gst_gl_display_glutGenerateOutputVideoFBO (GstGLDisplay *display) { glutSetWindow (display->glutWinId); @@ -821,7 +838,8 @@ gst_gl_display_glutUseFBO (GstGLDisplay *display) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //the opengl scene - display->glsceneFBO_cb (display->inputTextureWidth, display->inputTextureHeight, display->inputTexture); + display->glsceneFBO_cb (display->inputTextureWidth, display->inputTextureHeight, display->inputTexture, + display->usedHandleShader); glDrawBuffer(GL_NONE); @@ -890,9 +908,8 @@ gst_gl_display_glutUseFBO2 (GstGLDisplay *display) /* Called by the idle funtion */ static void -gst_gl_display_glutDestroyFBO (GstGLDisplay *display) +gst_gl_display_glutDestroyFBO (GstGLDisplay* display) { - glutSetWindow (display->glutWinId); glDeleteFramebuffersEXT (1, &display->rejectedFBO); @@ -906,6 +923,27 @@ gst_gl_display_glutDestroyFBO (GstGLDisplay *display) } +/* Called by the idle funtion */ +static void +gst_gl_display_glutInitShader (GstGLDisplay* display) +{ + glutSetWindow (display->glutWinId); + display->requestedHandleShader = gst_gl_display_loadGLSLprogram (display->requestedTextShader); + g_cond_signal (display->cond_initShader); +} + + +/* Called by the idle funtion */ +static void +gst_gl_display_glutDestroyShader (GstGLDisplay* display) +{ + glutSetWindow (display->glutWinId); + glDeleteObjectARB (display->rejectedHandleShader); + g_cond_signal (display->cond_destroyShader); +} + + + /* Called by the idle function */ static void gst_gl_display_glutDestroyWindow (GstGLDisplay *display) @@ -1127,7 +1165,13 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg) gst_gl_display_glutUseFBO2 (msg->display); break; case GST_GL_DISPLAY_ACTION_OVFBO: - gst_gldisplay_glutGenerateOutputVideoFBO (msg->display); + gst_gl_display_glutGenerateOutputVideoFBO (msg->display); + break; + case GST_GL_DISPLAY_ACTION_GENSHADER: + gst_gl_display_glutInitShader (msg->display); + break; + case GST_GL_DISPLAY_ACTION_DELSHADER: + gst_gl_display_glutDestroyShader (msg->display); break; default: g_assert_not_reached (); @@ -1161,6 +1205,8 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg) case GST_GL_DISPLAY_ACTION_USEFBO: case GST_GL_DISPLAY_ACTION_USEFBO2: case GST_GL_DISPLAY_ACTION_OVFBO: + case GST_GL_DISPLAY_ACTION_GENSHADER: + case GST_GL_DISPLAY_ACTION_DELSHADER: //msg is out of date if the associated display is not in the map if (!g_hash_table_lookup (gst_gl_display_map, GINT_TO_POINTER (msg->glutWinId))) valid = FALSE; @@ -1413,7 +1459,8 @@ gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height, void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight, guint fbo, guint depthbuffer, guint textureFBO, GLCB cb, - guint inputTextureWidth, guint inputTextureHeight, guint inputTexture) + guint inputTextureWidth, guint inputTextureHeight, guint inputTexture, + GLhandleARB handleShader) { gst_gl_display_lock (display); display->usedFBO = fbo; @@ -1425,6 +1472,7 @@ gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint texture display->inputTextureWidth = inputTextureWidth; display->inputTextureHeight = inputTextureHeight; display->inputTexture = inputTexture; + display->usedHandleShader = handleShader; gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_USEFBO, display); g_cond_wait (display->cond_useFBO, display->mutex); gst_gl_display_unlock (display); @@ -1478,6 +1526,31 @@ gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height) } +/* Called by gst_gl elements */ +void +gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader) +{ + gst_gl_display_lock (display); + display->requestedTextShader = textShader; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_GENSHADER, display); + g_cond_wait (display->cond_initShader, display->mutex); + *handleShader = display->requestedHandleShader; + gst_gl_display_unlock (display); +} + + +/* Called by gst_gl elements */ +void +gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader) +{ + gst_gl_display_lock (display); + display->rejectedHandleShader = shader; + gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_DELSHADER, display); + g_cond_wait (display->cond_destroyShader, display->mutex); + gst_gl_display_unlock (display); +} + + /* Called by gst_gl elements */ void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId) diff --git a/gst-libs/gst/gl/gstgldisplay.h b/gst-libs/gst/gl/gstgldisplay.h index 494a21370d..db8d7865f4 100644 --- a/gst-libs/gst/gl/gstgldisplay.h +++ b/gst-libs/gst/gl/gstgldisplay.h @@ -56,7 +56,9 @@ typedef enum { GST_GL_DISPLAY_ACTION_DELFBO, GST_GL_DISPLAY_ACTION_USEFBO, GST_GL_DISPLAY_ACTION_USEFBO2, - GST_GL_DISPLAY_ACTION_OVFBO + GST_GL_DISPLAY_ACTION_OVFBO, + GST_GL_DISPLAY_ACTION_GENSHADER, + GST_GL_DISPLAY_ACTION_DELSHADER } GstGLDisplayAction; @@ -82,7 +84,7 @@ typedef void (* CRCB) ( GLuint, GLuint ); typedef gboolean (* CDCB) ( GLuint, GLuint, GLuint); //opengl scene callback -typedef void (* GLCB) ( GLuint, GLuint, GLuint); +typedef void (* GLCB) ( GLuint, GLuint, GLuint, GLhandleARB); typedef void (* GLCB2) ( gpointer* p1, gpointer* p2, gint w, gint h); struct _GstGLDisplay { @@ -101,6 +103,8 @@ struct _GstGLDisplay { GCond* cond_useFBO2; GCond* cond_destroyFBO; GCond* cond_download; + GCond* cond_initShader; + GCond* cond_destroyShader; GCond* cond_create; GCond* cond_destroy; @@ -219,6 +223,12 @@ struct _GstGLDisplay { gchar* textFProgram_to_AYUV; GLhandleARB GLSLProgram_to_AYUV; + + //requested shader + gchar* requestedTextShader; + GLhandleARB requestedHandleShader; + GLhandleARB usedHandleShader; + GLhandleARB rejectedHandleShader; //client callbacks CRCB clientReshapeCallback; @@ -263,13 +273,16 @@ void gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height, guint* fbo, guint* depthbuffer, guint* texture); void gst_gl_display_useFBO (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight, guint fbo, guint depthbuffer, guint textureFBO, GLCB cb, - guint inputTextureWidth, guint inputTextureHeight, guint inputTexture); + guint inputTextureWidth, guint inputTextureHeight, guint inputTexture, + GLhandleARB handleShader); void gst_gl_display_useFBO2 (GstGLDisplay* display, gint textureFBOWidth, gint textureFBOheight, guint fbo, guint depthbuffer, guint textureFBO, GLCB2 cb, gpointer* p1, gpointer* p2); void gst_gl_display_rejectFBO (GstGLDisplay* display, guint fbo, guint depthbuffer, guint texture); void gst_gl_display_initDonwloadFBO (GstGLDisplay* display, gint width, gint height); +void gst_gl_display_initShader (GstGLDisplay* display, gchar* textShader, GLhandleARB* handleShader); +void gst_gl_display_destroyShader (GstGLDisplay* display, GLhandleARB shader); void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId); #endif diff --git a/gst-libs/gst/gl/gstglfilter.c b/gst-libs/gst/gl/gstglfilter.c index ea5225b7aa..a007c6c619 100644 --- a/gst-libs/gst/gl/gstglfilter.c +++ b/gst-libs/gst/gl/gstglfilter.c @@ -103,6 +103,7 @@ gst_gl_filter_class_init (GstGLFilterClass * klass) klass->set_caps = NULL; klass->filter = NULL; klass->onInitFBO = NULL; + klass->onReset = NULL; } static void @@ -147,6 +148,11 @@ gst_gl_filter_get_property (GObject * object, guint prop_id, static void gst_gl_filter_reset (GstGLFilter* filter) { + GstGLFilterClass* filter_class = GST_GL_FILTER_GET_CLASS (filter); + + if (filter_class->onReset) + filter_class->onReset (filter); + if (filter->display) { //blocking call, delete the FBO diff --git a/gst-libs/gst/gl/gstglfilter.h b/gst-libs/gst/gl/gstglfilter.h index 2171193dff..bd3d99dd15 100644 --- a/gst-libs/gst/gl/gstglfilter.h +++ b/gst-libs/gst/gl/gstglfilter.h @@ -44,6 +44,7 @@ typedef gboolean (*GstGLFilterSetCaps) (GstGLFilter* filter, typedef gboolean (*GstGLFilterProcessFunc) (GstGLFilter *filter, GstGLBuffer *inbuf, GstGLBuffer *outbuf); typedef void (*GstGLFilterOnInitFBO) (GstGLFilter *filter); +typedef void (*GstGLFilterOnReset) (GstGLFilter *filter); struct _GstGLFilter { @@ -67,6 +68,7 @@ struct _GstGLFilterClass GstGLFilterSetCaps set_caps; GstGLFilterProcessFunc filter; GstGLFilterOnInitFBO onInitFBO; + GstGLFilterOnReset onReset; }; GType gst_gl_filter_get_type(void);