[081/906] start to add a glfilter
authorJulien Isorce <julien.isorce@gmail.com>
Sat, 7 Jun 2008 00:01:18 +0000 (00:01 +0000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:31:16 +0000 (19:31 +0000)
git-svn-id: svn://svn.wobow.com/GStreamer_playground/gst-plugins-gl@493 93df14bb-0f41-7a43-8087-d3e2a2f0e464

gst-libs/gst/gl/gstglbuffer.c
gst-libs/gst/gl/gstgldisplay.c
gst-libs/gst/gl/gstgldisplay.h

index 40eb4dd..833318a 100644 (file)
@@ -95,7 +95,7 @@ gst_gl_buffer_new_from_video_format (GstGLDisplay* display,
 {
     GstGLBuffer *buffer;
 
-    g_return_val_if_fail (video_format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
+    //g_return_val_if_fail (video_format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
     g_return_val_if_fail (display != NULL, NULL);
     g_return_val_if_fail (width > 0, NULL);
     g_return_val_if_fail (height > 0, NULL);
@@ -108,10 +108,11 @@ gst_gl_buffer_new_from_video_format (GstGLDisplay* display,
     buffer->video_format = video_format;
     GST_BUFFER_SIZE (buffer) = gst_gl_buffer_format_get_size (video_format, context_width, context_height);
 
-    //blocking call, init texture 
-    gst_gl_display_textureRequested (buffer->display, buffer->video_format, 
-           buffer->width, buffer->height, 
-           &buffer->texture, &buffer->texture_u, &buffer->texture_v) ;
+    //blocking call, init texture
+    if (video_format != GST_VIDEO_FORMAT_UNKNOWN)
+        gst_gl_display_textureRequested (buffer->display, buffer->video_format, 
+               buffer->width, buffer->height, 
+               &buffer->texture, &buffer->texture_u, &buffer->texture_v) ;
 
     return buffer;
 }
index a48e0bf..2d8982e 100644 (file)
@@ -28,6 +28,7 @@
 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_gl_display_glutGenerateFBO (GstGLDisplay *display);
 static void gst_gl_display_glutDestroyWindow (GstGLDisplay* display);
 static void gst_gl_display_glutSetVisibleWindow (GstGLDisplay* display);
 static void gst_gl_display_glutPrepareTexture (GstGLDisplay* display);
@@ -93,6 +94,7 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
     display->cond_fill = g_cond_new ();
     display->cond_clear = g_cond_new ();
     display->cond_video = g_cond_new ();
+    display->cond_generateFBO = g_cond_new ();
     display->cond_create = g_cond_new ();
     display->cond_destroy = g_cond_new ();
 
@@ -106,6 +108,12 @@ gst_gl_display_init (GstGLDisplay *display, GstGLDisplayClass *klass)
     display->graphicDepthBuffer = 0;
     display->graphicTexture = 0;
 
+    display->requestedFBO = 0;
+    display->requestedDepthBuffer = 0;
+    display->requestedTextureFBO = 0;
+    display->requestedTextureFBOWidth = 0;
+    display->requestedTextureFBOHeight = 0;
+
     display->requestedTexture = 0;
     display->requestedTexture_u = 0;
     display->requestedTexture_v = 0;
@@ -326,6 +334,10 @@ gst_gl_display_finalize (GObject *object)
         g_cond_free (display->cond_video);
         display->cond_video = NULL;
     }
+    if (display->cond_generateFBO) {
+        g_cond_free (display->cond_generateFBO);
+        display->cond_generateFBO = NULL;
+    }
     if (display->cond_create) {
         g_cond_free (display->cond_create);
         display->cond_create = NULL;
@@ -343,7 +355,7 @@ gst_gl_display_finalize (GObject *object)
     if (g_hash_table_size (gst_gl_display_map) == 0)
     {
         g_thread_join (gst_gl_display_glutThread);
-        GST_DEBUG ("Glut thread joined");
+        g_print ("Glut thread joined\n");
         gst_gl_display_glutThread = NULL;
         g_async_queue_unref (gst_gl_display_messageQueue);
         g_hash_table_unref  (gst_gl_display_map);
@@ -370,9 +382,9 @@ gst_gl_display_glutThreadFunc (GstGLDisplay *display)
     gst_gl_display_glutCreateWindow (display);
     gst_gl_display_unlock (display);
 
-    GST_DEBUG ("Glut mainLoop start");
+    g_print ("Glut mainLoop start\n");
     glutMainLoop ();
-    GST_DEBUG ("Glut mainLoop exited");
+    g_print ("Glut mainLoop exited\n");
 
     return NULL;
 }
@@ -397,7 +409,7 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
     display->title =  g_string_append (display->title, buffer);
     glutWinId = glutCreateWindow (display->title->str, display->winId);
 
-    GST_DEBUG ("Context %d created\n", glutWinId);
+    g_print ("Context %d created\n", glutWinId);
 
     if (display->visible)
         glutShowWindow ();
@@ -646,6 +658,53 @@ gst_gl_display_glutCreateWindow (GstGLDisplay *display)
 }
 
 
+/* Called by the idle funtion */
+static void
+gst_gl_display_glutGenerateFBO (GstGLDisplay *display)
+{
+    
+    glutSetWindow (display->glutWinId);
+   
+    //-- generate frame buffer object
+
+    //setup FBO
+    glGenFramebuffersEXT (1, &display->requestedFBO);
+    glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, display->requestedFBO);
+
+    //setup the render buffer for depth        
+    glGenRenderbuffersEXT(1, &display->requestedDepthBuffer);
+    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, display->requestedDepthBuffer);
+    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,
+        display->requestedTextureFBOWidth, display->requestedTextureFBOHeight);
+
+    //setup a texture to render to
+    glGenTextures (1, &display->requestedTextureFBO);
+    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, display->requestedTextureFBO);
+    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, 
+        display->requestedTextureFBOWidth, display->requestedTextureFBOHeight, 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->requestedTextureFBO, 0);
+
+    //attach the depth render buffer to the FBO
+    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, 
+        GL_RENDERBUFFER_EXT, display->requestedDepthBuffer);
+
+    g_assert (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) ==
+        GL_FRAMEBUFFER_COMPLETE_EXT);
+
+    //unbind the FBO
+    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+    g_cond_signal (display->cond_video);
+}
+
+
 /* Called by the idle function */
 static void
 gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
@@ -695,7 +754,7 @@ gst_gl_display_glutDestroyWindow (GstGLDisplay *display)
     }
 
     g_hash_table_remove (gst_gl_display_map, GINT_TO_POINTER (display->glutWinId)); 
-    GST_DEBUG ("glut window destroyed: %d", display->glutWinId);
+    g_print ("glut window destroyed: %d\n", display->glutWinId);
 
     //if the map is empty, leaveMainloop and join the thread
     if (g_hash_table_size (gst_gl_display_map) == 0)
@@ -806,7 +865,7 @@ gst_gl_display_glut_idle (void)
                 gst_gl_display_glutDispatchAction (msg);  
         }
     }
-    else GST_DEBUG ("timeout reached in idle func");
+    else g_print ("timeout reached in idle func\n");
 }
 
 
@@ -841,6 +900,9 @@ gst_gl_display_glutDispatchAction (GstGLDisplayMsg* msg)
         case GST_GL_DISPLAY_ACTION_REDISPLAY:
             gst_gl_display_glutPostRedisplay (msg->display);
             break;
+        case GST_GL_DISPLAY_ACTION_GENFBO:
+            gst_gl_display_glutGenerateFBO (msg->display);
+            break;
         default:
             g_assert_not_reached ();
     }
@@ -867,6 +929,7 @@ gst_gl_display_checkMsgValidity (GstGLDisplayMsg *msg)
         case GST_GL_DISPLAY_ACTION_CLEAR:          
         case GST_GL_DISPLAY_ACTION_VIDEO:
         case GST_GL_DISPLAY_ACTION_REDISPLAY:
+        case GST_GL_DISPLAY_ACTION_GENFBO:
             //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;
@@ -1010,7 +1073,7 @@ gst_gl_display_textureRequested (GstGLDisplay * display, GstVideoFormat video_fo
 
 /* Called by gst_gl elements */
 void 
-gst_gl_display_textureChanged (GstGLDisplay * display, GstVideoFormat video_format, 
+gst_gl_display_textureChanged (GstGLDisplay* display, GstVideoFormat video_format, 
                                GLuint texture, GLuint texture_u, GLuint texture_v, 
                                gint width, gint height, gpointer data)
 {
@@ -1030,7 +1093,7 @@ gst_gl_display_textureChanged (GstGLDisplay * display, GstVideoFormat video_form
 
 /* Called by gstglbuffer */
 void 
-gst_gl_display_clearTexture (GstGLDisplay * display, guint texture, 
+gst_gl_display_clearTexture (GstGLDisplay* display, guint texture, 
                              guint texture_u, guint texture_v)
 {
     gst_gl_display_lock (display);
@@ -1076,6 +1139,23 @@ gst_gl_display_postRedisplay (GstGLDisplay* display)
 
 /* Called by gst_gl elements */
 void 
+gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height, 
+                           guint* fbo, guint* depthbuffer, guint* texture)
+{
+    gst_gl_display_lock (display);
+    display->requestedTextureFBOWidth = width;
+    display->requestedTextureFBOHeight = height;
+    gst_gl_display_postMessage (GST_GL_DISPLAY_ACTION_GENFBO, display);
+    g_cond_wait (display->cond_generateFBO, display->mutex);
+    *fbo = display->requestedFBO;
+    *depthbuffer = display->requestedDepthBuffer;
+    *texture = display->requestedTextureFBO;
+    gst_gl_display_unlock (display);
+}
+
+
+/* Called by gst_gl elements */
+void 
 gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId)
 {
     static gint glheight = 0;
@@ -1088,7 +1168,7 @@ gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId)
     if (g_hash_table_size (gst_gl_display_map) == 0)
     {
         g_thread_join (gst_gl_display_glutThread);
-        GST_DEBUG ("Glut thread joined when setting winId");
+        g_print ("Glut thread joined when setting winId\n");
         gst_gl_display_glutThread = NULL;
         g_async_queue_unref (gst_gl_display_messageQueue);
         g_hash_table_unref  (gst_gl_display_map);
index f45d4dc..fe5816e 100644 (file)
@@ -50,7 +50,8 @@ typedef enum {
     GST_GL_DISPLAY_ACTION_CHANGE,
     GST_GL_DISPLAY_ACTION_CLEAR,
     GST_GL_DISPLAY_ACTION_VIDEO,
-    GST_GL_DISPLAY_ACTION_REDISPLAY
+    GST_GL_DISPLAY_ACTION_REDISPLAY,
+    GST_GL_DISPLAY_ACTION_GENFBO
        
 } GstGLDisplayAction;
 
@@ -78,20 +79,21 @@ typedef gboolean (* CDCB) ( GLuint, GLuint, GLuint);
 struct _GstGLDisplay {
     GObject object;
 
-    GMutex *mutex;
+    GMutexmutex;
 
        GQueue* texturePool;
     
-    GCond *cond_make;
-    GCond *cond_fill;
-    GCond *cond_clear;
-    GCond *cond_video;
-
-    GCond *cond_create;
-    GCond *cond_destroy;
+    GCond* cond_make;
+    GCond* cond_fill;
+    GCond* cond_clear;
+    GCond* cond_video;
+    GCond* cond_generateFBO;
+
+    GCond* cond_create;
+    GCond* cond_destroy;
     gint glutWinId;
     gulong winId;
-    GString *title;
+    GStringtitle;
     gint win_xpos;
     gint win_ypos;
     gint glcontext_width;
@@ -111,6 +113,13 @@ struct _GstGLDisplay {
     GLuint graphicDepthBuffer;
     GLuint graphicTexture;
 
+    //filter frame buffer object (GL -> GL)
+    GLuint requestedFBO;
+    GLuint requestedDepthBuffer;
+    GLuint requestedTextureFBO;
+    GLuint requestedTextureFBOWidth;
+    GLuint requestedTextureFBOHeight;
+
     GLuint requestedTexture;
     GLuint requestedTexture_u;
     GLuint requestedTexture_v;
@@ -211,6 +220,8 @@ void gst_gl_display_clearTexture (GstGLDisplay* display, guint texture,
 void gst_gl_display_videoChanged (GstGLDisplay* display, GstVideoFormat video_format,
                                   gpointer data);
 gboolean gst_gl_display_postRedisplay (GstGLDisplay* display);
+void gst_gl_display_requestFBO (GstGLDisplay* display, gint width, gint height, 
+                                guint* fbo, guint* depthbuffer, guint* texture);
 void gst_gl_display_set_windowId (GstGLDisplay* display, gulong winId);
 
 #endif